revm_interpreter/instructions/
data.rs
1use crate::{
2 gas::{cost_per_word, BASE, DATA_LOAD_GAS, VERYLOW},
3 instructions::utility::read_u16,
4 interpreter::Interpreter,
5 primitives::U256,
6 Host,
7};
8
9pub fn data_load<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
10 require_eof!(interpreter);
11 gas!(interpreter, DATA_LOAD_GAS);
12 pop_top!(interpreter, offset);
13
14 let offset_usize = as_usize_saturated!(offset);
15
16 let slice = interpreter
17 .contract
18 .bytecode
19 .eof()
20 .expect("eof")
21 .data_slice(offset_usize, 32);
22
23 let mut word = [0u8; 32];
24 word[..slice.len()].copy_from_slice(slice);
25
26 *offset = U256::from_be_bytes(word);
27}
28
29pub fn data_loadn<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
30 require_eof!(interpreter);
31 gas!(interpreter, VERYLOW);
32 let offset = unsafe { read_u16(interpreter.instruction_pointer) } as usize;
33
34 let slice = interpreter
35 .contract
36 .bytecode
37 .eof()
38 .expect("eof")
39 .data_slice(offset, 32);
40
41 let mut word = [0u8; 32];
42 word[..slice.len()].copy_from_slice(slice);
43
44 push_b256!(interpreter, word.into());
45
46 interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(2) };
48}
49
50pub fn data_size<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
51 require_eof!(interpreter);
52 gas!(interpreter, BASE);
53 let data_size = interpreter.eof().expect("eof").header.data_size;
54
55 push!(interpreter, U256::from(data_size));
56}
57
58pub fn data_copy<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
59 require_eof!(interpreter);
60 gas!(interpreter, VERYLOW);
61 pop!(interpreter, mem_offset, offset, size);
62
63 let size = as_usize_or_fail!(interpreter, size);
65 if size == 0 {
67 return;
68 }
69 let mem_offset = as_usize_or_fail!(interpreter, mem_offset);
71 resize_memory!(interpreter, mem_offset, size);
72
73 gas_or_fail!(interpreter, cost_per_word(size as u64, VERYLOW));
74
75 let offset = as_usize_saturated!(offset);
76 let data = interpreter.contract.bytecode.eof().expect("eof").data();
77
78 interpreter
80 .shared_memory
81 .set_data(mem_offset, offset, size, data);
82}
83
84#[cfg(test)]
85mod test {
86 use revm_primitives::{b256, bytes, Bytecode, Bytes, Eof, PragueSpec};
87 use std::sync::Arc;
88
89 use super::*;
90 use crate::{
91 opcode::{make_instruction_table, DATACOPY, DATALOAD, DATALOADN, DATASIZE},
92 DummyHost, Gas, Interpreter,
93 };
94
95 fn dummy_eof(code_bytes: Bytes) -> Bytecode {
96 let bytes = bytes!("ef000101000402000100010400000000800000fe");
97 let mut eof = Eof::decode(bytes).unwrap();
98
99 eof.body.data_section =
100 bytes!("000000000000000000000000000000000000000000000000000000000000000102030405");
101 eof.header.data_size = eof.body.data_section.len() as u16;
102
103 eof.header.code_sizes[0] = code_bytes.len() as u16;
104 eof.body.code_section[0] = code_bytes;
105 Bytecode::Eof(Arc::new(eof))
106 }
107
108 #[test]
109 fn dataload_dataloadn() {
110 let table = make_instruction_table::<_, PragueSpec>();
111 let mut host = DummyHost::default();
112 let eof = dummy_eof(Bytes::from([
113 DATALOAD, DATALOADN, 0x00, 0x00, DATALOAD, DATALOADN, 0x00, 35, DATALOAD, DATALOADN,
114 0x00, 36, DATASIZE,
115 ]));
116
117 let mut interp = Interpreter::new_bytecode(eof);
118 interp.gas = Gas::new(10000);
119
120 interp.stack.push(U256::from(0)).unwrap();
122 interp.step(&table, &mut host);
123 assert_eq!(interp.stack.data(), &vec![U256::from(0x01)]);
124 interp.stack.pop().unwrap();
125
126 interp.step(&table, &mut host);
128 assert_eq!(interp.stack.data(), &vec![U256::from(0x01)]);
129 interp.stack.pop().unwrap();
130
131 interp.stack.push(U256::from(35)).unwrap();
133 interp.step(&table, &mut host);
134 assert_eq!(
135 interp.stack.data(),
136 &vec![b256!("0500000000000000000000000000000000000000000000000000000000000000").into()]
137 );
138 interp.stack.pop().unwrap();
139
140 interp.step(&table, &mut host);
142 assert_eq!(
143 interp.stack.data(),
144 &vec![b256!("0500000000000000000000000000000000000000000000000000000000000000").into()]
145 );
146 interp.stack.pop().unwrap();
147
148 interp.stack.push(U256::from(36)).unwrap();
150 interp.step(&table, &mut host);
151 assert_eq!(interp.stack.data(), &vec![U256::ZERO]);
152 interp.stack.pop().unwrap();
153
154 interp.step(&table, &mut host);
156 assert_eq!(interp.stack.data(), &vec![U256::ZERO]);
157 interp.stack.pop().unwrap();
158
159 interp.step(&table, &mut host);
161 assert_eq!(interp.stack.data(), &vec![U256::from(36)]);
162 }
163
164 #[test]
165 fn data_copy() {
166 let table = make_instruction_table::<_, PragueSpec>();
167 let mut host = DummyHost::default();
168 let eof = dummy_eof(Bytes::from([DATACOPY, DATACOPY, DATACOPY, DATACOPY]));
169
170 let mut interp = Interpreter::new_bytecode(eof);
171 interp.gas = Gas::new(10000);
172
173 interp.stack.push(U256::from(32)).unwrap();
176 interp.stack.push(U256::from(0)).unwrap();
177 interp.stack.push(U256::from(0)).unwrap();
178 interp.step(&table, &mut host);
179 assert_eq!(
180 interp.shared_memory.context_memory(),
181 &bytes!("0000000000000000000000000000000000000000000000000000000000000001")
182 );
183
184 interp.stack.push(U256::from(2)).unwrap();
187 interp.stack.push(U256::from(35)).unwrap();
188 interp.stack.push(U256::from(1)).unwrap();
189 interp.step(&table, &mut host);
190 assert_eq!(
191 interp.shared_memory.context_memory(),
192 &bytes!("0005000000000000000000000000000000000000000000000000000000000001")
193 );
194
195 interp.stack.push(U256::from(2)).unwrap();
198 interp.stack.push(U256::from(37)).unwrap();
199 interp.stack.push(U256::from(1)).unwrap();
200 interp.step(&table, &mut host);
201 assert_eq!(
202 interp.shared_memory.context_memory(),
203 &bytes!("0000000000000000000000000000000000000000000000000000000000000001")
204 );
205
206 interp.stack.push(U256::from(0)).unwrap();
209 interp.stack.push(U256::from(37)).unwrap();
210 interp.stack.push(U256::from(1)).unwrap();
211 interp.step(&table, &mut host);
212 assert_eq!(
213 interp.shared_memory.context_memory(),
214 &bytes!("0000000000000000000000000000000000000000000000000000000000000001")
215 );
216 }
217}