Skip to content
Prev Previous commit
Next Next commit
some cleanup
  • Loading branch information
rakita committed Sep 19, 2023
commit eba8bfbaf9d422375fb389e95c4b646102b1eb97
20 changes: 10 additions & 10 deletions crates/interpreter/src/instructions.rs
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to eval to opcode.rs, and the return instructions to control

Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#[macro_use]
mod macros;
pub mod macros;

mod arithmetic;
mod bitwise;
mod control;
mod host;
mod host_env;
mod i256;
mod memory;
pub mod arithmetic;
pub mod bitwise;
pub mod control;
pub mod host;
pub mod host_env;
pub mod i256;
pub mod memory;
pub mod opcode;
mod stack;
mod system;
pub mod stack;
pub mod system;

pub use opcode::{OpCode, OPCODE_JUMPMAP};
22 changes: 11 additions & 11 deletions crates/interpreter/src/instructions/arithmetic.rs
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • avoid reassigning to 0 when already 0 in div and rem

Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,67 @@ use crate::{
Host, InstructionResult, Interpreter,
};

pub(super) fn wrapped_add(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn wrapped_add(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = op1.wrapping_add(*op2);
}

pub(super) fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn wrapping_mul(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::LOW);
pop_top!(interpreter, op1, op2);
*op2 = op1.wrapping_mul(*op2);
}

pub(super) fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn wrapping_sub(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = op1.wrapping_sub(*op2);
}

pub(super) fn div(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn div(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::LOW);
pop_top!(interpreter, op1, op2);
if *op2 != U256::ZERO {
*op2 = op1.wrapping_div(*op2);
}
}

pub(super) fn sdiv(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn sdiv(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::LOW);
pop_top!(interpreter, op1, op2);
*op2 = i256_div(op1, *op2);
}

pub(super) fn rem(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn rem(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::LOW);
pop_top!(interpreter, op1, op2);
if *op2 != U256::ZERO {
*op2 = op1.wrapping_rem(*op2);
}
}

pub(super) fn smod(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn smod(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::LOW);
pop_top!(interpreter, op1, op2);
if *op2 != U256::ZERO {
*op2 = i256_mod(op1, *op2)
}
}

pub(super) fn addmod(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn addmod(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::MID);
pop_top!(interpreter, op1, op2, op3);
*op3 = op1.add_mod(op2, *op3)
}

pub(super) fn mulmod(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn mulmod(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::MID);
pop_top!(interpreter, op1, op2, op3);
*op3 = op1.mul_mod(op2, *op3)
}

