swamp_script_code_gen/
alloc.rs

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