Add msize

This commit is contained in:
wborgeaud 2022-10-20 19:23:01 +02:00
parent 71ed3c43ac
commit 9982d79999
5 changed files with 57 additions and 30 deletions

View File

@ -393,3 +393,21 @@
%mstore_kernel_general_2 %mstore_kernel_general_2
// stack: (empty) // stack: (empty)
%endmacro %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

View File

@ -45,3 +45,23 @@
%macro callvalue %macro callvalue
%mload_context_metadata(@CTX_METADATA_CALL_VALUE) %mload_context_metadata(@CTX_METADATA_CALL_VALUE)
%endmacro %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

View File

@ -23,7 +23,7 @@ pub(crate) enum ContextMetadata {
/// Pointer to the initial version of the state trie, at the creation of this context. Used when /// Pointer to the initial version of the state trie, at the creation of this context. Used when
/// we need to revert a context. /// we need to revert a context.
StateTrieCheckpointPointer = 9, StateTrieCheckpointPointer = 9,
/// Size of active memory. /// Size of the active main memory.
MSize = 10, MSize = 10,
} }

View File

@ -10,6 +10,7 @@ use plonky2_util::ceil_div_usize;
use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::aggregator::KERNEL;
use crate::cpu::kernel::assembler::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::global_metadata::GlobalMetadata;
use crate::cpu::kernel::constants::txn_fields::NormalizedTxnField; use crate::cpu::kernel::constants::txn_fields::NormalizedTxnField;
use crate::generation::memory::{MemoryContextState, MemorySegmentState}; use crate::generation::memory::{MemoryContextState, MemorySegmentState};
@ -46,9 +47,7 @@ impl InterpreterMemory {
mem mem
} }
}
impl InterpreterMemory {
fn mload_general(&mut self, context: usize, segment: Segment, offset: usize) -> U256 { fn mload_general(&mut self, context: usize, segment: Segment, offset: usize) -> U256 {
let value = self.context_memory[context].segments[segment as usize].get(offset); let value = self.context_memory[context].segments[segment as usize].get(offset);
assert!( assert!(
@ -67,6 +66,16 @@ impl InterpreterMemory {
); );
self.context_memory[context].segments[segment as usize].set(offset, value) self.context_memory[context].segments[segment as usize].set(offset, value)
} }
fn update_msize(&mut self, context: usize, offset: usize) {
let current_msize = self.context_memory[context].segments
[Segment::ContextMetadata as usize]
.get(ContextMetadata::MSize as usize);
let msize = ceil_div_usize(offset + 1, 32) * 32;
let new_msize = current_msize.max(msize.into());
self.context_memory[context].segments[Segment::ContextMetadata as usize]
.set(ContextMetadata::MSize as usize, new_msize)
}
} }
pub struct Interpreter<'a> { pub struct Interpreter<'a> {
@ -502,6 +511,8 @@ impl<'a> Interpreter<'a> {
fn run_keccak_general(&mut self) { fn run_keccak_general(&mut self) {
let context = self.pop().as_usize(); let context = self.pop().as_usize();
let segment = Segment::all()[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 offset = self.pop().as_usize();
let size = self.pop().as_usize(); let size = self.pop().as_usize();
let bytes = (offset..offset + size) let bytes = (offset..offset + size)
@ -582,7 +593,8 @@ impl<'a> Interpreter<'a> {
fn run_msize(&mut self) { fn run_msize(&mut self) {
self.push(U256::from( self.push(U256::from(
self.memory.context_memory[self.context].segments[Segment::MainMemory as usize].msize, self.memory.context_memory[self.context].segments[Segment::ContextMetadata as usize]
.get(ContextMetadata::MSize as usize),
)) ))
} }

View File

@ -23,34 +23,19 @@ impl Default for MemoryState {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Default, Debug)]
pub(crate) struct MemoryContextState { pub(crate) struct MemoryContextState {
/// The content of each memory segment. /// The content of each memory segment.
pub segments: [MemorySegmentState; Segment::COUNT], pub segments: [MemorySegmentState; Segment::COUNT],
} }
impl Default for MemoryContextState { #[derive(Clone, Default, Debug)]
fn default() -> Self {
Self {
segments: Segment::all().map(|segment| MemorySegmentState {
content: vec![],
segment,
msize: 0,
}),
}
}
}
#[derive(Clone, Debug)]
pub(crate) struct MemorySegmentState { pub(crate) struct MemorySegmentState {
pub content: Vec<U256>, pub content: Vec<U256>,
pub segment: Segment,
pub msize: usize,
} }
impl MemorySegmentState { impl MemorySegmentState {
pub(crate) fn get(&mut self, virtual_addr: usize) -> U256 { pub(crate) fn get(&self, virtual_addr: usize) -> U256 {
self.update_msize(virtual_addr);
self.content self.content
.get(virtual_addr) .get(virtual_addr)
.copied() .copied()
@ -58,17 +43,9 @@ impl MemorySegmentState {
} }
pub(crate) fn set(&mut self, virtual_addr: usize, value: U256) { pub(crate) fn set(&mut self, virtual_addr: usize, value: U256) {
assert_eq!(value >> self.segment.bit_range(), U256::zero());
self.update_msize(virtual_addr);
if virtual_addr >= self.content.len() { if virtual_addr >= self.content.len() {
self.content.resize(virtual_addr + 1, U256::zero()); self.content.resize(virtual_addr + 1, U256::zero());
} }
self.content[virtual_addr] = value; self.content[virtual_addr] = value;
} }
fn update_msize(&mut self, virtual_addr: usize) {
let word_size = 256 / self.segment.bit_range();
let new_msize = ceil_div_usize(virtual_addr + 1, word_size) * 32;
self.msize = self.msize.max(new_msize);
}
} }