revm_interpreter/instructions/
memory.rs

1use crate::{
2    gas,
3    interpreter::Interpreter,
4    interpreter_types::{InterpreterTypes, LoopControl, MemoryTr, RuntimeFlag, StackTr},
5    Host,
6};
7use core::cmp::max;
8use primitives::U256;
9
10pub fn mload<WIRE: InterpreterTypes, H: Host + ?Sized>(
11    interpreter: &mut Interpreter<WIRE>,
12    _host: &mut H,
13) {
14    gas!(interpreter, gas::VERYLOW);
15    popn_top!([], top, interpreter);
16    let offset = as_usize_or_fail!(interpreter, top);
17    resize_memory!(interpreter, offset, 32);
18    *top = U256::try_from_be_slice(interpreter.memory.slice_len(offset, 32).as_ref()).unwrap()
19}
20
21pub fn mstore<WIRE: InterpreterTypes, H: Host + ?Sized>(
22    interpreter: &mut Interpreter<WIRE>,
23    _host: &mut H,
24) {
25    gas!(interpreter, gas::VERYLOW);
26    popn!([offset, value], interpreter);
27    let offset = as_usize_or_fail!(interpreter, offset);
28    resize_memory!(interpreter, offset, 32);
29    interpreter.memory.set(offset, &value.to_be_bytes::<32>());
30}
31
32pub fn mstore8<WIRE: InterpreterTypes, H: Host + ?Sized>(
33    interpreter: &mut Interpreter<WIRE>,
34    _host: &mut H,
35) {
36    gas!(interpreter, gas::VERYLOW);
37    popn!([offset, value], interpreter);
38    let offset = as_usize_or_fail!(interpreter, offset);
39    resize_memory!(interpreter, offset, 1);
40    interpreter.memory.set(offset, &[value.byte(0)]);
41}
42
43pub fn msize<WIRE: InterpreterTypes, H: Host + ?Sized>(
44    interpreter: &mut Interpreter<WIRE>,
45    _host: &mut H,
46) {
47    gas!(interpreter, gas::BASE);
48    push!(interpreter, U256::from(interpreter.memory.size()));
49}
50
51// EIP-5656: MCOPY - Memory copying instruction
52pub fn mcopy<WIRE: InterpreterTypes, H: Host + ?Sized>(
53    interpreter: &mut Interpreter<WIRE>,
54    _host: &mut H,
55) {
56    check!(interpreter, CANCUN);
57    popn!([dst, src, len], interpreter);
58
59    // Into usize or fail
60    let len = as_usize_or_fail!(interpreter, len);
61    // Deduce gas
62    gas_or_fail!(interpreter, gas::copy_cost_verylow(len));
63    if len == 0 {
64        return;
65    }
66
67    let dst = as_usize_or_fail!(interpreter, dst);
68    let src = as_usize_or_fail!(interpreter, src);
69    // Resize memory
70    resize_memory!(interpreter, max(dst, src), len);
71    // Copy memory in place
72    interpreter.memory.copy(dst, src, len);
73}