revm_interpreter/instructions/
data.rs1use crate::{
2 gas::{cost_per_word, BASE, DATA_LOAD_GAS, VERYLOW},
3 interpreter::Interpreter,
4 interpreter_types::{
5 EofData, Immediates, InterpreterTypes, Jumps, LoopControl, MemoryTr, RuntimeFlag, StackTr,
6 },
7 Host,
8};
9use primitives::{B256, U256};
10
11pub fn data_load<WIRE: InterpreterTypes, H: Host + ?Sized>(
12 interpreter: &mut Interpreter<WIRE>,
13 _host: &mut H,
14) {
15 require_eof!(interpreter);
16 gas!(interpreter, DATA_LOAD_GAS);
17 popn_top!([], offset, interpreter);
18
19 let offset_usize = as_usize_saturated!(offset);
20
21 let slice = interpreter.bytecode.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<WIRE: InterpreterTypes, H: Host + ?Sized>(
30 interpreter: &mut Interpreter<WIRE>,
31 _host: &mut H,
32) {
33 require_eof!(interpreter);
34 gas!(interpreter, VERYLOW);
35 let offset = interpreter.bytecode.read_u16() as usize;
36
37 let slice = interpreter.bytecode.data_slice(offset, 32);
38
39 let mut word = [0u8; 32];
40 word[..slice.len()].copy_from_slice(slice);
41
42 push!(interpreter, B256::new(word).into());
43
44 interpreter.bytecode.relative_jump(2);
46}
47
48pub fn data_size<WIRE: InterpreterTypes, H: Host + ?Sized>(
49 interpreter: &mut Interpreter<WIRE>,
50 _host: &mut H,
51) {
52 require_eof!(interpreter);
53 gas!(interpreter, BASE);
54
55 push!(interpreter, U256::from(interpreter.bytecode.data_size()));
56}
57
58pub fn data_copy<WIRE: InterpreterTypes, H: Host + ?Sized>(
59 interpreter: &mut Interpreter<WIRE>,
60 _host: &mut H,
61) {
62 require_eof!(interpreter);
63 gas!(interpreter, VERYLOW);
64 popn!([mem_offset, offset, size], interpreter);
65
66 let size = as_usize_or_fail!(interpreter, size);
68 if size == 0 {
70 return;
71 }
72 let mem_offset = as_usize_or_fail!(interpreter, mem_offset);
74 resize_memory!(interpreter, mem_offset, size);
75
76 gas_or_fail!(interpreter, cost_per_word(size, VERYLOW));
77
78 let offset = as_usize_saturated!(offset);
79 let data = interpreter.bytecode.data();
80
81 interpreter.memory.set_data(mem_offset, offset, size, data);
83}
84
85#[cfg(test)]
86mod test {
87 use bytecode::{Bytecode, Eof};
88 use primitives::{b256, bytes, Bytes};
89 use std::sync::Arc;
90
91 use super::*;
92 use crate::{host::DummyHost, instruction_table};
93 use bytecode::opcode::{DATACOPY, DATALOAD, DATALOADN, DATASIZE};
94
95 fn dummy_eof(code_bytes: Bytes) -> Bytecode {
96 let bytes = bytes!("ef00010100040200010001ff00000000800000fe");
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.len();
105 eof.body.code = code_bytes;
106 Bytecode::Eof(Arc::new(eof))
107 }
108
109 #[test]
110 fn dataload_dataloadn() {
111 let table = instruction_table();
112 let mut host = DummyHost;
113
114 let eof = dummy_eof(Bytes::from([
115 DATALOAD, DATALOADN, 0x00, 0x00, DATALOAD, DATALOADN, 0x00, 35, DATALOAD, DATALOADN,
116 0x00, 36, DATASIZE,
117 ]));
118
119 let mut interpreter = Interpreter::default().with_bytecode(eof);
120 interpreter.runtime_flag.is_eof = true;
121
122 let _ = interpreter.stack.push(U256::from(0));
124 interpreter.step(&table, &mut host);
125 assert_eq!(interpreter.stack.data(), &vec![U256::from(0x01)]);
126 interpreter.stack.pop().unwrap();
127
128 interpreter.step(&table, &mut host);
130 assert_eq!(interpreter.stack.data(), &vec![U256::from(0x01)]);
131 interpreter.stack.pop().unwrap();
132
133 let _ = interpreter.stack.push(U256::from(35));
135 interpreter.step(&table, &mut host);
136
137 assert_eq!(
138 interpreter.stack.data(),
139 &vec![b256!("0500000000000000000000000000000000000000000000000000000000000000").into()]
140 );
141 interpreter.stack.pop().unwrap();
142
143 interpreter.step(&table, &mut host);
145 assert_eq!(
146 interpreter.stack.data(),
147 &vec![b256!("0500000000000000000000000000000000000000000000000000000000000000").into()]
148 );
149 interpreter.stack.pop().unwrap();
150
151 let _ = interpreter.stack.push(U256::from(36));
153 interpreter.step(&table, &mut host);
154 assert_eq!(interpreter.stack.data(), &vec![U256::ZERO]);
155 interpreter.stack.pop().unwrap();
156
157 interpreter.step(&table, &mut host);
159 assert_eq!(interpreter.stack.data(), &vec![U256::ZERO]);
160 interpreter.stack.pop().unwrap();
161
162 interpreter.step(&table, &mut host);
164 assert_eq!(interpreter.stack.data(), &vec![U256::from(36)]);
165 }
166
167 #[test]
168 fn data_copy() {
169 let table = instruction_table();
170 let mut host = DummyHost;
171 let eof = dummy_eof(Bytes::from([DATACOPY, DATACOPY, DATACOPY, DATACOPY]));
172
173 let mut interpreter = Interpreter::default().with_bytecode(eof);
174 interpreter.runtime_flag.is_eof = true;
175
176 let _ = interpreter.stack.push(U256::from(32));
179 let _ = interpreter.stack.push(U256::from(0));
180 let _ = interpreter.stack.push(U256::from(0));
181 interpreter.step(&table, &mut host);
182 assert_eq!(
183 *interpreter.memory.context_memory(),
184 bytes!("0000000000000000000000000000000000000000000000000000000000000001")
185 );
186
187 let _ = interpreter.stack.push(U256::from(2));
190 let _ = interpreter.stack.push(U256::from(35));
191 let _ = interpreter.stack.push(U256::from(1));
192 interpreter.step(&table, &mut host);
193 assert_eq!(
194 *interpreter.memory.context_memory(),
195 bytes!("0005000000000000000000000000000000000000000000000000000000000001")
196 );
197
198 let _ = interpreter.stack.push(U256::from(2));
201 let _ = interpreter.stack.push(U256::from(37));
202 let _ = interpreter.stack.push(U256::from(1));
203 interpreter.step(&table, &mut host);
204 assert_eq!(
205 *interpreter.memory.context_memory(),
206 bytes!("0000000000000000000000000000000000000000000000000000000000000001")
207 );
208
209 let _ = interpreter.stack.push(U256::from(0));
212 let _ = interpreter.stack.push(U256::from(37));
213 let _ = interpreter.stack.push(U256::from(1));
214 interpreter.step(&table, &mut host);
215 assert_eq!(
216 *interpreter.memory.context_memory(),
217 bytes!("0000000000000000000000000000000000000000000000000000000000000001")
218 );
219 }
220}