swamp_script_code_gen/
alloc.rs1use 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}