Skip to content

Commit db5d39c

Browse files
committed
perf: remove bounds check in DUP
1 parent 1ca3d39 commit db5d39c

File tree

1 file changed

+15
-2
lines changed
  • crates/interpreter/src/interpreter

1 file changed

+15
-2
lines changed

crates/interpreter/src/interpreter/stack.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
primitives::{B256, U256},
33
InstructionResult,
44
};
5-
use core::fmt;
5+
use core::{fmt, ptr};
66
use std::vec::Vec;
77

88
/// EVM interpreter stack limit.
@@ -222,8 +222,14 @@ impl Stack {
222222
}
223223

224224
/// Duplicates the `N`th value from the top of the stack.
225+
///
226+
/// # Panics
227+
///
228+
/// Panics if `n` is 0.
225229
#[inline]
230+
#[cfg_attr(debug_assertions, track_caller)]
226231
pub fn dup(&mut self, n: usize) -> Result<(), InstructionResult> {
232+
assume!(n > 0, "attempted to dup 0");
227233
let len = self.data.len();
228234
if len < n {
229235
Err(InstructionResult::StackUnderflow)
@@ -232,16 +238,23 @@ impl Stack {
232238
} else {
233239
// SAFETY: check for out of bounds is done above and it makes this safe to do.
234240
unsafe {
241+
let ptr = self.data.as_mut_ptr().add(len);
242+
ptr::copy_nonoverlapping(ptr.sub(n), ptr, 1);
235243
self.data.set_len(len + 1);
236244
}
237-
self.data[len] = self.data[len - n];
238245
Ok(())
239246
}
240247
}
241248

242249
/// Swaps the topmost value with the `N`th value from the top.
250+
///
251+
/// # Panics
252+
///
253+
/// Panics if `n` is 0.
243254
#[inline]
255+
#[cfg_attr(debug_assertions, track_caller)]
244256
pub fn swap(&mut self, n: usize) -> Result<(), InstructionResult> {
257+
assume!(n > 0, "attempted to swap with 0");
245258
let len = self.data.len();
246259
if n >= len {
247260
return Err(InstructionResult::StackUnderflow);

0 commit comments

Comments
 (0)