From 9028d3b3a2209af24500846f1929c3e3b1efeed2 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Sun, 29 Oct 2023 18:48:05 +0100 Subject: [PATCH] Introduce the concept of Etable in core --- core/src/eval/misc.rs | 36 +-- core/src/eval/mod.rs | 698 ++++++++++++++++++++++-------------------- core/src/lib.rs | 48 +-- rust-toolchain.toml | 2 +- 4 files changed, 404 insertions(+), 380 deletions(-) diff --git a/core/src/eval/misc.rs b/core/src/eval/misc.rs index 398bcc34c..b04bc6308 100644 --- a/core/src/eval/misc.rs +++ b/core/src/eval/misc.rs @@ -4,7 +4,7 @@ use core::cmp::min; use primitive_types::{H256, U256}; #[inline] -pub fn codesize(state: &mut Machine) -> Control { +pub fn codesize(state: &mut Machine) -> Control { let size = U256::from(state.code.len()); trace_op!("CodeSize: {}", size); push_u256!(state, size); @@ -12,7 +12,7 @@ pub fn codesize(state: &mut Machine) -> Control { } #[inline] -pub fn codecopy(state: &mut Machine) -> Control { +pub fn codecopy(state: &mut Machine) -> Control { pop_u256!(state, memory_offset, code_offset, len); trace_op!("CodeCopy: {}", len); @@ -27,7 +27,7 @@ pub fn codecopy(state: &mut Machine) -> Control { } #[inline] -pub fn calldataload(state: &mut Machine) -> Control { +pub fn calldataload(state: &mut Machine) -> Control { pop_u256!(state, index); let mut load = [0u8; 32]; @@ -48,7 +48,7 @@ pub fn calldataload(state: &mut Machine) -> Control { } #[inline] -pub fn calldatasize(state: &mut Machine) -> Control { +pub fn calldatasize(state: &mut Machine) -> Control { let len = U256::from(state.data.len()); trace_op!("CallDataSize: {}", len); push_u256!(state, len); @@ -56,7 +56,7 @@ pub fn calldatasize(state: &mut Machine) -> Control { } #[inline] -pub fn calldatacopy(state: &mut Machine) -> Control { +pub fn calldatacopy(state: &mut Machine) -> Control { pop_u256!(state, memory_offset, data_offset, len); trace_op!("CallDataCopy: {}", len); @@ -75,14 +75,14 @@ pub fn calldatacopy(state: &mut Machine) -> Control { } #[inline] -pub fn pop(state: &mut Machine) -> Control { +pub fn pop(state: &mut Machine) -> Control { pop!(state, _val); trace_op!("Pop [@{}]: {}", state.stack.len(), _val); Control::Continue(1) } #[inline] -pub fn mload(state: &mut Machine) -> Control { +pub fn mload(state: &mut Machine) -> Control { pop_u256!(state, index); trace_op!("MLoad: {}", index); try_or_fail!(state.memory.resize_offset(index, U256::from(32))); @@ -93,7 +93,7 @@ pub fn mload(state: &mut Machine) -> Control { } #[inline] -pub fn mstore(state: &mut Machine) -> Control { +pub fn mstore(state: &mut Machine) -> Control { pop_u256!(state, index); pop!(state, value); trace_op!("MStore: {}, {}", index, value); @@ -106,7 +106,7 @@ pub fn mstore(state: &mut Machine) -> Control { } #[inline] -pub fn mstore8(state: &mut Machine) -> Control { +pub fn mstore8(state: &mut Machine) -> Control { pop_u256!(state, index, value); try_or_fail!(state.memory.resize_offset(index, U256::one())); let index = as_usize_or_fail!(index); @@ -118,7 +118,7 @@ pub fn mstore8(state: &mut Machine) -> Control { } #[inline] -pub fn jump(state: &mut Machine) -> Control { +pub fn jump(state: &mut Machine) -> Control { pop_u256!(state, dest); let dest = as_usize_or_fail!(dest, ExitError::InvalidJump); trace_op!("Jump: {}", dest); @@ -131,7 +131,7 @@ pub fn jump(state: &mut Machine) -> Control { } #[inline] -pub fn jumpi(state: &mut Machine) -> Control { +pub fn jumpi(state: &mut Machine) -> Control { pop_u256!(state, dest); pop!(state, value); @@ -150,20 +150,20 @@ pub fn jumpi(state: &mut Machine) -> Control { } #[inline] -pub fn pc(state: &mut Machine, position: usize) -> Control { +pub fn pc(state: &mut Machine, position: usize) -> Control { trace_op!("PC"); push_u256!(state, U256::from(position)); Control::Continue(1) } #[inline] -pub fn msize(state: &mut Machine) -> Control { +pub fn msize(state: &mut Machine) -> Control { push_u256!(state, state.memory.effective_len()); Control::Continue(1) } #[inline] -pub fn push(state: &mut Machine, n: usize, position: usize) -> Control { +pub fn push(state: &mut Machine, n: usize, position: usize) -> Control { let end = min(position + 1 + n, state.code.len()); let slice = &state.code[(position + 1)..end]; let mut val = [0u8; 32]; @@ -176,7 +176,7 @@ pub fn push(state: &mut Machine, n: usize, position: usize) -> Control { } #[inline] -pub fn dup(state: &mut Machine, n: usize) -> Control { +pub fn dup(state: &mut Machine, n: usize) -> Control { let value = match state.stack.peek(n - 1) { Ok(value) => value, Err(e) => return Control::Exit(e.into()), @@ -187,7 +187,7 @@ pub fn dup(state: &mut Machine, n: usize) -> Control { } #[inline] -pub fn swap(state: &mut Machine, n: usize) -> Control { +pub fn swap(state: &mut Machine, n: usize) -> Control { let val1 = match state.stack.peek(0) { Ok(value) => value, Err(e) => return Control::Exit(e.into()), @@ -209,7 +209,7 @@ pub fn swap(state: &mut Machine, n: usize) -> Control { } #[inline] -pub fn ret(state: &mut Machine) -> Control { +pub fn ret(state: &mut Machine) -> Control { trace_op!("Return"); pop_u256!(state, start, len); try_or_fail!(state.memory.resize_offset(start, len)); @@ -218,7 +218,7 @@ pub fn ret(state: &mut Machine) -> Control { } #[inline] -pub fn revert(state: &mut Machine) -> Control { +pub fn revert(state: &mut Machine) -> Control { trace_op!("Revert"); pop_u256!(state, start, len); try_or_fail!(state.memory.resize_offset(start, len)); diff --git a/core/src/eval/mod.rs b/core/src/eval/mod.rs index 519f5d925..064eb7cf6 100644 --- a/core/src/eval/mod.rs +++ b/core/src/eval/mod.rs @@ -5,9 +5,153 @@ mod bitwise; mod misc; use crate::{ExitError, ExitReason, ExitSucceed, Machine, Opcode}; -use core::ops::{BitAnd, BitOr, BitXor}; +use core::ops::{BitAnd, BitOr, BitXor, Deref}; use primitive_types::{H256, U256}; +/// Evaluation function type. +pub type Efn = fn(&mut Machine, Opcode, usize) -> Control; + +/// The evaluation table for the EVM. +#[derive(Clone)] +pub struct Etable([Efn; 256]); + +impl Deref for Etable { + type Target = [Efn; 256]; + + fn deref(&self) -> &[Efn; 256] { + &self.0 + } +} + +impl Etable { + /// Default core value for Etable. + pub const fn core() -> Etable { + let mut table = [eval_external as _; 256]; + + table[Opcode::STOP.as_usize()] = eval_stop as _; + table[Opcode::ADD.as_usize()] = eval_add as _; + table[Opcode::MUL.as_usize()] = eval_mul as _; + table[Opcode::SUB.as_usize()] = eval_sub as _; + table[Opcode::DIV.as_usize()] = eval_div as _; + table[Opcode::SDIV.as_usize()] = eval_sdiv as _; + table[Opcode::MOD.as_usize()] = eval_mod as _; + table[Opcode::SMOD.as_usize()] = eval_smod as _; + table[Opcode::ADDMOD.as_usize()] = eval_addmod as _; + table[Opcode::MULMOD.as_usize()] = eval_mulmod as _; + table[Opcode::EXP.as_usize()] = eval_exp as _; + table[Opcode::SIGNEXTEND.as_usize()] = eval_signextend as _; + table[Opcode::LT.as_usize()] = eval_lt as _; + table[Opcode::GT.as_usize()] = eval_gt as _; + table[Opcode::SLT.as_usize()] = eval_slt as _; + table[Opcode::SGT.as_usize()] = eval_sgt as _; + table[Opcode::EQ.as_usize()] = eval_eq as _; + table[Opcode::ISZERO.as_usize()] = eval_iszero as _; + table[Opcode::AND.as_usize()] = eval_and as _; + table[Opcode::OR.as_usize()] = eval_or as _; + table[Opcode::XOR.as_usize()] = eval_xor as _; + table[Opcode::NOT.as_usize()] = eval_not as _; + table[Opcode::BYTE.as_usize()] = eval_byte as _; + table[Opcode::SHL.as_usize()] = eval_shl as _; + table[Opcode::SHR.as_usize()] = eval_shr as _; + table[Opcode::SAR.as_usize()] = eval_sar as _; + table[Opcode::CODESIZE.as_usize()] = eval_codesize as _; + table[Opcode::CODECOPY.as_usize()] = eval_codecopy as _; + table[Opcode::CALLDATALOAD.as_usize()] = eval_calldataload as _; + table[Opcode::CALLDATASIZE.as_usize()] = eval_calldatasize as _; + table[Opcode::CALLDATACOPY.as_usize()] = eval_calldatacopy as _; + table[Opcode::POP.as_usize()] = eval_pop as _; + table[Opcode::MLOAD.as_usize()] = eval_mload as _; + table[Opcode::MSTORE.as_usize()] = eval_mstore as _; + table[Opcode::MSTORE8.as_usize()] = eval_mstore8 as _; + table[Opcode::JUMP.as_usize()] = eval_jump as _; + table[Opcode::JUMPI.as_usize()] = eval_jumpi as _; + table[Opcode::PC.as_usize()] = eval_pc as _; + table[Opcode::MSIZE.as_usize()] = eval_msize as _; + table[Opcode::JUMPDEST.as_usize()] = eval_jumpdest as _; + + table[Opcode::PUSH0.as_usize()] = eval_push0 as _; + table[Opcode::PUSH1.as_usize()] = eval_push1 as _; + table[Opcode::PUSH2.as_usize()] = eval_push2 as _; + table[Opcode::PUSH3.as_usize()] = eval_push3 as _; + table[Opcode::PUSH4.as_usize()] = eval_push4 as _; + table[Opcode::PUSH5.as_usize()] = eval_push5 as _; + table[Opcode::PUSH6.as_usize()] = eval_push6 as _; + table[Opcode::PUSH7.as_usize()] = eval_push7 as _; + table[Opcode::PUSH8.as_usize()] = eval_push8 as _; + table[Opcode::PUSH9.as_usize()] = eval_push9 as _; + table[Opcode::PUSH10.as_usize()] = eval_push10 as _; + table[Opcode::PUSH11.as_usize()] = eval_push11 as _; + table[Opcode::PUSH12.as_usize()] = eval_push12 as _; + table[Opcode::PUSH13.as_usize()] = eval_push13 as _; + table[Opcode::PUSH14.as_usize()] = eval_push14 as _; + table[Opcode::PUSH15.as_usize()] = eval_push15 as _; + table[Opcode::PUSH16.as_usize()] = eval_push16 as _; + table[Opcode::PUSH17.as_usize()] = eval_push17 as _; + table[Opcode::PUSH18.as_usize()] = eval_push18 as _; + table[Opcode::PUSH19.as_usize()] = eval_push19 as _; + table[Opcode::PUSH20.as_usize()] = eval_push20 as _; + table[Opcode::PUSH21.as_usize()] = eval_push21 as _; + table[Opcode::PUSH22.as_usize()] = eval_push22 as _; + table[Opcode::PUSH23.as_usize()] = eval_push23 as _; + table[Opcode::PUSH24.as_usize()] = eval_push24 as _; + table[Opcode::PUSH25.as_usize()] = eval_push25 as _; + table[Opcode::PUSH26.as_usize()] = eval_push26 as _; + table[Opcode::PUSH27.as_usize()] = eval_push27 as _; + table[Opcode::PUSH28.as_usize()] = eval_push28 as _; + table[Opcode::PUSH29.as_usize()] = eval_push29 as _; + table[Opcode::PUSH30.as_usize()] = eval_push30 as _; + table[Opcode::PUSH31.as_usize()] = eval_push31 as _; + table[Opcode::PUSH32.as_usize()] = eval_push32 as _; + + table[Opcode::DUP1.as_usize()] = eval_dup1 as _; + table[Opcode::DUP2.as_usize()] = eval_dup2 as _; + table[Opcode::DUP3.as_usize()] = eval_dup3 as _; + table[Opcode::DUP4.as_usize()] = eval_dup4 as _; + table[Opcode::DUP5.as_usize()] = eval_dup5 as _; + table[Opcode::DUP6.as_usize()] = eval_dup6 as _; + table[Opcode::DUP7.as_usize()] = eval_dup7 as _; + table[Opcode::DUP8.as_usize()] = eval_dup8 as _; + table[Opcode::DUP9.as_usize()] = eval_dup9 as _; + table[Opcode::DUP10.as_usize()] = eval_dup10 as _; + table[Opcode::DUP11.as_usize()] = eval_dup11 as _; + table[Opcode::DUP12.as_usize()] = eval_dup12 as _; + table[Opcode::DUP13.as_usize()] = eval_dup13 as _; + table[Opcode::DUP14.as_usize()] = eval_dup14 as _; + table[Opcode::DUP15.as_usize()] = eval_dup15 as _; + table[Opcode::DUP16.as_usize()] = eval_dup16 as _; + + table[Opcode::SWAP1.as_usize()] = eval_swap1 as _; + table[Opcode::SWAP2.as_usize()] = eval_swap2 as _; + table[Opcode::SWAP3.as_usize()] = eval_swap3 as _; + table[Opcode::SWAP4.as_usize()] = eval_swap4 as _; + table[Opcode::SWAP5.as_usize()] = eval_swap5 as _; + table[Opcode::SWAP6.as_usize()] = eval_swap6 as _; + table[Opcode::SWAP7.as_usize()] = eval_swap7 as _; + table[Opcode::SWAP8.as_usize()] = eval_swap8 as _; + table[Opcode::SWAP9.as_usize()] = eval_swap9 as _; + table[Opcode::SWAP10.as_usize()] = eval_swap10 as _; + table[Opcode::SWAP11.as_usize()] = eval_swap11 as _; + table[Opcode::SWAP12.as_usize()] = eval_swap12 as _; + table[Opcode::SWAP13.as_usize()] = eval_swap13 as _; + table[Opcode::SWAP14.as_usize()] = eval_swap14 as _; + table[Opcode::SWAP15.as_usize()] = eval_swap15 as _; + table[Opcode::SWAP16.as_usize()] = eval_swap16 as _; + + table[Opcode::RETURN.as_usize()] = eval_return as _; + table[Opcode::REVERT.as_usize()] = eval_revert as _; + table[Opcode::INVALID.as_usize()] = eval_invalid as _; + + Self(table) + } +} + +impl Default for Etable<()> { + fn default() -> Self { + Self::core() + } +} + +/// Control state. #[derive(Clone, Eq, PartialEq, Debug)] pub enum Control { Continue(usize), @@ -16,562 +160,438 @@ pub enum Control { Trap(Opcode), } -fn eval_stop(_state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { +fn eval_stop(_machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { Control::Exit(ExitSucceed::Stopped.into()) } -fn eval_add(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_tuple!(state, overflowing_add) +fn eval_add(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_tuple!(machine, overflowing_add) } -fn eval_mul(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_tuple!(state, overflowing_mul) +fn eval_mul(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_tuple!(machine, overflowing_mul) } -fn eval_sub(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_tuple!(state, overflowing_sub) +fn eval_sub(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_tuple!(machine, overflowing_sub) } -fn eval_div(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::arithmetic::div) +fn eval_div(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::arithmetic::div) } -fn eval_sdiv(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::arithmetic::sdiv) +fn eval_sdiv(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::arithmetic::sdiv) } -fn eval_mod(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::arithmetic::rem) +fn eval_mod(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::arithmetic::rem) } -fn eval_smod(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::arithmetic::srem) +fn eval_smod(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::arithmetic::srem) } -fn eval_addmod(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op3_u256_fn!(state, self::arithmetic::addmod) +fn eval_addmod(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op3_u256_fn!(machine, self::arithmetic::addmod) } -fn eval_mulmod(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op3_u256_fn!(state, self::arithmetic::mulmod) +fn eval_mulmod(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op3_u256_fn!(machine, self::arithmetic::mulmod) } -fn eval_exp(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::arithmetic::exp) +fn eval_exp(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::arithmetic::exp) } -fn eval_signextend(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::arithmetic::signextend) +fn eval_signextend(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::arithmetic::signextend) } -fn eval_lt(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_bool_ref!(state, lt) +fn eval_lt(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_bool_ref!(machine, lt) } -fn eval_gt(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_bool_ref!(state, gt) +fn eval_gt(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_bool_ref!(machine, gt) } -fn eval_slt(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::bitwise::slt) +fn eval_slt(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::bitwise::slt) } -fn eval_sgt(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::bitwise::sgt) +fn eval_sgt(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::bitwise::sgt) } -fn eval_eq(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_bool_ref!(state, eq) +fn eval_eq(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_bool_ref!(machine, eq) } -fn eval_iszero(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op1_u256_fn!(state, self::bitwise::iszero) +fn eval_iszero(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op1_u256_fn!(machine, self::bitwise::iszero) } -fn eval_and(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256!(state, bitand) +fn eval_and(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256!(machine, bitand) } -fn eval_or(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256!(state, bitor) +fn eval_or(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256!(machine, bitor) } -fn eval_xor(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256!(state, bitxor) +fn eval_xor(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256!(machine, bitxor) } -fn eval_not(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op1_u256_fn!(state, self::bitwise::not) +fn eval_not(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op1_u256_fn!(machine, self::bitwise::not) } -fn eval_byte(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::bitwise::byte) +fn eval_byte(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::bitwise::byte) } -fn eval_shl(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::bitwise::shl) +fn eval_shl(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::bitwise::shl) } -fn eval_shr(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::bitwise::shr) +fn eval_shr(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::bitwise::shr) } -fn eval_sar(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - op2_u256_fn!(state, self::bitwise::sar) +fn eval_sar(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + op2_u256_fn!(machine, self::bitwise::sar) } -fn eval_codesize(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::codesize(state) +fn eval_codesize(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::codesize(machine) } -fn eval_codecopy(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::codecopy(state) +fn eval_codecopy(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::codecopy(machine) } -fn eval_calldataload(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::calldataload(state) +fn eval_calldataload(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::calldataload(machine) } -fn eval_calldatasize(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::calldatasize(state) +fn eval_calldatasize(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::calldatasize(machine) } -fn eval_calldatacopy(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::calldatacopy(state) +fn eval_calldatacopy(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::calldatacopy(machine) } -fn eval_pop(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::pop(state) +fn eval_pop(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::pop(machine) } -fn eval_mload(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::mload(state) +fn eval_mload(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::mload(machine) } -fn eval_mstore(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::mstore(state) +fn eval_mstore(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::mstore(machine) } -fn eval_mstore8(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::mstore8(state) +fn eval_mstore8(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::mstore8(machine) } -fn eval_jump(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::jump(state) +fn eval_jump(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::jump(machine) } -fn eval_jumpi(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::jumpi(state) +fn eval_jumpi(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::jumpi(machine) } -fn eval_pc(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::pc(state, position) +fn eval_pc(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::pc(machine, position) } -fn eval_msize(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::msize(state) +fn eval_msize(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::msize(machine) } -fn eval_jumpdest(_state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { +fn eval_jumpdest(_machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { Control::Continue(1) } -fn eval_push0(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 0, position) +fn eval_push0(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 0, position) } -fn eval_push1(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 1, position) +fn eval_push1(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 1, position) } -fn eval_push2(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 2, position) +fn eval_push2(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 2, position) } -fn eval_push3(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 3, position) +fn eval_push3(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 3, position) } -fn eval_push4(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 4, position) +fn eval_push4(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 4, position) } -fn eval_push5(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 5, position) +fn eval_push5(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 5, position) } -fn eval_push6(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 6, position) +fn eval_push6(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 6, position) } -fn eval_push7(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 7, position) +fn eval_push7(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 7, position) } -fn eval_push8(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 8, position) +fn eval_push8(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 8, position) } -fn eval_push9(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 9, position) +fn eval_push9(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 9, position) } -fn eval_push10(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 10, position) +fn eval_push10(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 10, position) } -fn eval_push11(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 11, position) +fn eval_push11(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 11, position) } -fn eval_push12(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 12, position) +fn eval_push12(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 12, position) } -fn eval_push13(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 13, position) +fn eval_push13(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 13, position) } -fn eval_push14(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 14, position) +fn eval_push14(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 14, position) } -fn eval_push15(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 15, position) +fn eval_push15(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 15, position) } -fn eval_push16(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 16, position) +fn eval_push16(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 16, position) } -fn eval_push17(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 17, position) +fn eval_push17(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 17, position) } -fn eval_push18(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 18, position) +fn eval_push18(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 18, position) } -fn eval_push19(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 19, position) +fn eval_push19(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 19, position) } -fn eval_push20(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 20, position) +fn eval_push20(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 20, position) } -fn eval_push21(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 21, position) +fn eval_push21(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 21, position) } -fn eval_push22(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 22, position) +fn eval_push22(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 22, position) } -fn eval_push23(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 23, position) +fn eval_push23(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 23, position) } -fn eval_push24(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 24, position) +fn eval_push24(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 24, position) } -fn eval_push25(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 25, position) +fn eval_push25(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 25, position) } -fn eval_push26(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 26, position) +fn eval_push26(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 26, position) } -fn eval_push27(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 27, position) +fn eval_push27(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 27, position) } -fn eval_push28(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 28, position) +fn eval_push28(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 28, position) } -fn eval_push29(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 29, position) +fn eval_push29(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 29, position) } -fn eval_push30(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 30, position) +fn eval_push30(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 30, position) } -fn eval_push31(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 31, position) +fn eval_push31(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 31, position) } -fn eval_push32(state: &mut Machine, _opcode: Opcode, position: usize) -> Control { - self::misc::push(state, 32, position) +fn eval_push32(machine: &mut Machine, _opcode: Opcode, position: usize) -> Control { + self::misc::push(machine, 32, position) } -fn eval_dup1(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 1) +fn eval_dup1(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 1) } -fn eval_dup2(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 2) +fn eval_dup2(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 2) } -fn eval_dup3(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 3) +fn eval_dup3(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 3) } -fn eval_dup4(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 4) +fn eval_dup4(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 4) } -fn eval_dup5(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 5) +fn eval_dup5(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 5) } -fn eval_dup6(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 6) +fn eval_dup6(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 6) } -fn eval_dup7(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 7) +fn eval_dup7(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 7) } -fn eval_dup8(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 8) +fn eval_dup8(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 8) } -fn eval_dup9(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 9) +fn eval_dup9(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 9) } -fn eval_dup10(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 10) +fn eval_dup10(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 10) } -fn eval_dup11(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 11) +fn eval_dup11(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 11) } -fn eval_dup12(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 12) +fn eval_dup12(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 12) } -fn eval_dup13(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 13) +fn eval_dup13(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 13) } -fn eval_dup14(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 14) +fn eval_dup14(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 14) } -fn eval_dup15(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 15) +fn eval_dup15(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 15) } -fn eval_dup16(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::dup(state, 16) +fn eval_dup16(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::dup(machine, 16) } -fn eval_swap1(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 1) +fn eval_swap1(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 1) } -fn eval_swap2(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 2) +fn eval_swap2(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 2) } -fn eval_swap3(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 3) +fn eval_swap3(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 3) } -fn eval_swap4(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 4) +fn eval_swap4(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 4) } -fn eval_swap5(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 5) +fn eval_swap5(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 5) } -fn eval_swap6(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 6) +fn eval_swap6(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 6) } -fn eval_swap7(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 7) +fn eval_swap7(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 7) } -fn eval_swap8(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 8) +fn eval_swap8(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 8) } -fn eval_swap9(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 9) +fn eval_swap9(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 9) } -fn eval_swap10(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 10) +fn eval_swap10(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 10) } -fn eval_swap11(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 11) +fn eval_swap11(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 11) } -fn eval_swap12(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 12) +fn eval_swap12(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 12) } -fn eval_swap13(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 13) +fn eval_swap13(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 13) } -fn eval_swap14(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 14) +fn eval_swap14(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 14) } -fn eval_swap15(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 15) +fn eval_swap15(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 15) } -fn eval_swap16(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::swap(state, 16) +fn eval_swap16(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::swap(machine, 16) } -fn eval_return(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::ret(state) +fn eval_return(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::ret(machine) } -fn eval_revert(state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { - self::misc::revert(state) +fn eval_revert(machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { + self::misc::revert(machine) } -fn eval_invalid(_state: &mut Machine, _opcode: Opcode, _position: usize) -> Control { +fn eval_invalid(_machine: &mut Machine, _opcode: Opcode, _position: usize) -> Control { Control::Exit(ExitError::DesignatedInvalid.into()) } -fn eval_external(_state: &mut Machine, opcode: Opcode, _position: usize) -> Control { +fn eval_external(_machine: &mut Machine, opcode: Opcode, _position: usize) -> Control { Control::Trap(opcode) } - -#[inline] -pub fn eval(state: &mut Machine, opcode: Opcode, position: usize) -> Control { - static TABLE: [fn(state: &mut Machine, opcode: Opcode, position: usize) -> Control; 256] = { - let mut table = [eval_external as _; 256]; - - table[Opcode::STOP.as_usize()] = eval_stop as _; - table[Opcode::ADD.as_usize()] = eval_add as _; - table[Opcode::MUL.as_usize()] = eval_mul as _; - table[Opcode::SUB.as_usize()] = eval_sub as _; - table[Opcode::DIV.as_usize()] = eval_div as _; - table[Opcode::SDIV.as_usize()] = eval_sdiv as _; - table[Opcode::MOD.as_usize()] = eval_mod as _; - table[Opcode::SMOD.as_usize()] = eval_smod as _; - table[Opcode::ADDMOD.as_usize()] = eval_addmod as _; - table[Opcode::MULMOD.as_usize()] = eval_mulmod as _; - table[Opcode::EXP.as_usize()] = eval_exp as _; - table[Opcode::SIGNEXTEND.as_usize()] = eval_signextend as _; - table[Opcode::LT.as_usize()] = eval_lt as _; - table[Opcode::GT.as_usize()] = eval_gt as _; - table[Opcode::SLT.as_usize()] = eval_slt as _; - table[Opcode::SGT.as_usize()] = eval_sgt as _; - table[Opcode::EQ.as_usize()] = eval_eq as _; - table[Opcode::ISZERO.as_usize()] = eval_iszero as _; - table[Opcode::AND.as_usize()] = eval_and as _; - table[Opcode::OR.as_usize()] = eval_or as _; - table[Opcode::XOR.as_usize()] = eval_xor as _; - table[Opcode::NOT.as_usize()] = eval_not as _; - table[Opcode::BYTE.as_usize()] = eval_byte as _; - table[Opcode::SHL.as_usize()] = eval_shl as _; - table[Opcode::SHR.as_usize()] = eval_shr as _; - table[Opcode::SAR.as_usize()] = eval_sar as _; - table[Opcode::CODESIZE.as_usize()] = eval_codesize as _; - table[Opcode::CODECOPY.as_usize()] = eval_codecopy as _; - table[Opcode::CALLDATALOAD.as_usize()] = eval_calldataload as _; - table[Opcode::CALLDATASIZE.as_usize()] = eval_calldatasize as _; - table[Opcode::CALLDATACOPY.as_usize()] = eval_calldatacopy as _; - table[Opcode::POP.as_usize()] = eval_pop as _; - table[Opcode::MLOAD.as_usize()] = eval_mload as _; - table[Opcode::MSTORE.as_usize()] = eval_mstore as _; - table[Opcode::MSTORE8.as_usize()] = eval_mstore8 as _; - table[Opcode::JUMP.as_usize()] = eval_jump as _; - table[Opcode::JUMPI.as_usize()] = eval_jumpi as _; - table[Opcode::PC.as_usize()] = eval_pc as _; - table[Opcode::MSIZE.as_usize()] = eval_msize as _; - table[Opcode::JUMPDEST.as_usize()] = eval_jumpdest as _; - - table[Opcode::PUSH0.as_usize()] = eval_push0 as _; - table[Opcode::PUSH1.as_usize()] = eval_push1 as _; - table[Opcode::PUSH2.as_usize()] = eval_push2 as _; - table[Opcode::PUSH3.as_usize()] = eval_push3 as _; - table[Opcode::PUSH4.as_usize()] = eval_push4 as _; - table[Opcode::PUSH5.as_usize()] = eval_push5 as _; - table[Opcode::PUSH6.as_usize()] = eval_push6 as _; - table[Opcode::PUSH7.as_usize()] = eval_push7 as _; - table[Opcode::PUSH8.as_usize()] = eval_push8 as _; - table[Opcode::PUSH9.as_usize()] = eval_push9 as _; - table[Opcode::PUSH10.as_usize()] = eval_push10 as _; - table[Opcode::PUSH11.as_usize()] = eval_push11 as _; - table[Opcode::PUSH12.as_usize()] = eval_push12 as _; - table[Opcode::PUSH13.as_usize()] = eval_push13 as _; - table[Opcode::PUSH14.as_usize()] = eval_push14 as _; - table[Opcode::PUSH15.as_usize()] = eval_push15 as _; - table[Opcode::PUSH16.as_usize()] = eval_push16 as _; - table[Opcode::PUSH17.as_usize()] = eval_push17 as _; - table[Opcode::PUSH18.as_usize()] = eval_push18 as _; - table[Opcode::PUSH19.as_usize()] = eval_push19 as _; - table[Opcode::PUSH20.as_usize()] = eval_push20 as _; - table[Opcode::PUSH21.as_usize()] = eval_push21 as _; - table[Opcode::PUSH22.as_usize()] = eval_push22 as _; - table[Opcode::PUSH23.as_usize()] = eval_push23 as _; - table[Opcode::PUSH24.as_usize()] = eval_push24 as _; - table[Opcode::PUSH25.as_usize()] = eval_push25 as _; - table[Opcode::PUSH26.as_usize()] = eval_push26 as _; - table[Opcode::PUSH27.as_usize()] = eval_push27 as _; - table[Opcode::PUSH28.as_usize()] = eval_push28 as _; - table[Opcode::PUSH29.as_usize()] = eval_push29 as _; - table[Opcode::PUSH30.as_usize()] = eval_push30 as _; - table[Opcode::PUSH31.as_usize()] = eval_push31 as _; - table[Opcode::PUSH32.as_usize()] = eval_push32 as _; - - table[Opcode::DUP1.as_usize()] = eval_dup1 as _; - table[Opcode::DUP2.as_usize()] = eval_dup2 as _; - table[Opcode::DUP3.as_usize()] = eval_dup3 as _; - table[Opcode::DUP4.as_usize()] = eval_dup4 as _; - table[Opcode::DUP5.as_usize()] = eval_dup5 as _; - table[Opcode::DUP6.as_usize()] = eval_dup6 as _; - table[Opcode::DUP7.as_usize()] = eval_dup7 as _; - table[Opcode::DUP8.as_usize()] = eval_dup8 as _; - table[Opcode::DUP9.as_usize()] = eval_dup9 as _; - table[Opcode::DUP10.as_usize()] = eval_dup10 as _; - table[Opcode::DUP11.as_usize()] = eval_dup11 as _; - table[Opcode::DUP12.as_usize()] = eval_dup12 as _; - table[Opcode::DUP13.as_usize()] = eval_dup13 as _; - table[Opcode::DUP14.as_usize()] = eval_dup14 as _; - table[Opcode::DUP15.as_usize()] = eval_dup15 as _; - table[Opcode::DUP16.as_usize()] = eval_dup16 as _; - - table[Opcode::SWAP1.as_usize()] = eval_swap1 as _; - table[Opcode::SWAP2.as_usize()] = eval_swap2 as _; - table[Opcode::SWAP3.as_usize()] = eval_swap3 as _; - table[Opcode::SWAP4.as_usize()] = eval_swap4 as _; - table[Opcode::SWAP5.as_usize()] = eval_swap5 as _; - table[Opcode::SWAP6.as_usize()] = eval_swap6 as _; - table[Opcode::SWAP7.as_usize()] = eval_swap7 as _; - table[Opcode::SWAP8.as_usize()] = eval_swap8 as _; - table[Opcode::SWAP9.as_usize()] = eval_swap9 as _; - table[Opcode::SWAP10.as_usize()] = eval_swap10 as _; - table[Opcode::SWAP11.as_usize()] = eval_swap11 as _; - table[Opcode::SWAP12.as_usize()] = eval_swap12 as _; - table[Opcode::SWAP13.as_usize()] = eval_swap13 as _; - table[Opcode::SWAP14.as_usize()] = eval_swap14 as _; - table[Opcode::SWAP15.as_usize()] = eval_swap15 as _; - table[Opcode::SWAP16.as_usize()] = eval_swap16 as _; - - table[Opcode::RETURN.as_usize()] = eval_return as _; - table[Opcode::REVERT.as_usize()] = eval_revert as _; - table[Opcode::INVALID.as_usize()] = eval_invalid as _; - - table - }; - - TABLE[opcode.as_usize()](state, opcode, position) -} diff --git a/core/src/lib.rs b/core/src/lib.rs index 53aafc364..d905d3f42 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -21,15 +21,31 @@ pub use crate::memory::Memory; pub use crate::opcode::Opcode; pub use crate::stack::Stack; pub use crate::valids::Valids; +pub use crate::eval::{Etable, Efn, Control}; -use crate::eval::{eval, Control}; use alloc::rc::Rc; use alloc::vec::Vec; use core::ops::Range; use primitive_types::U256; +pub trait State: 'static + Sized { + /// Etable of the state. + fn etable() -> &'static Etable; +} + +static CORE_ETABLE: Etable<()> = { + Etable::<()>::core() +}; + +impl State for () { + #[inline] + fn etable() -> &'static Etable { + &CORE_ETABLE + } +} + /// Core execution layer for EVM. -pub struct Machine { +pub struct Machine { /// Program data. data: Rc>, /// Program code. @@ -41,28 +57,14 @@ pub struct Machine { /// Code validity maps. valids: Valids, /// Memory. - memory: Memory, + pub memory: Memory, /// Stack. - stack: Stack, + pub stack: Stack, + /// Extra state, + pub state: S, } -impl Machine { - /// Reference of machine stack. - pub fn stack(&self) -> &Stack { - &self.stack - } - /// Mutable reference of machine stack. - pub fn stack_mut(&mut self) -> &mut Stack { - &mut self.stack - } - /// Reference of machine memory. - pub fn memory(&self) -> &Memory { - &self.memory - } - /// Mutable reference of machine memory. - pub fn memory_mut(&mut self) -> &mut Memory { - &mut self.memory - } +impl Machine { /// Return a reference of the program counter. pub fn position(&self) -> &Result { &self.position @@ -74,6 +76,7 @@ impl Machine { data: Rc>, stack_limit: usize, memory_limit: usize, + state: S, ) -> Self { let valids = Valids::new(&code[..]); @@ -85,6 +88,7 @@ impl Machine { valids, memory: Memory::new(memory_limit), stack: Stack::new(stack_limit), + state, } } @@ -147,7 +151,7 @@ impl Machine { .map_err(|reason| Capture::Exit(reason.clone()))?; match self.code.get(position).map(|v| Opcode(*v)) { - Some(opcode) => match eval(self, opcode, position) { + Some(opcode) => match S::etable()[opcode.as_usize()](self, opcode, position) { Control::Continue(p) => { self.position = Ok(position + p); Ok(()) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 294c8a2ca..1a15b5bce 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.68.2" +channel = "nightly" profile = "minimal" components = [ "rustfmt", "clippy" ]