1use swamp_vm_types::{
7 ConstantMemoryAddress, FrameMemoryAddress, MemoryAlignment, MemorySize, align_frame_addr,
8};
9use tracing::error;
10
11const ALIGNMENT: u16 = 8;
12const ALIGNMENT_REST: u16 = ALIGNMENT - 1;
13const ALIGNMENT_MASK: u16 = !ALIGNMENT_REST;
14
15#[derive(Debug, Copy, Clone)]
16pub struct ConstantMemoryRegion {
17 pub addr: ConstantMemoryAddress,
18 pub size: MemorySize,
19}
20
21#[derive(Debug, Copy, Clone)]
22pub struct FrameMemoryRegion {
23 pub addr: FrameMemoryAddress,
24 pub size: MemorySize,
25}
26
27impl Default for FrameMemoryRegion {
28 fn default() -> Self {
29 Self {
30 addr: FrameMemoryAddress(0),
31 size: MemorySize(0),
32 }
33 }
34}
35
36impl FrameMemoryRegion {
37 pub(crate) fn new(frame_addr: FrameMemoryAddress, size: MemorySize) -> FrameMemoryRegion {
38 Self {
39 addr: frame_addr,
40 size,
41 }
42 }
43
44 pub fn last_valid_end_addr(&self) -> FrameMemoryAddress {
45 self.addr.add(MemorySize(self.size.0))
46 }
47}
48
49impl FrameMemoryRegion {
50 #[must_use]
51 pub fn addr(&self) -> FrameMemoryAddress {
52 self.addr
53 }
54}
55
56#[derive(Copy, Clone)]
57pub struct ScopeAllocator {
58 initial_addr: FrameMemoryAddress,
59 addr: FrameMemoryAddress,
60 target_info: FrameMemoryRegion,
61}
62
63impl ScopeAllocator {
64 #[must_use]
65 pub const fn new(target_info: FrameMemoryRegion) -> Self {
66 Self {
67 initial_addr: target_info.addr,
68 addr: target_info.addr,
69 target_info,
70 }
71 }
72
73 pub fn allocate(&mut self, size: MemorySize, alignment: MemoryAlignment) -> FrameMemoryAddress {
74 let start_addr = align_frame_addr(self.addr, alignment);
75
76 self.addr = start_addr.add(size);
77
78 if self.addr.0 > self.target_info.last_valid_end_addr().0 {
79 error!("out of alloc memory");
80 }
81
82 assert!(self.addr.0 <= self.target_info.last_valid_end_addr().0);
83
84 start_addr
85 }
86
87 pub fn reserve(&mut self, size: MemorySize, alignment: MemoryAlignment) -> FrameMemoryRegion {
88 FrameMemoryRegion {
89 addr: self.allocate(size, alignment),
90 size,
91 }
92 }
93
94 #[must_use]
95 pub const fn create_scope(&self) -> Self {
96 Self {
97 addr: self.addr,
98 initial_addr: self.addr,
99 target_info: self.target_info,
100 }
101 }
102
103 #[must_use]
104 pub const fn addr(&self) -> FrameMemoryAddress {
105 self.addr
106 }
107
108 pub fn reset(&mut self) {
109 self.addr = self.initial_addr;
110 }
111}