1use crate::{
2 gas,
3 interpreter::Interpreter,
4 interpreter_types::{
5 InputsTr, InterpreterTypes, LegacyBytecode, LoopControl, MemoryTr, ReturnData, RuntimeFlag,
6 StackTr,
7 },
8 Host, InstructionResult,
9};
10use core::ptr;
11use primitives::{B256, KECCAK_EMPTY, U256};
12
13pub fn keccak256<WIRE: InterpreterTypes, H: Host + ?Sized>(
14 interpreter: &mut Interpreter<WIRE>,
15 _host: &mut H,
16) {
17 popn_top!([offset], top, interpreter);
18 let len = as_usize_or_fail!(interpreter, top);
19 gas_or_fail!(interpreter, gas::keccak256_cost(len));
20 let hash = if len == 0 {
21 KECCAK_EMPTY
22 } else {
23 let from = as_usize_or_fail!(interpreter, offset);
24 resize_memory!(interpreter, from, len);
25 primitives::keccak256(interpreter.memory.slice_len(from, len).as_ref())
26 };
27 *top = hash.into();
28}
29
30pub fn address<WIRE: InterpreterTypes, H: Host + ?Sized>(
31 interpreter: &mut Interpreter<WIRE>,
32 _host: &mut H,
33) {
34 gas!(interpreter, gas::BASE);
35 push!(
36 interpreter,
37 interpreter.input.target_address().into_word().into()
38 );
39}
40
41pub fn caller<WIRE: InterpreterTypes, H: Host + ?Sized>(
42 interpreter: &mut Interpreter<WIRE>,
43 _host: &mut H,
44) {
45 gas!(interpreter, gas::BASE);
46 push!(
47 interpreter,
48 interpreter.input.caller_address().into_word().into()
49 );
50}
51
52pub fn codesize<WIRE: InterpreterTypes, H: Host + ?Sized>(
53 interpreter: &mut Interpreter<WIRE>,
54 _host: &mut H,
55) {
56 gas!(interpreter, gas::BASE);
57 push!(interpreter, U256::from(interpreter.bytecode.bytecode_len()));
58}
59
60pub fn codecopy<WIRE: InterpreterTypes, H: Host + ?Sized>(
61 interpreter: &mut Interpreter<WIRE>,
62 _host: &mut H,
63) {
64 popn!([memory_offset, code_offset, len], interpreter);
65 let len = as_usize_or_fail!(interpreter, len);
66 let Some(memory_offset) = memory_resize(interpreter, memory_offset, len) else {
67 return;
68 };
69 let code_offset = as_usize_saturated!(code_offset);
70
71 interpreter.memory.set_data(
73 memory_offset,
74 code_offset,
75 len,
76 interpreter.bytecode.bytecode_slice(),
77 );
78}
79
80pub fn calldataload<WIRE: InterpreterTypes, H: Host + ?Sized>(
81 interpreter: &mut Interpreter<WIRE>,
82 _host: &mut H,
83) {
84 gas!(interpreter, gas::VERYLOW);
85 popn_top!([], offset_ptr, interpreter);
87 let mut word = B256::ZERO;
88 let offset = as_usize_saturated!(offset_ptr);
89 let input = interpreter.input.input();
90 let input_len = input.len();
91 if offset < input_len {
92 let count = 32.min(input_len - offset);
93 debug_assert!(count <= 32 && offset + count <= input_len);
98 unsafe { ptr::copy_nonoverlapping(input.as_ptr().add(offset), word.as_mut_ptr(), count) };
99 }
100 *offset_ptr = word.into();
101}
102
103pub fn calldatasize<WIRE: InterpreterTypes, H: Host + ?Sized>(
104 interpreter: &mut Interpreter<WIRE>,
105 _host: &mut H,
106) {
107 gas!(interpreter, gas::BASE);
108 push!(interpreter, U256::from(interpreter.input.input().len()));
109}
110
111pub fn callvalue<WIRE: InterpreterTypes, H: Host + ?Sized>(
112 interpreter: &mut Interpreter<WIRE>,
113 _host: &mut H,
114) {
115 gas!(interpreter, gas::BASE);
116 push!(interpreter, interpreter.input.call_value());
117}
118
119pub fn calldatacopy<WIRE: InterpreterTypes, H: Host + ?Sized>(
120 interpreter: &mut Interpreter<WIRE>,
121 _host: &mut H,
122) {
123 popn!([memory_offset, data_offset, len], interpreter);
124 let len = as_usize_or_fail!(interpreter, len);
125 let Some(memory_offset) = memory_resize(interpreter, memory_offset, len) else {
126 return;
127 };
128
129 let data_offset = as_usize_saturated!(data_offset);
130 interpreter
132 .memory
133 .set_data(memory_offset, data_offset, len, interpreter.input.input());
134}
135
136pub fn returndatasize<WIRE: InterpreterTypes, H: Host + ?Sized>(
138 interpreter: &mut Interpreter<WIRE>,
139 _host: &mut H,
140) {
141 check!(interpreter, BYZANTIUM);
142 gas!(interpreter, gas::BASE);
143 push!(
144 interpreter,
145 U256::from(interpreter.return_data.buffer().len())
146 );
147}
148
149pub fn returndatacopy<WIRE: InterpreterTypes, H: Host + ?Sized>(
151 interpreter: &mut Interpreter<WIRE>,
152 _host: &mut H,
153) {
154 check!(interpreter, BYZANTIUM);
155 popn!([memory_offset, offset, len], interpreter);
156
157 let len = as_usize_or_fail!(interpreter, len);
158 let data_offset = as_usize_saturated!(offset);
159
160 let data_end = data_offset.saturating_add(len);
163 if data_end > interpreter.return_data.buffer().len() && !interpreter.runtime_flag.is_eof() {
164 interpreter
165 .control
166 .set_instruction_result(InstructionResult::OutOfOffset);
167 return;
168 }
169
170 let Some(memory_offset) = memory_resize(interpreter, memory_offset, len) else {
171 return;
172 };
173
174 interpreter.memory.set_data(
176 memory_offset,
177 data_offset,
178 len,
179 interpreter.return_data.buffer(),
180 );
181}
182
183pub fn returndataload<WIRE: InterpreterTypes, H: Host + ?Sized>(
185 interpreter: &mut Interpreter<WIRE>,
186 _host: &mut H,
187) {
188 require_eof!(interpreter);
189 gas!(interpreter, gas::VERYLOW);
190 popn_top!([], offset, interpreter);
191 let offset_usize = as_usize_saturated!(offset);
192
193 let mut output = [0u8; 32];
194 if let Some(available) = interpreter
195 .return_data
196 .buffer()
197 .len()
198 .checked_sub(offset_usize)
199 {
200 let copy_len = available.min(32);
201 output[..copy_len].copy_from_slice(
202 &interpreter.return_data.buffer()[offset_usize..offset_usize + copy_len],
203 );
204 }
205
206 *offset = B256::from(output).into();
207}
208
209pub fn gas<WIRE: InterpreterTypes, H: Host + ?Sized>(
210 interpreter: &mut Interpreter<WIRE>,
211 _host: &mut H,
212) {
213 gas!(interpreter, gas::BASE);
214 push!(
215 interpreter,
216 U256::from(interpreter.control.gas().remaining())
217 );
218}
219
220pub fn memory_resize(
222 interpreter: &mut Interpreter<impl InterpreterTypes>,
223 memory_offset: U256,
224 len: usize,
225) -> Option<usize> {
226 gas_or_fail!(interpreter, gas::copy_cost_verylow(len), None);
228 if len == 0 {
229 return None;
230 }
231 let memory_offset = as_usize_or_fail_ret!(interpreter, memory_offset, None);
232 resize_memory!(interpreter, memory_offset, len, None);
233
234 Some(memory_offset)
235}
236
237#[cfg(test)]
238mod test {
239 use super::*;
240 use crate::{host::DummyHost, instruction_table, InstructionResult};
241 use bytecode::{opcode::RETURNDATACOPY, opcode::RETURNDATALOAD, Bytecode};
242 use primitives::{bytes, Bytes};
243
244 #[test]
245 fn returndataload() {
246 let bytecode = Bytecode::new_raw(Bytes::from(&[
247 RETURNDATALOAD,
248 RETURNDATALOAD,
249 RETURNDATALOAD,
250 RETURNDATALOAD,
251 ]));
252 let mut interpreter = Interpreter::default().with_bytecode(bytecode);
253
254 let table = instruction_table();
255 let mut host = DummyHost;
256 interpreter.runtime_flag.is_eof = true;
257
258 let _ = interpreter.stack.push(U256::from(0));
259 interpreter.return_data.set_buffer(bytes!(
260 "000000000000000400000000000000030000000000000002000000000000000100"
261 ));
262 interpreter.step(&table, &mut host);
263 assert_eq!(
264 interpreter.stack.data(),
265 &vec![U256::from_limbs([0x01, 0x02, 0x03, 0x04])]
266 );
267
268 let _ = interpreter.stack.pop();
269 let _ = interpreter.stack.push(U256::from(1));
270
271 interpreter.step(&table, &mut host);
272 assert_eq!(
273 interpreter.control.instruction_result,
274 InstructionResult::Continue
275 );
276 assert_eq!(
277 interpreter.stack.data(),
278 &vec![U256::from_limbs([0x0100, 0x0200, 0x0300, 0x0400])]
279 );
280
281 let _ = interpreter.stack.pop();
282 let _ = interpreter.stack.push(U256::from(32));
283 interpreter.step(&table, &mut host);
284 assert_eq!(
285 interpreter.control.instruction_result,
286 InstructionResult::Continue
287 );
288 assert_eq!(
289 interpreter.stack.data(),
290 &vec![U256::from_limbs([0x00, 0x00, 0x00, 0x00])]
291 );
292
293 let _ = interpreter.stack.pop();
295 let _ = interpreter
296 .stack
297 .push(U256::from(interpreter.return_data.buffer().len()));
298 interpreter.step(&table, &mut host);
299 assert_eq!(
300 interpreter.control.instruction_result,
301 InstructionResult::Continue
302 );
303 assert_eq!(
304 interpreter.stack.data(),
305 &vec![U256::from_limbs([0x00, 0x00, 0x00, 0x00])]
306 );
307 }
308
309 #[test]
310 fn returndatacopy() {
311 let bytecode = Bytecode::new_raw(Bytes::from(&[
312 RETURNDATACOPY,
313 RETURNDATACOPY,
314 RETURNDATACOPY,
315 RETURNDATACOPY,
316 RETURNDATACOPY,
317 RETURNDATACOPY,
318 ]));
319 let mut interpreter = Interpreter::default().with_bytecode(bytecode);
320
321 let table = instruction_table();
322 let mut host = DummyHost;
323 interpreter.runtime_flag.is_eof = true;
324
325 interpreter.return_data.set_buffer(bytes!(
326 "000000000000000400000000000000030000000000000002000000000000000100"
327 ));
328 interpreter.memory.resize(256);
329
330 let _ = interpreter.stack.push(U256::from(32));
332 let _ = interpreter.stack.push(U256::from(0));
333 let _ = interpreter.stack.push(U256::from(0));
334 interpreter.step(&table, &mut host);
335 assert_eq!(
336 interpreter.control.instruction_result,
337 InstructionResult::Continue
338 );
339 assert_eq!(
340 *interpreter.memory.slice(0..32),
341 interpreter.return_data.buffer()[0..32]
342 );
343
344 let _ = interpreter.stack.push(U256::from(64));
346 let _ = interpreter.stack.push(U256::from(16));
347 let _ = interpreter.stack.push(U256::from(64));
348 interpreter.step(&table, &mut host);
349 assert_eq!(
350 interpreter.control.instruction_result,
351 InstructionResult::Continue
352 );
353 assert_eq!(
354 *interpreter.memory.slice(64..80),
355 interpreter.return_data.buffer()[16..32]
356 );
357 assert_eq!(*interpreter.memory.slice(80..128), [0u8; 48]);
358
359 let _ = interpreter.stack.push(U256::from(32));
361 let _ = interpreter.stack.push(U256::from(96));
362 let _ = interpreter.stack.push(U256::from(128));
363 interpreter.step(&table, &mut host);
364 assert_eq!(
365 interpreter.control.instruction_result,
366 InstructionResult::Continue
367 );
368 assert_eq!(*interpreter.memory.slice(128..160), [0u8; 32]);
369
370 let _ = interpreter.stack.push(U256::from(32));
372 let _ = interpreter.stack.push(U256::MAX);
373 let _ = interpreter.stack.push(U256::from(0));
374 interpreter.step(&table, &mut host);
375 assert_eq!(
376 interpreter.control.instruction_result,
377 InstructionResult::Continue
378 );
379 assert_eq!(*interpreter.memory.slice(0..32), [0u8; 32]);
380
381 let _ = interpreter.stack.push(U256::from(32));
383 let _ = interpreter
384 .stack
385 .push(U256::from(interpreter.return_data.buffer().len() - 32));
386 let _ = interpreter.stack.push(U256::from(0));
387 interpreter.step(&table, &mut host);
388 assert_eq!(
389 interpreter.control.instruction_result,
390 InstructionResult::Continue
391 );
392 assert_eq!(
393 *interpreter.memory.slice(0..32),
394 interpreter.return_data.buffer()[interpreter.return_data.buffer().len() - 32..]
395 );
396
397 let _ = interpreter.stack.push(U256::from(32));
399 let _ = interpreter
400 .stack
401 .push(U256::from(interpreter.return_data.buffer().len()));
402 let _ = interpreter.stack.push(U256::from(0));
403 interpreter.step(&table, &mut host);
404 assert_eq!(
405 interpreter.control.instruction_result,
406 InstructionResult::Continue
407 );
408 assert_eq!(*interpreter.memory.slice(0..32), [0u8; 32]);
409 }
410}