pub(super) fn exp<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn exp<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pop_top!(interpreter, op1, op2);
gas_or_fail!(interpreter, gas::exp_cost::<SPEC>(*op2));
*op2 = op1.pow(*op2);
Expand All @@ -86,7 +86,7 @@ pub(super) fn exp<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Hos
/// `y | !mask` where `|` is the bitwise `OR` and `!` is bitwise negation. Similarly, if
/// `b == 0` then the yellow paper says the output should start with all zeros, then end with
/// bits from `b`; this is equal to `y & mask` where `&` is bitwise `AND`.
pub(super) fn signextend(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn signextend(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::LOW);
pop_top!(interpreter, op1, op2);
if op1 < U256::from(32) {
Expand Down
34 changes: 17 additions & 17 deletions crates/interpreter/src/instructions/bitwise.rs
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • cmp opcodes are now branchless
  • byte indexes into the slice instead of performing shifts
  • sar uses U256::MAX instead of computing it at runtime

Original file line number Diff line number Diff line change
Expand Up @@ -6,67 +6,67 @@ use crate::{
};
use core::cmp::Ordering;

pub(super) fn lt(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn lt(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = U256::from(op1 < *op2);
}

pub(super) fn gt(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn gt(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = U256::from(op1 > *op2);
}

pub(super) fn slt(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn slt(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = U256::from(i256_cmp(&op1, op2) == Ordering::Less);
}

pub(super) fn sgt(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn sgt(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = U256::from(i256_cmp(&op1, op2) == Ordering::Greater);
}

pub(super) fn eq(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn eq(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = U256::from(op1 == *op2);
}

pub(super) fn iszero(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn iszero(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1);
*op1 = U256::from(*op1 == U256::ZERO);
}

pub(super) fn bitand(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn bitand(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = op1 & *op2;
}

pub(super) fn bitor(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn bitor(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = op1 | *op2;
}

pub(super) fn bitxor(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn bitxor(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 = op1 ^ *op2;
}

pub(super) fn not(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn not(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1);
*op1 = !*op1;
}

pub(super) fn byte(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn byte(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);

Expand All @@ -79,24 +79,24 @@ pub(super) fn byte(interpreter: &mut Interpreter, _host: &mut dyn Host) {
};
}

// EIP-145: Bitwise shifting instructions in EVM
pub(super) fn shl<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
/// EIP-145: Bitwise shifting instructions in EVM
pub fn shl<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
check!(interpreter, CONSTANTINOPLE);
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 <<= as_usize_saturated!(op1);
}

// EIP-145: Bitwise shifting instructions in EVM
pub(super) fn shr<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
/// EIP-145: Bitwise shifting instructions in EVM
pub fn shr<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
check!(interpreter, CONSTANTINOPLE);
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
*op2 >>= as_usize_saturated!(op1);
}

// EIP-145: Bitwise shifting instructions in EVM
pub(super) fn sar<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
/// EIP-145: Bitwise shifting instructions in EVM
pub fn sar<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
check!(interpreter, CONSTANTINOPLE);
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, op1, op2);
Expand Down
47 changes: 21 additions & 26 deletions crates/interpreter/src/instructions/control.rs
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • factored out the set up in common for return and revert

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
Host, InstructionResult, Interpreter,
};

pub(super) fn jump(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn jump(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::MID);
pop!(interpreter, dest);
let dest = as_usize_or_fail!(interpreter, dest, InstructionResult::InvalidJump);
Expand All @@ -18,7 +18,7 @@ pub(super) fn jump(interpreter: &mut Interpreter, _host: &mut dyn Host) {
}
}

pub(super) fn jumpi(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn jumpi(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::HIGH);
pop!(interpreter, dest, value);
if value != U256::ZERO {
Expand All @@ -34,54 +34,49 @@ pub(super) fn jumpi(interpreter: &mut Interpreter, _host: &mut dyn Host) {
}
}

pub(super) fn jumpdest(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn jumpdest(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::JUMPDEST);
}

pub(super) fn pc(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn pc(interpreter: &mut Interpreter, _host: &mut dyn Host) {
gas!(interpreter, gas::BASE);
// - 1 because we have already advanced the instruction pointer in `Interpreter::step`
push!(interpreter, U256::from(interpreter.program_counter() - 1));
}

macro_rules! return_setup {
($interpreter:expr) => {
pop!($interpreter, offset, len);
let len = as_usize_or_fail!($interpreter, len);
// important: offset must be ignored if len is zero
if len != 0 {
let offset = as_usize_or_fail!($interpreter, offset);
memory_resize!($interpreter, offset, len);
$interpreter.return_offset = offset;
}
$interpreter.return_len = len;
};
}

pub(super) fn ret(interpreter: &mut Interpreter, _host: &mut dyn Host) {
#[inline]
pub fn ret(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// zero gas cost
// gas!(interpreter, gas::ZERO);
return_setup!(interpreter);
pop!(interpreter, offset, len);
let len = as_usize_or_fail!(interpreter, len);
// important: offset must be ignored if len is zero
if len != 0 {
let offset = as_usize_or_fail!(interpreter, offset);
memory_resize!(interpreter, offset, len);
interpreter.return_offset = offset;
}
interpreter.return_len = len;
interpreter.instruction_result = InstructionResult::Return;
}

// EIP-140: REVERT instruction
pub(super) fn revert<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
/// EIP-140: REVERT instruction
pub fn revert<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// zero gas cost
// gas!(interpreter, gas::ZERO);
check!(interpreter, BYZANTIUM);
return_setup!(interpreter);
ret(interpreter, _host);
interpreter.instruction_result = InstructionResult::Revert;
}

pub(super) fn stop(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn stop(interpreter: &mut Interpreter, _host: &mut dyn Host) {
interpreter.instruction_result = InstructionResult::Stop;
}

pub(super) fn invalid(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn invalid(interpreter: &mut Interpreter, _host: &mut dyn Host) {
interpreter.instruction_result = InstructionResult::InvalidFEOpcode;
}

pub(super) fn not_found(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn not_found(interpreter: &mut Interpreter, _host: &mut dyn Host) {
interpreter.instruction_result = InstructionResult::OpcodeNotFound;
}
Loading