essential_constraint_vm/
memory.rs1use essential_types::Word;
2
3use crate::{error::TemporaryError, OpResult};
4
5#[cfg(test)]
6mod tests;
7
8#[derive(Default, Debug, PartialEq)]
9pub struct Memory(Vec<Word>);
11
12impl Memory {
13 pub const SIZE_LIMIT: usize = 1024 * 10;
15
16 pub fn new() -> Self {
18 Self::default()
19 }
20
21 pub fn alloc(&mut self, size: Word) -> OpResult<()> {
23 let size = usize::try_from(size).map_err(|_| TemporaryError::Overflow)?;
24 let new_size = self
25 .0
26 .len()
27 .checked_add(size)
28 .ok_or(TemporaryError::Overflow)?;
29 if new_size > Self::SIZE_LIMIT {
30 return Err(TemporaryError::Overflow.into());
31 }
32 self.0.resize(new_size, 0);
33 Ok(())
34 }
35
36 pub fn store(&mut self, address: Word, value: Word) -> OpResult<()> {
38 let index = usize::try_from(address).map_err(|_| TemporaryError::IndexOutOfBounds)?;
39 *self
40 .0
41 .get_mut(index)
42 .ok_or(TemporaryError::IndexOutOfBounds)? = value;
43 Ok(())
44 }
45
46 pub fn load(&mut self, address: Word) -> OpResult<Word> {
48 let index = usize::try_from(address).map_err(|_| TemporaryError::IndexOutOfBounds)?;
49 Ok(*self.0.get(index).ok_or(TemporaryError::IndexOutOfBounds)?)
50 }
51
52 pub fn store_range(&mut self, address: Word, values: &[Word]) -> OpResult<()> {
54 let address = usize::try_from(address).map_err(|_| TemporaryError::IndexOutOfBounds)?;
55 let end = address
56 .checked_add(values.len())
57 .ok_or(TemporaryError::Overflow)?;
58 if end > self.0.len() {
59 return Err(TemporaryError::IndexOutOfBounds.into());
60 }
61 self.0[address..end].copy_from_slice(values);
62 Ok(())
63 }
64
65 pub fn load_range(&mut self, address: Word, size: Word) -> OpResult<Vec<Word>> {
67 let address = usize::try_from(address).map_err(|_| TemporaryError::IndexOutOfBounds)?;
68 let size = usize::try_from(size).map_err(|_| TemporaryError::Overflow)?;
69 let end = address.checked_add(size).ok_or(TemporaryError::Overflow)?;
70 if end > self.0.len() {
71 return Err(TemporaryError::IndexOutOfBounds.into());
72 }
73 Ok(self.0[address..end].to_vec())
74 }
75
76 pub fn free(&mut self, address: Word) -> OpResult<()> {
78 let index = usize::try_from(address).map_err(|_| TemporaryError::IndexOutOfBounds)?;
79 if index >= self.0.len() {
80 return Err(TemporaryError::IndexOutOfBounds.into());
81 }
82 self.0.truncate(index);
83 self.0.shrink_to_fit();
84 Ok(())
85 }
86
87 pub fn len(&self) -> OpResult<Word> {
89 Ok(self
90 .0
91 .len()
92 .try_into()
93 .map_err(|_| TemporaryError::Overflow)?)
94 }
95
96 pub fn is_empty(&self) -> bool {
98 self.0.is_empty()
99 }
100}