revm_interpreter/instructions/
memory.rs

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