revm_interpreter/instructions/
memory.rs

1use crate::{
2    gas,
3    primitives::{Spec, U256},
4    Host, Interpreter,
5};
6use core::cmp::max;
7
8pub fn mload<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
9    gas!(interpreter, gas::VERYLOW);
10    pop_top!(interpreter, top);
11    let offset = as_usize_or_fail!(interpreter, top);
12    resize_memory!(interpreter, offset, 32);
13    *top = interpreter.shared_memory.get_u256(offset);
14}
15
16pub fn mstore<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
17    gas!(interpreter, gas::VERYLOW);
18    pop!(interpreter, offset, value);
19    let offset = as_usize_or_fail!(interpreter, offset);
20    resize_memory!(interpreter, offset, 32);
21    interpreter.shared_memory.set_u256(offset, value);
22}
23
24pub fn mstore8<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
25    gas!(interpreter, gas::VERYLOW);
26    pop!(interpreter, offset, value);
27    let offset = as_usize_or_fail!(interpreter, offset);
28    resize_memory!(interpreter, offset, 1);
29    interpreter.shared_memory.set_byte(offset, value.byte(0))
30}
31
32pub fn msize<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
33    gas!(interpreter, gas::BASE);
34    push!(interpreter, U256::from(interpreter.shared_memory.len()));
35}
36
37// EIP-5656: MCOPY - Memory copying instruction
38pub fn mcopy<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut H) {
39    check!(interpreter, CANCUN);
40    pop!(interpreter, dst, src, len);
41
42    // into usize or fail
43    let len = as_usize_or_fail!(interpreter, len);
44    // deduce gas
45    gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64));
46    if len == 0 {
47        return;
48    }
49
50    let dst = as_usize_or_fail!(interpreter, dst);
51    let src = as_usize_or_fail!(interpreter, src);
52    // resize memory
53    resize_memory!(interpreter, max(dst, src), len);
54    // copy memory in place
55    interpreter.shared_memory.copy(dst, src, len);
56}