1use crate::utils::bytes32::Bytes32;
2
3#[derive(Debug)]
4pub struct Memory {
5 pub heap: Vec<u8>,
6}
7
8impl Default for Memory {
9 fn default() -> Self {
10 Self::new()
11 }
12}
13
14impl Memory {
15 pub fn new() -> Self {
16 Self { heap: vec![0; 0] }
17 }
18
19 fn extend(&mut self, size: usize) {
20 self.heap.extend(vec![0; size]);
21 }
22
23 pub unsafe fn mload(&mut self, location: Bytes32) -> Bytes32 {
29 let location: usize = location.try_into().unwrap();
30 let extended_location = location + 32;
31
32 if extended_location > self.heap.len() {
33 if location % 32 == 0 {
34 self.extend(extended_location - self.heap.len());
35 } else {
36 self.extend(extended_location + (location % 32) - self.heap.len());
37 };
38 }
39
40 let ptr = self.heap.as_ptr().add(location) as *const Bytes32;
41
42 unsafe { *ptr }
43 }
44
45 pub unsafe fn mstore(&mut self, location: Bytes32, data: Bytes32) {
51 let location: usize = location.try_into().unwrap();
52 let extended_location = location + 32;
53
54 if extended_location > self.heap.len() {
55 self.extend(extended_location - self.heap.len());
56 }
57
58 let ptr = self.heap.as_mut_ptr().add(location) as *mut [u8; 32];
59
60 *ptr = data.0;
61 }
62
63 pub unsafe fn load_only(&self, location: Bytes32) -> Bytes32 {
69 let location: usize = location.try_into().unwrap();
70
71 let ptr = self.heap.as_ptr().add(location) as *const Bytes32;
72
73 unsafe { *ptr }
74 }
75
76 pub fn msize(&self) -> usize {
77 self.heap.len()
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn it_creates_memory_heap() {
87 let memory = Memory::new();
88
89 assert_eq!(memory.heap.is_empty(), true);
90 }
91
92 #[test]
93 fn it_extends_memory() {
94 let mut memory = Memory::new();
95
96 memory.extend(32);
97
98 assert_eq!(memory.heap.is_empty(), false);
99 assert_eq!(memory.msize(), 32);
100 }
101
102 #[test]
103 fn it_stores_and_loads_data_which_is_multiplication_of_32_in_memory() {
104 let mut memory = Memory::new();
105
106 let data = "ff1122".parse::<Bytes32>().unwrap();
107 let mem_location = Bytes32::from(0);
108
109 let result: Bytes32;
110 unsafe {
111 memory.mstore(mem_location, data);
112
113 result = memory.mload(mem_location);
114 }
115
116 assert_eq!(result, data);
117 }
118
119 #[test]
120 fn it_stores_and_loads_data_which_is_not_multiplication_of_32_in_memory() {
121 let mut memory = Memory::new();
122
123 let data = "ff1122".parse::<Bytes32>().unwrap();
124 let mem_location = Bytes32::from(37);
125 let mem_upper_limit = 37 + 32;
126
127 let result: Bytes32;
128 unsafe {
129 memory.mstore(mem_location, data);
130
131 result = memory.mload(mem_location);
132 }
133
134 assert_eq!(result, data);
135 assert_eq!(memory.msize(), mem_upper_limit);
136 }
137}