swamp_code_gen/
constants.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5
6use 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}