diff --git a/evm/src/cpu/kernel/asm/memory/core.asm b/evm/src/cpu/kernel/asm/memory/core.asm index 2b4d2b68..f6bb99b6 100644 --- a/evm/src/cpu/kernel/asm/memory/core.asm +++ b/evm/src/cpu/kernel/asm/memory/core.asm @@ -393,3 +393,21 @@ %mstore_kernel_general_2 // stack: (empty) %endmacro + +%macro mload_main + // stack: offset + DUP1 + // stack: offset, offset + %update_msize + // stack: offset + %mload_current(@SEGMENT_MAIN_MEMORY) +%endmacro + +%macro mstore_main + // stack: offset, value + DUP1 + // stack: offset, offset, value + %update_msize + // stack: offset, value + %mstore_current(@SEGMENT_MAIN_MEMORY) +%endmacro diff --git a/evm/src/cpu/kernel/asm/memory/metadata.asm b/evm/src/cpu/kernel/asm/memory/metadata.asm index 644699e0..1a495682 100644 --- a/evm/src/cpu/kernel/asm/memory/metadata.asm +++ b/evm/src/cpu/kernel/asm/memory/metadata.asm @@ -45,3 +45,23 @@ %macro callvalue %mload_context_metadata(@CTX_METADATA_CALL_VALUE) %endmacro + +%macro msize + %mload_context_metadata(@CTX_METADATA_MSIZE) +%endmacro + +%macro update_msize + // stack: offset + %add_const(32) + // stack: 32 + offset + %div_const(32) + // stack: (offset+32)/32 = ceil_div_usize(offset+1, 32) + %mul_const(32) + // stack: ceil_div_usize(offset+1, 32) * 32 + %msize + // stack: current_msize, ceil_div_usize(offset+1, 32) * 32 + %max + // stack: new_msize + %mstore_context_metadata(@CTX_METADATA_MSIZE) +%endmacro + diff --git a/evm/src/cpu/kernel/constants/context_metadata.rs b/evm/src/cpu/kernel/constants/context_metadata.rs index a2c460fc..fab74373 100644 --- a/evm/src/cpu/kernel/constants/context_metadata.rs +++ b/evm/src/cpu/kernel/constants/context_metadata.rs @@ -23,10 +23,12 @@ pub(crate) enum ContextMetadata { /// Pointer to the initial version of the state trie, at the creation of this context. Used when /// we need to revert a context. StateTrieCheckpointPointer = 9, + /// Size of the active main memory. + MSize = 10, } impl ContextMetadata { - pub(crate) const COUNT: usize = 10; + pub(crate) const COUNT: usize = 11; pub(crate) fn all() -> [Self; Self::COUNT] { [ @@ -40,6 +42,7 @@ impl ContextMetadata { Self::CallValue, Self::Static, Self::StateTrieCheckpointPointer, + Self::MSize, ] } @@ -56,6 +59,7 @@ impl ContextMetadata { ContextMetadata::CallValue => "CTX_METADATA_CALL_VALUE", ContextMetadata::Static => "CTX_METADATA_STATIC", ContextMetadata::StateTrieCheckpointPointer => "CTX_METADATA_STATE_TRIE_CHECKPOINT_PTR", + ContextMetadata::MSize => "CTX_METADATA_MSIZE", } } } diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index a2c25bf6..f6cae73e 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -9,6 +9,7 @@ use plonky2::field::goldilocks_field::GoldilocksField; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::assembler::Kernel; +use crate::cpu::kernel::constants::context_metadata::ContextMetadata; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::constants::txn_fields::NormalizedTxnField; use crate::generation::memory::{MemoryContextState, MemorySegmentState}; @@ -45,9 +46,7 @@ impl InterpreterMemory { mem } -} -impl InterpreterMemory { fn mload_general(&self, context: usize, segment: Segment, offset: usize) -> U256 { let value = self.context_memory[context].segments[segment as usize].get(offset); assert!( @@ -499,6 +498,8 @@ impl<'a> Interpreter<'a> { fn run_keccak_general(&mut self) { let context = self.pop().as_usize(); let segment = Segment::all()[self.pop().as_usize()]; + // Not strictly needed but here to avoid surprises with MSIZE. + assert_ne!(segment, Segment::MainMemory, "Call KECCAK256 instead."); let offset = self.pop().as_usize(); let size = self.pop().as_usize(); let bytes = (offset..offset + size) @@ -578,11 +579,10 @@ impl<'a> Interpreter<'a> { } fn run_msize(&mut self) { - let num_bytes = self.memory.context_memory[self.context].segments - [Segment::MainMemory as usize] - .content - .len(); - self.push(U256::from(num_bytes)); + self.push( + self.memory.context_memory[self.context].segments[Segment::ContextMetadata as usize] + .get(ContextMetadata::MSize as usize), + ) } fn run_jumpdest(&mut self) {