1use crate::{
2 gas,
3 interpreter::Interpreter,
4 interpreter_types::{
5 InputsTr, InterpreterTypes, LegacyBytecode, LoopControl, MemoryTr, ReturnData, RuntimeFlag,
6 StackTr,
7 },
8 CallInput, 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
94 match interpreter.input.input() {
99 CallInput::Bytes(bytes) => {
100 unsafe {
101 ptr::copy_nonoverlapping(bytes.as_ptr().add(offset), word.as_mut_ptr(), count)
102 };
103 }
104 CallInput::SharedBuffer(range) => {
105 let input_slice = interpreter.memory.global_slice(range.clone());
106 unsafe {
107 ptr::copy_nonoverlapping(
108 input_slice.as_ptr().add(offset),
109 word.as_mut_ptr(),
110 count,
111 )
112 };
113 }
114 }
115 }
116 *offset_ptr = word.into();
117}
118
119pub fn calldatasize<WIRE: InterpreterTypes, H: Host + ?Sized>(
120 interpreter: &mut Interpreter<WIRE>,
121 _host: &mut H,
122) {
123 gas!(interpreter, gas::BASE);
124 push!(interpreter, U256::from(interpreter.input.input().len()));
125}
126
127pub fn callvalue<WIRE: InterpreterTypes, H: Host + ?Sized>(
128 interpreter: &mut Interpreter<WIRE>,
129 _host: &mut H,
130) {
131 gas!(interpreter, gas::BASE);
132 push!(interpreter, interpreter.input.call_value());
133}
134
135pub fn calldatacopy<WIRE: InterpreterTypes, H: Host + ?Sized>(
136 interpreter: &mut Interpreter<WIRE>,
137 _host: &mut H,
138) {
139 popn!([memory_offset, data_offset, len], interpreter);
140 let len = as_usize_or_fail!(interpreter, len);
141 let Some(memory_offset) = memory_resize(interpreter, memory_offset, len) else {
142 return;
143 };
144
145 let data_offset = as_usize_saturated!(data_offset);
146 match interpreter.input.input() {
147 CallInput::Bytes(bytes) => {
148 interpreter
149 .memory
150 .set_data(memory_offset, data_offset, len, bytes.as_ref());
151 }
152 CallInput::SharedBuffer(range) => {
153 interpreter
154 .memory
155 .set_data_from_global(memory_offset, data_offset, len, range.clone());
156 }
157 }
158}
159
160pub fn returndatasize<WIRE: InterpreterTypes, H: Host + ?Sized>(
162 interpreter: &mut Interpreter<WIRE>,
163 _host: &mut H,
164) {
165 check!(interpreter, BYZANTIUM);
166 gas!(interpreter, gas::BASE);
167 push!(
168 interpreter,
169 U256::from(interpreter.return_data.buffer().len())
170 );
171}
172
173pub fn returndatacopy<WIRE: InterpreterTypes, H: Host + ?Sized>(
175 interpreter: &mut Interpreter<WIRE>,
176 _host: &mut H,
177) {
178 check!(interpreter, BYZANTIUM);
179 popn!([memory_offset, offset, len], interpreter);
180
181 let len = as_usize_or_fail!(interpreter, len);
182 let data_offset = as_usize_saturated!(offset);
183
184 let data_end = data_offset.saturating_add(len);
187 if data_end > interpreter.return_data.buffer().len() && !interpreter.runtime_flag.is_eof() {
188 interpreter
189 .control
190 .set_instruction_result(InstructionResult::OutOfOffset);
191 return;
192 }
193
194 let Some(memory_offset) = memory_resize(interpreter, memory_offset, len) else {
195 return;
196 };
197
198 interpreter.memory.set_data(
200 memory_offset,
201 data_offset,
202 len,
203 interpreter.return_data.buffer(),
204 );
205}
206
207pub fn returndataload<WIRE: InterpreterTypes, H: Host + ?Sized>(
209 interpreter: &mut Interpreter<WIRE>,
210 _host: &mut H,
211) {
212 require_eof!(interpreter);
213 gas!(interpreter, gas::VERYLOW);
214 popn_top!([], offset, interpreter);
215 let offset_usize = as_usize_saturated!(offset);
216
217 let mut output = [0u8; 32];
218 if let Some(available) = interpreter
219 .return_data
220 .buffer()
221 .len()
222 .checked_sub(offset_usize)
223 {
224 let copy_len = available.min(32);
225 output[..copy_len].copy_from_slice(
226 &interpreter.return_data.buffer()[offset_usize..offset_usize + copy_len],
227 );
228 }
229
230 *offset = B256::from(output).into();
231}
232
233pub fn gas<WIRE: InterpreterTypes, H: Host + ?Sized>(
234 interpreter: &mut Interpreter<WIRE>,
235 _host: &mut H,
236) {
237 gas!(interpreter, gas::BASE);
238 push!(
239 interpreter,
240 U256::from(interpreter.control.gas().remaining())
241 );
242}
243
244pub fn memory_resize(
246 interpreter: &mut Interpreter<impl InterpreterTypes>,
247 memory_offset: U256,
248 len: usize,
249) -> Option<usize> {
250 gas_or_fail!(interpreter, gas::copy_cost_verylow(len), None);
252 if len == 0 {
253 return None;
254 }
255 let memory_offset = as_usize_or_fail_ret!(interpreter, memory_offset, None);
256 resize_memory!(interpreter, memory_offset, len, None);
257
258 Some(memory_offset)
259}
260
261#[cfg(test)]
262mod test {
263 use super::*;
264 use crate::{host::DummyHost, instruction_table, InstructionResult};
265 use bytecode::{opcode::RETURNDATACOPY, opcode::RETURNDATALOAD, Bytecode};
266 use primitives::{bytes, Bytes};
267
268 #[test]
269 fn returndataload() {
270 let bytecode = Bytecode::new_raw(Bytes::from(&[
271 RETURNDATALOAD,
272 RETURNDATALOAD,
273 RETURNDATALOAD,
274 RETURNDATALOAD,
275 ]));
276 let mut interpreter = Interpreter::default().with_bytecode(bytecode);
277
278 let table = instruction_table();
279 let mut host = DummyHost;
280 interpreter.runtime_flag.is_eof = true;
281
282 let _ = interpreter.stack.push(U256::from(0));
283 interpreter.return_data.set_buffer(bytes!(
284 "000000000000000400000000000000030000000000000002000000000000000100"
285 ));
286 interpreter.step(&table, &mut host);
287 assert_eq!(
288 interpreter.stack.data(),
289 &vec![U256::from_limbs([0x01, 0x02, 0x03, 0x04])]
290 );
291
292 let _ = interpreter.stack.pop();
293 let _ = interpreter.stack.push(U256::from(1));
294
295 interpreter.step(&table, &mut host);
296 assert_eq!(
297 interpreter.control.instruction_result,
298 InstructionResult::Continue
299 );
300 assert_eq!(
301 interpreter.stack.data(),
302 &vec![U256::from_limbs([0x0100, 0x0200, 0x0300, 0x0400])]
303 );
304
305 let _ = interpreter.stack.pop();
306 let _ = interpreter.stack.push(U256::from(32));
307 interpreter.step(&table, &mut host);
308 assert_eq!(
309 interpreter.control.instruction_result,
310 InstructionResult::Continue
311 );
312 assert_eq!(
313 interpreter.stack.data(),
314 &vec![U256::from_limbs([0x00, 0x00, 0x00, 0x00])]
315 );
316
317 let _ = interpreter.stack.pop();
319 let _ = interpreter
320 .stack
321 .push(U256::from(interpreter.return_data.buffer().len()));
322 interpreter.step(&table, &mut host);
323 assert_eq!(
324 interpreter.control.instruction_result,
325 InstructionResult::Continue
326 );
327 assert_eq!(
328 interpreter.stack.data(),
329 &vec![U256::from_limbs([0x00, 0x00, 0x00, 0x00])]
330 );
331 }
332
333 #[test]
334 fn returndatacopy() {
335 let bytecode = Bytecode::new_raw(Bytes::from(&[
336 RETURNDATACOPY,
337 RETURNDATACOPY,
338 RETURNDATACOPY,
339 RETURNDATACOPY,
340 RETURNDATACOPY,
341 RETURNDATACOPY,
342 ]));
343 let mut interpreter = Interpreter::default().with_bytecode(bytecode);
344
345 let table = instruction_table();
346 let mut host = DummyHost;
347 interpreter.runtime_flag.is_eof = true;
348
349 interpreter.return_data.set_buffer(bytes!(
350 "000000000000000400000000000000030000000000000002000000000000000100"
351 ));
352 interpreter.memory.resize(256);
353
354 let _ = interpreter.stack.push(U256::from(32));
356 let _ = interpreter.stack.push(U256::from(0));
357 let _ = interpreter.stack.push(U256::from(0));
358 interpreter.step(&table, &mut host);
359 assert_eq!(
360 interpreter.control.instruction_result,
361 InstructionResult::Continue
362 );
363 assert_eq!(
364 *interpreter.memory.slice(0..32),
365 interpreter.return_data.buffer()[0..32]
366 );
367
368 let _ = interpreter.stack.push(U256::from(64));
370 let _ = interpreter.stack.push(U256::from(16));
371 let _ = interpreter.stack.push(U256::from(64));
372 interpreter.step(&table, &mut host);
373 assert_eq!(
374 interpreter.control.instruction_result,
375 InstructionResult::Continue
376 );
377 assert_eq!(
378 *interpreter.memory.slice(64..80),
379 interpreter.return_data.buffer()[16..32]
380 );
381 assert_eq!(*interpreter.memory.slice(80..128), [0u8; 48]);
382
383 let _ = interpreter.stack.push(U256::from(32));
385 let _ = interpreter.stack.push(U256::from(96));
386 let _ = interpreter.stack.push(U256::from(128));
387 interpreter.step(&table, &mut host);
388 assert_eq!(
389 interpreter.control.instruction_result,
390 InstructionResult::Continue
391 );
392 assert_eq!(*interpreter.memory.slice(128..160), [0u8; 32]);
393
394 let _ = interpreter.stack.push(U256::from(32));
396 let _ = interpreter.stack.push(U256::MAX);
397 let _ = interpreter.stack.push(U256::from(0));
398 interpreter.step(&table, &mut host);
399 assert_eq!(
400 interpreter.control.instruction_result,
401 InstructionResult::Continue
402 );
403 assert_eq!(*interpreter.memory.slice(0..32), [0u8; 32]);
404
405 let _ = interpreter.stack.push(U256::from(32));
407 let _ = interpreter
408 .stack
409 .push(U256::from(interpreter.return_data.buffer().len() - 32));
410 let _ = interpreter.stack.push(U256::from(0));
411 interpreter.step(&table, &mut host);
412 assert_eq!(
413 interpreter.control.instruction_result,
414 InstructionResult::Continue
415 );
416 assert_eq!(
417 *interpreter.memory.slice(0..32),
418 interpreter.return_data.buffer()[interpreter.return_data.buffer().len() - 32..]
419 );
420
421 let _ = interpreter.stack.push(U256::from(32));
423 let _ = interpreter
424 .stack
425 .push(U256::from(interpreter.return_data.buffer().len()));
426 let _ = interpreter.stack.push(U256::from(0));
427 interpreter.step(&table, &mut host);
428 assert_eq!(
429 interpreter.control.instruction_result,
430 InstructionResult::Continue
431 );
432 assert_eq!(*interpreter.memory.slice(0..32), [0u8; 32]);
433 }
434}