swamp_code_gen/
constants.rs1use swamp_types::TypeRef;
6use swamp_vm_isa::aligner::{align, SAFE_ALIGNMENT};
7use swamp_vm_isa::HeapMemoryAddress;
8use swamp_vm_layout::LayoutCache;
9use swamp_vm_types::types::{HeapPlacedArray, HeapPlacedType};
10
11pub struct ConstantsAllocator {
12 current_addr: u32,
13 max_size: u32,
14}
15
16impl ConstantsAllocator {
17 #[must_use]
18 pub const fn new(max_size: u32) -> Self {
19 Self {
20 current_addr: SAFE_ALIGNMENT as u32, max_size,
22 }
23 }
24
25 pub fn allocate(&mut self, layout_cache: &mut LayoutCache, ty: &TypeRef) -> HeapPlacedType {
28 let gen_type = layout_cache.layout(ty);
29 let alignment: usize = gen_type.max_alignment.into();
30 let start_addr = align(self.current_addr as usize, alignment) as u32;
31
32 self.current_addr = start_addr + gen_type.total_size.0;
33 assert!(self.current_addr < self.max_size);
34
35 HeapPlacedType::new(HeapMemoryAddress(start_addr), gen_type)
36 }
37
38 pub fn allocate_byte_array(&mut self, byte_count: u32) -> HeapPlacedArray {
41 let start_addr = align(self.current_addr as usize, SAFE_ALIGNMENT) as u32;
42 self.current_addr = start_addr + byte_count;
43 assert!(self.current_addr < self.max_size);
44
45 HeapPlacedArray::new(HeapMemoryAddress(start_addr), byte_count)
46 }
47
48 pub const fn reset(&mut self) {
49 self.current_addr = SAFE_ALIGNMENT as u32;
50 }
51}
52
53pub struct ConstantsManager {
54 pub(crate) allocator: ConstantsAllocator,
55 data: Vec<u8>,
56}
57
58impl ConstantsManager {
59 #[must_use]
60 pub fn new(memory_size: u32) -> Self {
61 let data = vec![0; memory_size as usize];
62 Self {
63 allocator: ConstantsAllocator::new(memory_size),
64 data,
65 }
66 }
67
68 pub fn allocate_byte_array(&mut self, data: &[u8]) -> HeapPlacedArray {
69 let count = data.len();
70 if count == 0 {
71 return HeapPlacedArray::new(HeapMemoryAddress(0), 0);
72 }
73 let addr = self.allocator.allocate_byte_array(count as u32);
74 let start_idx = addr.addr().0 as usize;
75 self.data[start_idx..start_idx + data.len()].copy_from_slice(data);
76
77 addr
78 }
79
80 #[must_use]
81 pub fn take_data(self) -> Vec<u8> {
82 let safe_size = align(self.allocator.current_addr as usize, SAFE_ALIGNMENT);
83 self.data[..safe_size].to_vec()
84 }
85}