vvm/interpreter/
memory.rs1use vapory_types::U256;
18use tetsy_vm::ReturnData;
19
20const MAX_RETURN_WASTE_BYTES: usize = 16384;
21
22pub trait Memory {
23 fn size(&self) -> usize;
25 fn resize(&mut self, new_size: usize);
27 fn expand(&mut self, new_size: usize);
29 fn write_byte(&mut self, offset: U256, value: U256);
31 fn write(&mut self, offset: U256, value: U256);
33 fn read(&self, offset: U256) -> U256;
35 fn write_slice(&mut self, offset: U256, slice: &[u8]);
37 fn read_slice(&self, offset: U256, size: U256) -> &[u8];
39 fn writeable_slice(&mut self, offset: U256, size: U256) -> &mut[u8];
41 fn into_return_data(self, offset: U256, size: U256) -> ReturnData;
43}
44
45pub fn is_valid_range(off: usize, size: usize) -> bool {
47 let overflow = off.overflowing_add(size).1;
49 size > 0 && !overflow
50}
51
52impl Memory for Vec<u8> {
53 fn size(&self) -> usize {
54 self.len()
55 }
56
57 fn read_slice(&self, init_off_u: U256, init_size_u: U256) -> &[u8] {
58 let off = init_off_u.low_u64() as usize;
59 let size = init_size_u.low_u64() as usize;
60 if !is_valid_range(off, size) {
61 &self[0..0]
62 } else {
63 &self[off..off+size]
64 }
65 }
66
67 fn read(&self, offset: U256) -> U256 {
68 let off = offset.low_u64() as usize;
69 U256::from(&self[off..off+32])
70 }
71
72 fn writeable_slice(&mut self, offset: U256, size: U256) -> &mut [u8] {
73 let off = offset.low_u64() as usize;
74 let s = size.low_u64() as usize;
75 if !is_valid_range(off, s) {
76 &mut self[0..0]
77 } else {
78 &mut self[off..off+s]
79 }
80 }
81
82 fn write_slice(&mut self, offset: U256, slice: &[u8]) {
83 if !slice.is_empty() {
84 let off = offset.low_u64() as usize;
85 self[off..off+slice.len()].copy_from_slice(slice);
86 }
87 }
88
89 fn write(&mut self, offset: U256, value: U256) {
90 let off = offset.low_u64() as usize;
91 value.to_big_endian(&mut self[off..off+32]);
92 }
93
94 fn write_byte(&mut self, offset: U256, value: U256) {
95 let off = offset.low_u64() as usize;
96 let val = value.low_u64() as u64;
97 self[off] = val as u8;
98 }
99
100 fn resize(&mut self, new_size: usize) {
101 self.resize(new_size, 0);
102 }
103
104 fn expand(&mut self, size: usize) {
105 if size > self.len() {
106 Memory::resize(self, size)
107 }
108 }
109
110 fn into_return_data(mut self, offset: U256, size: U256) -> ReturnData {
111 let mut offset = offset.low_u64() as usize;
112 let size = size.low_u64() as usize;
113
114 if !is_valid_range(offset, size) {
115 return ReturnData::empty();
116 }
117
118 if self.len() - size > MAX_RETURN_WASTE_BYTES {
119 if offset == 0 {
120 self.truncate(size);
121 self.shrink_to_fit();
122 } else {
123 self = self[offset..(offset + size)].to_vec();
124 offset = 0;
125 }
126 }
127 ReturnData::new(self, offset, size)
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use vapory_types::U256;
134 use super::Memory;
135
136 #[test]
137 fn test_memory_read_and_write() {
138 let mem: &mut dyn Memory = &mut vec![];
140 mem.resize(0x80 + 32);
141
142 mem.write(U256::from(0x80), U256::from(0xabcdef));
144
145 assert_eq!(mem.read(U256::from(0x80)), U256::from(0xabcdef));
147 }
148
149 #[test]
150 fn test_memory_read_and_write_byte() {
151 let mem: &mut dyn Memory = &mut vec![];
153 mem.resize(32);
154
155 mem.write_byte(U256::from(0x1d), U256::from(0xab));
157 mem.write_byte(U256::from(0x1e), U256::from(0xcd));
158 mem.write_byte(U256::from(0x1f), U256::from(0xef));
159
160 assert_eq!(mem.read(U256::from(0x00)), U256::from(0xabcdef));
162 }
163
164 #[test]
165 fn test_memory_read_slice_and_write_slice() {
166 let mem: &mut dyn Memory = &mut vec![];
167 mem.resize(32);
168
169 {
170 let slice = "abcdefghijklmnopqrstuvwxyz012345".as_bytes();
171 mem.write_slice(U256::from(0), slice);
172
173 assert_eq!(mem.read_slice(U256::from(0), U256::from(32)), slice);
174 }
175
176 {
178 let slice = "67890".as_bytes();
179 mem.write_slice(U256::from(0x1), slice);
180
181 assert_eq!(mem.read_slice(U256::from(0), U256::from(7)), "a67890g".as_bytes());
182 }
183
184 {
186 let slice = [];
187 mem.write_slice(U256::from(0x1000), &slice);
188 assert_eq!(mem.size(), 32);
189 }
190 }
191}