1use essential_types::Word;
2
3use crate::error::MemoryError;
4
5#[cfg(test)]
6mod tests;
7
8#[derive(Clone, 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) -> Result<(), MemoryError> {
23 let size = usize::try_from(size).map_err(|_| MemoryError::Overflow)?;
24 let new_size = self
25 .0
26 .len()
27 .checked_add(size)
28 .ok_or(MemoryError::Overflow)?;
29 if new_size > Self::SIZE_LIMIT {
30 return Err(MemoryError::Overflow);
31 }
32 self.0.resize(new_size, 0);
33 Ok(())
34 }
35
36 pub fn store(&mut self, address: Word, value: Word) -> Result<(), MemoryError> {
38 let index = usize::try_from(address).map_err(|_| MemoryError::IndexOutOfBounds)?;
39 *self.0.get_mut(index).ok_or(MemoryError::IndexOutOfBounds)? = value;
40 Ok(())
41 }
42
43 pub fn load(&self, address: Word) -> Result<Word, MemoryError> {
45 let index = usize::try_from(address).map_err(|_| MemoryError::IndexOutOfBounds)?;
46 Ok(*self.0.get(index).ok_or(MemoryError::IndexOutOfBounds)?)
47 }
48
49 pub fn store_range(&mut self, address: Word, values: &[Word]) -> Result<(), MemoryError> {
51 let address = usize::try_from(address).map_err(|_| MemoryError::IndexOutOfBounds)?;
52 let end = address
53 .checked_add(values.len())
54 .ok_or(MemoryError::Overflow)?;
55 if end > self.0.len() {
56 return Err(MemoryError::IndexOutOfBounds);
57 }
58 self.0[address..end].copy_from_slice(values);
59 Ok(())
60 }
61
62 pub fn load_range(&self, address: Word, size: Word) -> Result<Vec<Word>, MemoryError> {
64 let address = usize::try_from(address).map_err(|_| MemoryError::IndexOutOfBounds)?;
65 let size = usize::try_from(size).map_err(|_| MemoryError::Overflow)?;
66 let end = address.checked_add(size).ok_or(MemoryError::Overflow)?;
67 if end > self.0.len() {
68 return Err(MemoryError::IndexOutOfBounds);
69 }
70 Ok(self.0[address..end].to_vec())
71 }
72
73 pub fn free(&mut self, new_len: Word) -> Result<(), MemoryError> {
75 let new_len = usize::try_from(new_len).map_err(|_| MemoryError::IndexOutOfBounds)?;
76 if new_len > self.0.len() {
77 return Err(MemoryError::IndexOutOfBounds);
78 }
79 self.0.truncate(new_len);
80 self.0.shrink_to_fit();
81 Ok(())
82 }
83
84 pub fn len(&self) -> Result<Word, MemoryError> {
86 self.0.len().try_into().map_err(|_| MemoryError::Overflow)
87 }
88
89 pub fn is_empty(&self) -> bool {
91 self.0.is_empty()
92 }
93}
94
95impl From<Memory> for Vec<Word> {
96 fn from(m: Memory) -> Vec<Word> {
97 m.0
98 }
99}
100
101impl TryFrom<Vec<Word>> for Memory {
102 type Error = MemoryError;
103 fn try_from(words: Vec<Word>) -> Result<Self, Self::Error> {
104 if words.len() > Self::SIZE_LIMIT {
105 Err(MemoryError::Overflow)
106 } else {
107 Ok(Self(words))
108 }
109 }
110}
111
112impl core::ops::Deref for Memory {
113 type Target = [Word];
114 fn deref(&self) -> &Self::Target {
115 &self.0
116 }
117}