revm_interpreter/instructions/
memory.rs

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