Skip to content

Commit

Permalink
use copy_within for MCOPY
Browse files Browse the repository at this point in the history
  • Loading branch information
snissn committed Aug 14, 2024
1 parent 50f466f commit c7df38d
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions actors/evm/src/interpreter/instructions/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,39 @@ pub fn mcopy(
src_index: U256,
size: U256,
) -> Result<(), ActorError> {
// We are copying between two potentially overlapping slices in the same memory.
// MCOPY spec: Copying takes place as if an intermediate buffer was used,
// allowing the destination and source to overlap.
// Copy memory from src_index to dest_index.
// Handles overlapping slices as if using an intermediate buffer, ensuring correct copying.
// Expands memory if src_index + size or dest_index + size exceeds current bounds.
// Returns an error if memory regions are invalid or cannot be allocated.

// expand memory to accomodate requested src_index + size
let region = get_memory_region(&mut state.memory, src_index, size)?.expect("empty region");
let memory_slice = state.memory[region.offset..region.offset + region.size.get()].to_vec();
copy_within_memory(&mut state.memory, dest_index, src_index, size)
}

pub fn copy_within_memory(
memory: &mut Memory,
dest_index: U256,
src_index: U256,
size: U256,
) -> Result<(), ActorError> {
// Expand memory to accommodate requested src_index + size
let region = get_memory_region(memory, src_index, size)?.expect("empty region");

// Expand memory to match dest_index + size
let _destination_region = get_memory_region(memory, dest_index, size)?.expect("empty region");

if size > 0 {
let src_start = src_index.low_u64() as usize;
let src_end = src_start + size.low_u64() as usize;
let dest_start = dest_index.low_u64() as usize;

// expand memory to match dest_index + size
let _destination_region =
get_memory_region(&mut state.memory, dest_index, size)?.expect("empty region");
// Named variables for clarity
let source_range = src_start..src_end;
let destination_index = dest_start;

//copy
copy_to_memory(&mut state.memory, dest_index, size, U256::zero(), &memory_slice, true)
memory.copy_within(source_range, destination_index);
}

Ok(())
}

pub fn copy_to_memory(
Expand Down

0 comments on commit c7df38d

Please sign in to comment.