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
10pub fn mload<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
11    gas!(context.interpreter, gas::VERYLOW);
12    popn_top!([], top, context.interpreter);
13    let offset = as_usize_or_fail!(context.interpreter, top);
14    resize_memory!(context.interpreter, offset, 32);
15    *top =
16        U256::try_from_be_slice(context.interpreter.memory.slice_len(offset, 32).as_ref()).unwrap()
17}
18
19pub fn mstore<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
20    gas!(context.interpreter, gas::VERYLOW);
21    popn!([offset, value], context.interpreter);
22    let offset = as_usize_or_fail!(context.interpreter, offset);
23    resize_memory!(context.interpreter, offset, 32);
24    context
25        .interpreter
26        .memory
27        .set(offset, &value.to_be_bytes::<32>());
28}
29
30pub fn mstore8<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
31    gas!(context.interpreter, gas::VERYLOW);
32    popn!([offset, value], context.interpreter);
33    let offset = as_usize_or_fail!(context.interpreter, offset);
34    resize_memory!(context.interpreter, offset, 1);
35    context.interpreter.memory.set(offset, &[value.byte(0)]);
36}
37
38pub fn msize<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
39    gas!(context.interpreter, gas::BASE);
40    push!(
41        context.interpreter,
42        U256::from(context.interpreter.memory.size())
43    );
44}
45
46// EIP-5656: MCOPY - Memory copying instruction
47pub fn mcopy<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
48    check!(context.interpreter, CANCUN);
49    popn!([dst, src, len], context.interpreter);
50
51    // Into usize or fail
52    let len = as_usize_or_fail!(context.interpreter, len);
53    // Deduce gas
54    gas_or_fail!(context.interpreter, gas::copy_cost_verylow(len));
55    if len == 0 {
56        return;
57    }
58
59    let dst = as_usize_or_fail!(context.interpreter, dst);
60    let src = as_usize_or_fail!(context.interpreter, src);
61    // Resize memory
62    resize_memory!(context.interpreter, max(dst, src), len);
63    // Copy memory in place
64    context.interpreter.memory.copy(dst, src, len);
65}