use crate::interpreter::resize_memory;
use crate::interpreter_types::{InterpreterTypes as ITy, MemoryTr, RuntimeFlag, StackTr};
use crate::{InstructionContext as Ictx, InstructionExecResult as Result};
use context_interface::Host;
use core::cmp::max;
use primitives::U256;
pub fn mload<IT: ITy, H: Host + ?Sized>(context: Ictx<'_, H, IT>) -> Result {
popn_top!([], top, context.interpreter);
let offset = as_usize_or_fail!(context.interpreter, top);
resize_memory(
&mut context.interpreter.gas,
&mut context.interpreter.memory,
context.host.gas_params(),
offset,
32,
)?;
*top =
U256::try_from_be_slice(context.interpreter.memory.slice_len(offset, 32).as_ref()).unwrap();
Ok(())
}
pub fn mstore<IT: ITy, H: Host + ?Sized>(context: Ictx<'_, H, IT>) -> Result {
popn!([offset, value], context.interpreter);
let offset = as_usize_or_fail!(context.interpreter, offset);
context
.interpreter
.resize_memory(context.host.gas_params(), offset, 32)?;
context
.interpreter
.memory
.set(offset, &value.to_be_bytes::<32>());
Ok(())
}
pub fn mstore8<IT: ITy, H: Host + ?Sized>(context: Ictx<'_, H, IT>) -> Result {
popn!([offset, value], context.interpreter);
let offset = as_usize_or_fail!(context.interpreter, offset);
context
.interpreter
.resize_memory(context.host.gas_params(), offset, 1)?;
context.interpreter.memory.set(offset, &[value.byte(0)]);
Ok(())
}
pub fn msize<IT: ITy, H: ?Sized>(context: Ictx<'_, H, IT>) -> Result {
push!(
context.interpreter,
U256::from(context.interpreter.memory.size())
);
Ok(())
}
pub fn mcopy<IT: ITy, H: Host + ?Sized>(context: Ictx<'_, H, IT>) -> Result {
check!(context.interpreter, CANCUN);
popn!([dst, src, len], context.interpreter);
let len = as_usize_or_fail!(context.interpreter, len);
gas!(
context.interpreter,
context.host.gas_params().mcopy_cost(len)
);
if len == 0 {
return Ok(());
}
let dst = as_usize_or_fail!(context.interpreter, dst);
let src = as_usize_or_fail!(context.interpreter, src);
context
.interpreter
.resize_memory(context.host.gas_params(), max(dst, src), len)?;
context.interpreter.memory.copy(dst, src, len);
Ok(())
}