swamp_script_code_gen/
alloc.rs

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