swamp_code_gen/
constants.rs1use swamp_vm_types::aligner::align;
7use swamp_vm_types::{ConstantMemoryAddress, MemoryAlignment, MemorySize};
8
9const ALIGNMENT_MASK: usize = 0x7;
10
11pub struct ConstantsAllocator {
12 current_addr: u32,
13}
14
15impl Default for ConstantsAllocator {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21impl ConstantsAllocator {
22 #[must_use]
23 pub const fn new() -> Self {
24 Self { current_addr: 0 }
25 }
26
27 pub fn allocate(
28 &mut self,
29 size: MemorySize,
30 alignment_enum: MemoryAlignment,
31 ) -> ConstantMemoryAddress {
32 let alignment: usize = alignment_enum.into();
33 let start_addr = align(self.current_addr as usize, alignment) as u32;
34
35 self.current_addr = start_addr + size.0 as u32;
36
37 ConstantMemoryAddress(start_addr)
38 }
39
40 pub fn reset(&mut self) {
41 self.current_addr = 0;
42 }
43}
44
45pub struct ConstantsManager {
46 allocator: ConstantsAllocator,
47 data: Vec<u8>,
48}
49
50impl Default for ConstantsManager {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl ConstantsManager {
57 #[must_use]
58 pub fn new() -> Self {
59 Self {
60 allocator: ConstantsAllocator::new(),
61 data: vec![0u8; 1024 * 1024],
62 }
63 }
64
65 pub fn reserve(
66 &mut self,
67 memory_size: MemorySize,
68 memory_alignment: MemoryAlignment,
69 ) -> ConstantMemoryAddress {
70 self.allocator.allocate(memory_size, memory_alignment)
71 }
72
73 pub fn allocate(
74 &mut self,
75 data: &[u8],
76 alignment_enum: MemoryAlignment,
77 ) -> ConstantMemoryAddress {
78 let addr = self
79 .allocator
80 .allocate(MemorySize(data.len() as u16), alignment_enum);
81
82 let start_idx = addr.0 as usize;
83 self.data[start_idx..start_idx + data.len()].copy_from_slice(data);
84
85 ConstantMemoryAddress(addr.0)
86 }
87
88 pub fn take_data(self) -> Vec<u8> {
89 self.data
90 }
91}