1use revm_interpreter::{Gas, InstructionResult, SharedMemory, as_usize_saturated};
2use revmc_context::{EvmContext, EvmWord};
3
4#[inline(always)]
14pub(crate) unsafe fn read_words_rev<'a, const N: usize>(sp: *mut EvmWord) -> &'a mut [EvmWord; N] {
15 &mut *sp.cast::<[EvmWord; N]>()
16}
17
18#[inline]
19pub(crate) fn ensure_memory(
20 ecx: &mut EvmContext<'_>,
21 offset: usize,
22 len: usize,
23) -> InstructionResult {
24 ensure_memory_inner(ecx.memory, ecx.gas, offset, len)
25}
26
27#[inline]
28pub(crate) fn ensure_memory_inner(
29 memory: &mut SharedMemory,
30 gas: &mut Gas,
31 offset: usize,
32 len: usize,
33) -> InstructionResult {
34 let new_size = offset.saturating_add(len);
35 if new_size > memory.len() {
36 return resize_memory_inner(memory, gas, new_size);
37 }
38 InstructionResult::Stop
39}
40
41#[inline]
42pub(crate) fn resize_memory(ecx: &mut EvmContext<'_>, new_size: usize) -> InstructionResult {
43 resize_memory_inner(ecx.memory, ecx.gas, new_size)
44}
45
46fn resize_memory_inner(
47 memory: &mut SharedMemory,
48 gas: &mut Gas,
49 new_size: usize,
50) -> InstructionResult {
51 let new_num_words = revm_interpreter::interpreter::num_words(new_size);
53 let current_words = gas.memory().words_num;
54
55 if new_num_words > current_words {
56 let new_cost = crate::gas::memory_gas(new_num_words, 3, 512);
60 let old_cost = crate::gas::memory_gas(current_words, 3, 512);
61 let cost = new_cost.saturating_sub(old_cost);
62
63 if !gas.record_cost(cost) {
64 return InstructionResult::MemoryOOG;
65 }
66
67 gas.memory_mut().words_num = new_num_words;
69
70 memory.resize(new_num_words * 32);
72 }
73 InstructionResult::Stop
74}
75
76pub(crate) unsafe fn copy_operation(
77 ecx: &mut EvmContext<'_>,
78 rev![memory_offset, data_offset, len]: &mut [EvmWord; 3],
79 data: &[u8],
80) -> InstructionResult {
81 let len = try_into_usize!(len);
82 if len != 0 {
83 gas!(ecx, ecx.host.gas_params().copy_cost(len));
84 let memory_offset = try_into_usize!(memory_offset);
85 ensure_memory!(ecx, memory_offset, len);
86 let data_offset = data_offset.to_u256();
87 let data_offset = as_usize_saturated!(data_offset);
88 ecx.memory.set_data(memory_offset, data_offset, len, data);
89 }
90 InstructionResult::Stop
91}