revm_interpreter/instructions/
memory.rs

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