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