From d26270d6841246c5a1333ad58558a4727f0c5656 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Jun 2018 14:43:24 +0800 Subject: [PATCH 01/10] Add a basic instruction c-like enum --- ethcore/evm/src/instructions.rs | 736 +++++++++++++++++++------------- 1 file changed, 448 insertions(+), 288 deletions(-) diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index 76f99a93338..20ba1d0ec32 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -16,7 +16,454 @@ //! VM Instructions list and utility functions -pub type Instruction = u8; +pub use self::Instruction::*; + +/// Virtual machine bytecode instruction. +#[repr(u8)] +#[derive(Eq, PartialEq, Debug)] +pub enum Instruction { + /// halts execution + STOP = 0x00, + /// addition operation + ADD = 0x01, + /// mulitplication operation + MUL = 0x02, + /// subtraction operation + SUB = 0x03, + /// integer division operation + DIV = 0x04, + /// signed integer division operation + SDIV = 0x05, + /// modulo remainder operation + MOD = 0x06, + /// signed modulo remainder operation + SMOD = 0x07, + /// unsigned modular addition + ADDMOD = 0x08, + /// unsigned modular multiplication + MULMOD = 0x09, + /// exponential operation + EXP = 0x0a, + /// extend length of signed integer + SIGNEXTEND = 0x0b, + + /// less-than comparision + LT = 0x10, + /// greater-than comparision + GT = 0x11, + /// signed less-than comparision + SLT = 0x12, + /// signed greater-than comparision + SGT = 0x13, + /// equality comparision + EQ = 0x14, + /// simple not operator + ISZERO = 0x15, + /// bitwise AND operation + AND = 0x16, + /// bitwise OR operation + OR = 0x17, + /// bitwise XOR operation + XOR = 0x18, + /// bitwise NOT opertation + NOT = 0x19, + /// retrieve single byte from word + BYTE = 0x1a, + /// shift left operation + SHL = 0x1b, + /// logical shift right operation + SHR = 0x1c, + /// arithmetic shift right operation + SAR = 0x1d, + + /// compute SHA3-256 hash + SHA3 = 0x20, + + /// get address of currently executing account + ADDRESS = 0x30, + /// get balance of the given account + BALANCE = 0x31, + /// get execution origination address + ORIGIN = 0x32, + /// get caller address + CALLER = 0x33, + /// get deposited value by the instruction/transaction responsible for this execution + CALLVALUE = 0x34, + /// get input data of current environment + CALLDATALOAD = 0x35, + /// get size of input data in current environment + CALLDATASIZE = 0x36, + /// copy input data in current environment to memory + CALLDATACOPY = 0x37, + /// get size of code running in current environment + CODESIZE = 0x38, + /// copy code running in current environment to memory + CODECOPY = 0x39, + /// get price of gas in current environment + GASPRICE = 0x3a, + /// get external code size (from another contract) + EXTCODESIZE = 0x3b, + /// copy external code (from another contract) + EXTCODECOPY = 0x3c, + /// get the size of the return data buffer for the last call + RETURNDATASIZE = 0x3d, + /// copy return data buffer to memory + RETURNDATACOPY = 0x3e, + + /// get hash of most recent complete block + BLOCKHASH = 0x40, + /// get the block's coinbase address + COINBASE = 0x41, + /// get the block's timestamp + TIMESTAMP = 0x42, + /// get the block's number + NUMBER = 0x43, + /// get the block's difficulty + DIFFICULTY = 0x44, + /// get the block's gas limit + GASLIMIT = 0x45, + + /// remove item from stack + POP = 0x50, + /// load word from memory + MLOAD = 0x51, + /// save word to memory + MSTORE = 0x52, + /// save byte to memory + MSTORE8 = 0x53, + /// load word from storage + SLOAD = 0x54, + /// save word to storage + SSTORE = 0x55, + /// alter the program counter + JUMP = 0x56, + /// conditionally alter the program counter + JUMPI = 0x57, + /// get the program counter + PC = 0x58, + /// get the size of active memory + MSIZE = 0x59, + /// get the amount of available gas + GAS = 0x5a, + /// set a potential jump destination + JUMPDEST = 0x5b, + + /// place 1 byte item on stack + PUSH1 = 0x60, + /// place 2 byte item on stack + PUSH2 = 0x61, + /// place 3 byte item on stack + PUSH3 = 0x62, + /// place 4 byte item on stack + PUSH4 = 0x63, + /// place 5 byte item on stack + PUSH5 = 0x64, + /// place 6 byte item on stack + PUSH6 = 0x65, + /// place 7 byte item on stack + PUSH7 = 0x66, + /// place 8 byte item on stack + PUSH8 = 0x67, + /// place 9 byte item on stack + PUSH9 = 0x68, + /// place 10 byte item on stack + PUSH10 = 0x69, + /// place 11 byte item on stack + PUSH11 = 0x6a, + /// place 12 byte item on stack + PUSH12 = 0x6b, + /// place 13 byte item on stack + PUSH13 = 0x6c, + /// place 14 byte item on stack + PUSH14 = 0x6d, + /// place 15 byte item on stack + PUSH15 = 0x6e, + /// place 16 byte item on stack + PUSH16 = 0x6f, + /// place 17 byte item on stack + PUSH17 = 0x70, + /// place 18 byte item on stack + PUSH18 = 0x71, + /// place 19 byte item on stack + PUSH19 = 0x72, + /// place 20 byte item on stack + PUSH20 = 0x73, + /// place 21 byte item on stack + PUSH21 = 0x74, + /// place 22 byte item on stack + PUSH22 = 0x75, + /// place 23 byte item on stack + PUSH23 = 0x76, + /// place 24 byte item on stack + PUSH24 = 0x77, + /// place 25 byte item on stack + PUSH25 = 0x78, + /// place 26 byte item on stack + PUSH26 = 0x79, + /// place 27 byte item on stack + PUSH27 = 0x7a, + /// place 28 byte item on stack + PUSH28 = 0x7b, + /// place 29 byte item on stack + PUSH29 = 0x7c, + /// place 30 byte item on stack + PUSH30 = 0x7d, + /// place 31 byte item on stack + PUSH31 = 0x7e, + /// place 32 byte item on stack + PUSH32 = 0x7f, + + /// copies the highest item in the stack to the top of the stack + DUP1 = 0x80, + /// copies the second highest item in the stack to the top of the stack + DUP2 = 0x81, + /// copies the third highest item in the stack to the top of the stack + DUP3 = 0x82, + /// copies the 4th highest item in the stack to the top of the stack + DUP4 = 0x83, + /// copies the 5th highest item in the stack to the top of the stack + DUP5 = 0x84, + /// copies the 6th highest item in the stack to the top of the stack + DUP6 = 0x85, + /// copies the 7th highest item in the stack to the top of the stack + DUP7 = 0x86, + /// copies the 8th highest item in the stack to the top of the stack + DUP8 = 0x87, + /// copies the 9th highest item in the stack to the top of the stack + DUP9 = 0x88, + /// copies the 10th highest item in the stack to the top of the stack + DUP10 = 0x89, + /// copies the 11th highest item in the stack to the top of the stack + DUP11 = 0x8a, + /// copies the 12th highest item in the stack to the top of the stack + DUP12 = 0x8b, + /// copies the 13th highest item in the stack to the top of the stack + DUP13 = 0x8c, + /// copies the 14th highest item in the stack to the top of the stack + DUP14 = 0x8d, + /// copies the 15th highest item in the stack to the top of the stack + DUP15 = 0x8e, + /// copies the 16th highest item in the stack to the top of the stack + DUP16 = 0x8f, + + /// swaps the highest and second highest value on the stack + SWAP1 = 0x90, + /// swaps the highest and third highest value on the stack + SWAP2 = 0x91, + /// swaps the highest and 4th highest value on the stack + SWAP3 = 0x92, + /// swaps the highest and 5th highest value on the stack + SWAP4 = 0x93, + /// swaps the highest and 6th highest value on the stack + SWAP5 = 0x94, + /// swaps the highest and 7th highest value on the stack + SWAP6 = 0x95, + /// swaps the highest and 8th highest value on the stack + SWAP7 = 0x96, + /// swaps the highest and 9th highest value on the stack + SWAP8 = 0x97, + /// swaps the highest and 10th highest value on the stack + SWAP9 = 0x98, + /// swaps the highest and 11th highest value on the stack + SWAP10 = 0x99, + /// swaps the highest and 12th highest value on the stack + SWAP11 = 0x9a, + /// swaps the highest and 13th highest value on the stack + SWAP12 = 0x9b, + /// swaps the highest and 14th highest value on the stack + SWAP13 = 0x9c, + /// swaps the highest and 15th highest value on the stack + SWAP14 = 0x9d, + /// swaps the highest and 16th highest value on the stack + SWAP15 = 0x9e, + /// swaps the highest and 17th highest value on the stack + SWAP16 = 0x9f, + + /// Makes a log entry, no topics. + LOG0 = 0xa0, + /// Makes a log entry, 1 topic. + LOG1 = 0xa1, + /// Makes a log entry, 2 topics. + LOG2 = 0xa2, + /// Makes a log entry, 3 topics. + LOG3 = 0xa3, + /// Makes a log entry, 4 topics. + LOG4 = 0xa4, + + /// create a new account with associated code + CREATE = 0xf0, + /// message-call into an account + CALL = 0xf1, + /// message-call with another account's code only + CALLCODE = 0xf2, + /// halt execution returning output data + RETURN = 0xf3, + /// like CALLCODE but keeps caller's value and sender + DELEGATECALL = 0xf4, + /// create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160 + CREATE2 = 0xfb, + /// stop execution and revert state changes. Return output data. + REVERT = 0xfd, + /// like CALL but it does not take value, nor modify the state + STATICCALL = 0xfa, + /// halt execution and register account for later deletion + SUICIDE = 0xff, +} + +impl Instruction { + pub fn from_u8(value: u8) -> Option { + match value { + 0x00 => Instruction::STOP, + 0x01 => Instruction::ADD, + 0x02 => Instruction::MUL, + 0x03 => Instruction::SUB, + 0x04 => Instruction::DIV, + 0x05 => Instruction::SDIV, + 0x06 => Instruction::MOD, + 0x07 => Instruction::SMOD, + 0x08 => Instruction::ADDMOD, + 0x09 => Instruction::MULMOD, + 0x0a => Instruction::EXP, + 0x0b => Instruction::SIGNEXTEND, + + 0x10 => Instruction::LT, + 0x11 => Instruction::GT, + 0x12 => Instruction::SLT, + 0x13 => Instruction::SGT, + 0x14 => Instruction::EQ, + 0x15 => Instruction::ISZERO, + 0x16 => Instruction::AND, + 0x17 => Instruction::OR, + 0x18 => Instruction::XOR, + 0x19 => Instruction::NOT, + 0x1a => Instruction::BYTE, + 0x1b => Instruction::SHL, + 0x1c => Instruction::SHR, + 0x1d => Instruction::SAR, + + 0x20 => Instruction::SHA3, + + 0x30 => Instruction::ADDRESS, + 0x31 => Instruction::BALANCE, + 0x32 => Instruction::ORIGIN, + 0x33 => Instruction::CALLER, + 0x34 => Instruction::CALLVALUE, + 0x35 => Instruction::CALLDATALOAD, + 0x36 => Instruction::CALLDATASIZE, + 0x37 => Instruction::CALLDATACOPY, + 0x38 => Instruction::CODESIZE, + 0x39 => Instruction::CODECOPY, + 0x3a => Instruction::GASPRICE, + 0x3b => Instruction::EXTCODESIZE, + 0x3c => Instruction::EXTCODECOPY, + 0x3d => Instruction::RETURNDATASIZE, + 0x3e => Instruction::RETURNDATACOPY, + + 0x40 => Instruction::BLOCKHASH, + 0x41 => Instruction::COINBASE, + 0x42 => Instruction::TIMESTAMP, + 0x43 => Instruction::NUMBER, + 0x44 => Instruction::DIFFICULTY, + 0x45 => Instruction::GASLIMIT, + + 0x50 => Instruction::POP, + 0x51 => Instruction::MLOAD, + 0x52 => Instruction::MSTORE, + 0x53 => Instruction::MSTORE8, + 0x54 => Instruction::SLOAD, + 0x55 => Instruction::SSTORE, + 0x56 => Instruction::JUMP, + 0x57 => Instruction::JUMPI, + 0x58 => Instruction::PC, + 0x59 => Instruction::MSIZE, + 0x5a => Instruction::GAS, + 0x5b => Instruction::JUMPDEST, + + 0x60 => Instruction::PUSH1, + 0x61 => Instruction::PUSH2, + 0x62 => Instruction::PUSH3, + 0x63 => Instruction::PUSH4, + 0x64 => Instruction::PUSH5, + 0x65 => Instruction::PUSH6, + 0x66 => Instruction::PUSH7, + 0x67 => Instruction::PUSH8, + 0x68 => Instruction::PUSH9, + 0x69 => Instruction::PUSH10, + 0x6a => Instruction::PUSH11, + 0x6b => Instruction::PUSH12, + 0x6c => Instruction::PUSH13, + 0x6d => Instruction::PUSH14, + 0x6e => Instruction::PUSH15, + 0x6f => Instruction::PUSH16, + 0x70 => Instruction::PUSH17, + 0x71 => Instruction::PUSH18, + 0x72 => Instruction::PUSH19, + 0x73 => Instruction::PUSH20, + 0x74 => Instruction::PUSH21, + 0x75 => Instruction::PUSH22, + 0x76 => Instruction::PUSH23, + 0x77 => Instruction::PUSH24, + 0x78 => Instruction::PUSH25, + 0x79 => Instruction::PUSH26, + 0x7a => Instruction::PUSH27, + 0x7b => Instruction::PUSH28, + 0x7c => Instruction::PUSH29, + 0x7d => Instruction::PUSH30, + 0x7e => Instruction::PUSH31, + 0x7f => Instruction::PUSH32, + + 0x80 => Instruction::DUP1, + 0x81 => Instruction::DUP2, + 0x82 => Instruction::DUP3, + 0x83 => Instruction::DUP4, + 0x84 => Instruction::DUP5, + 0x85 => Instruction::DUP6, + 0x86 => Instruction::DUP7, + 0x87 => Instruction::DUP8, + 0x88 => Instruction::DUP9, + 0x89 => Instruction::DUP10, + 0x8a => Instruction::DUP11, + 0x8b => Instruction::DUP12, + 0x8c => Instruction::DUP13, + 0x8d => Instruction::DUP14, + 0x8e => Instruction::DUP15, + 0x8f => Instruction::DUP16, + + 0x90 => Instruction::SWAP1, + 0x91 => Instruction::SWAP2, + 0x92 => Instruction::SWAP3, + 0x93 => Instruction::SWAP4, + 0x94 => Instruction::SWAP5, + 0x95 => Instruction::SWAP6, + 0x96 => Instruction::SWAP7, + 0x97 => Instruction::SWAP8, + 0x98 => Instruction::SWAP9, + 0x99 => Instruction::SWAP10, + 0x9a => Instruction::SWAP11, + 0x9b => Instruction::SWAP12, + 0x9c => Instruction::SWAP13, + 0x9d => Instruction::SWAP14, + 0x9e => Instruction::SWAP15, + 0x9f => Instruction::SWAP16, + + 0xa0 => Instruction::LOG0, + 0xa1 => Instruction::LOG1, + 0xa2 => Instruction::LOG2, + 0xa3 => Instruction::LOG3, + 0xa4 => Instruction::LOG4, + + 0xf0 => Instruction::CREATE, + 0xf1 => Instruction::CALL, + 0xf2 => Instruction::CALLCODE, + 0xf3 => Instruction::RETURN, + 0xf4 => Instruction::DELEGATECALL, + 0xfb => Instruction::CREATE2, + 0xfd => Instruction::REVERT, + 0xfa => Instruction::STATICCALL, + 0xff => Instruction::SUICIDE, + } + } +} /// Returns true if given instruction is `PUSHN` instruction. pub fn is_push(i: Instruction) -> bool { @@ -309,292 +756,5 @@ lazy_static! { }; } -/// Virtual machine bytecode instruction. -/// halts execution -pub const STOP: Instruction = 0x00; -/// addition operation -pub const ADD: Instruction = 0x01; -/// mulitplication operation -pub const MUL: Instruction = 0x02; -/// subtraction operation -pub const SUB: Instruction = 0x03; -/// integer division operation -pub const DIV: Instruction = 0x04; -/// signed integer division operation -pub const SDIV: Instruction = 0x05; -/// modulo remainder operation -pub const MOD: Instruction = 0x06; -/// signed modulo remainder operation -pub const SMOD: Instruction = 0x07; -/// unsigned modular addition -pub const ADDMOD: Instruction = 0x08; -/// unsigned modular multiplication -pub const MULMOD: Instruction = 0x09; -/// exponential operation -pub const EXP: Instruction = 0x0a; -/// extend length of signed integer -pub const SIGNEXTEND: Instruction = 0x0b; - -/// less-than comparision -pub const LT: Instruction = 0x10; -/// greater-than comparision -pub const GT: Instruction = 0x11; -/// signed less-than comparision -pub const SLT: Instruction = 0x12; -/// signed greater-than comparision -pub const SGT: Instruction = 0x13; -/// equality comparision -pub const EQ: Instruction = 0x14; -/// simple not operator -pub const ISZERO: Instruction = 0x15; -/// bitwise AND operation -pub const AND: Instruction = 0x16; -/// bitwise OR operation -pub const OR: Instruction = 0x17; -/// bitwise XOR operation -pub const XOR: Instruction = 0x18; -/// bitwise NOT opertation -pub const NOT: Instruction = 0x19; -/// retrieve single byte from word -pub const BYTE: Instruction = 0x1a; -/// shift left operation -pub const SHL: Instruction = 0x1b; -/// logical shift right operation -pub const SHR: Instruction = 0x1c; -/// arithmetic shift right operation -pub const SAR: Instruction = 0x1d; - -/// compute SHA3-256 hash -pub const SHA3: Instruction = 0x20; - -/// get address of currently executing account -pub const ADDRESS: Instruction = 0x30; -/// get balance of the given account -pub const BALANCE: Instruction = 0x31; -/// get execution origination address -pub const ORIGIN: Instruction = 0x32; -/// get caller address -pub const CALLER: Instruction = 0x33; -/// get deposited value by the instruction/transaction responsible for this execution -pub const CALLVALUE: Instruction = 0x34; -/// get input data of current environment -pub const CALLDATALOAD: Instruction = 0x35; -/// get size of input data in current environment -pub const CALLDATASIZE: Instruction = 0x36; -/// copy input data in current environment to memory -pub const CALLDATACOPY: Instruction = 0x37; -/// get size of code running in current environment -pub const CODESIZE: Instruction = 0x38; -/// copy code running in current environment to memory -pub const CODECOPY: Instruction = 0x39; -/// get price of gas in current environment -pub const GASPRICE: Instruction = 0x3a; -/// get external code size (from another contract) -pub const EXTCODESIZE: Instruction = 0x3b; -/// copy external code (from another contract) -pub const EXTCODECOPY: Instruction = 0x3c; -/// get the size of the return data buffer for the last call -pub const RETURNDATASIZE: Instruction = 0x3d; -/// copy return data buffer to memory -pub const RETURNDATACOPY: Instruction = 0x3e; - -/// get hash of most recent complete block -pub const BLOCKHASH: Instruction = 0x40; -/// get the block's coinbase address -pub const COINBASE: Instruction = 0x41; -/// get the block's timestamp -pub const TIMESTAMP: Instruction = 0x42; -/// get the block's number -pub const NUMBER: Instruction = 0x43; -/// get the block's difficulty -pub const DIFFICULTY: Instruction = 0x44; -/// get the block's gas limit -pub const GASLIMIT: Instruction = 0x45; - -/// remove item from stack -pub const POP: Instruction = 0x50; -/// load word from memory -pub const MLOAD: Instruction = 0x51; -/// save word to memory -pub const MSTORE: Instruction = 0x52; -/// save byte to memory -pub const MSTORE8: Instruction = 0x53; -/// load word from storage -pub const SLOAD: Instruction = 0x54; -/// save word to storage -pub const SSTORE: Instruction = 0x55; -/// alter the program counter -pub const JUMP: Instruction = 0x56; -/// conditionally alter the program counter -pub const JUMPI: Instruction = 0x57; -/// get the program counter -pub const PC: Instruction = 0x58; -/// get the size of active memory -pub const MSIZE: Instruction = 0x59; -/// get the amount of available gas -pub const GAS: Instruction = 0x5a; -/// set a potential jump destination -pub const JUMPDEST: Instruction = 0x5b; - -/// place 1 byte item on stack -pub const PUSH1: Instruction = 0x60; -/// place 2 byte item on stack -pub const PUSH2: Instruction = 0x61; -/// place 3 byte item on stack -pub const PUSH3: Instruction = 0x62; -/// place 4 byte item on stack -pub const PUSH4: Instruction = 0x63; -/// place 5 byte item on stack -pub const PUSH5: Instruction = 0x64; -/// place 6 byte item on stack -pub const PUSH6: Instruction = 0x65; -/// place 7 byte item on stack -pub const PUSH7: Instruction = 0x66; -/// place 8 byte item on stack -pub const PUSH8: Instruction = 0x67; -/// place 9 byte item on stack -pub const PUSH9: Instruction = 0x68; -/// place 10 byte item on stack -pub const PUSH10: Instruction = 0x69; -/// place 11 byte item on stack -pub const PUSH11: Instruction = 0x6a; -/// place 12 byte item on stack -pub const PUSH12: Instruction = 0x6b; -/// place 13 byte item on stack -pub const PUSH13: Instruction = 0x6c; -/// place 14 byte item on stack -pub const PUSH14: Instruction = 0x6d; -/// place 15 byte item on stack -pub const PUSH15: Instruction = 0x6e; -/// place 16 byte item on stack -pub const PUSH16: Instruction = 0x6f; -/// place 17 byte item on stack -pub const PUSH17: Instruction = 0x70; -/// place 18 byte item on stack -pub const PUSH18: Instruction = 0x71; -/// place 19 byte item on stack -pub const PUSH19: Instruction = 0x72; -/// place 20 byte item on stack -pub const PUSH20: Instruction = 0x73; -/// place 21 byte item on stack -pub const PUSH21: Instruction = 0x74; -/// place 22 byte item on stack -pub const PUSH22: Instruction = 0x75; -/// place 23 byte item on stack -pub const PUSH23: Instruction = 0x76; -/// place 24 byte item on stack -pub const PUSH24: Instruction = 0x77; -/// place 25 byte item on stack -pub const PUSH25: Instruction = 0x78; -/// place 26 byte item on stack -pub const PUSH26: Instruction = 0x79; -/// place 27 byte item on stack -pub const PUSH27: Instruction = 0x7a; -/// place 28 byte item on stack -pub const PUSH28: Instruction = 0x7b; -/// place 29 byte item on stack -pub const PUSH29: Instruction = 0x7c; -/// place 30 byte item on stack -pub const PUSH30: Instruction = 0x7d; -/// place 31 byte item on stack -pub const PUSH31: Instruction = 0x7e; -/// place 32 byte item on stack -pub const PUSH32: Instruction = 0x7f; - -/// copies the highest item in the stack to the top of the stack -pub const DUP1: Instruction = 0x80; -/// copies the second highest item in the stack to the top of the stack -pub const DUP2: Instruction = 0x81; -/// copies the third highest item in the stack to the top of the stack -pub const DUP3: Instruction = 0x82; -/// copies the 4th highest item in the stack to the top of the stack -pub const DUP4: Instruction = 0x83; -/// copies the 5th highest item in the stack to the top of the stack -pub const DUP5: Instruction = 0x84; -/// copies the 6th highest item in the stack to the top of the stack -pub const DUP6: Instruction = 0x85; -/// copies the 7th highest item in the stack to the top of the stack -pub const DUP7: Instruction = 0x86; -/// copies the 8th highest item in the stack to the top of the stack -pub const DUP8: Instruction = 0x87; -/// copies the 9th highest item in the stack to the top of the stack -pub const DUP9: Instruction = 0x88; -/// copies the 10th highest item in the stack to the top of the stack -pub const DUP10: Instruction = 0x89; -/// copies the 11th highest item in the stack to the top of the stack -pub const DUP11: Instruction = 0x8a; -/// copies the 12th highest item in the stack to the top of the stack -pub const DUP12: Instruction = 0x8b; -/// copies the 13th highest item in the stack to the top of the stack -pub const DUP13: Instruction = 0x8c; -/// copies the 14th highest item in the stack to the top of the stack -pub const DUP14: Instruction = 0x8d; -/// copies the 15th highest item in the stack to the top of the stack -pub const DUP15: Instruction = 0x8e; -/// copies the 16th highest item in the stack to the top of the stack -pub const DUP16: Instruction = 0x8f; - -/// swaps the highest and second highest value on the stack -pub const SWAP1: Instruction = 0x90; -/// swaps the highest and third highest value on the stack -pub const SWAP2: Instruction = 0x91; -/// swaps the highest and 4th highest value on the stack -pub const SWAP3: Instruction = 0x92; -/// swaps the highest and 5th highest value on the stack -pub const SWAP4: Instruction = 0x93; -/// swaps the highest and 6th highest value on the stack -pub const SWAP5: Instruction = 0x94; -/// swaps the highest and 7th highest value on the stack -pub const SWAP6: Instruction = 0x95; -/// swaps the highest and 8th highest value on the stack -pub const SWAP7: Instruction = 0x96; -/// swaps the highest and 9th highest value on the stack -pub const SWAP8: Instruction = 0x97; -/// swaps the highest and 10th highest value on the stack -pub const SWAP9: Instruction = 0x98; -/// swaps the highest and 11th highest value on the stack -pub const SWAP10: Instruction = 0x99; -/// swaps the highest and 12th highest value on the stack -pub const SWAP11: Instruction = 0x9a; -/// swaps the highest and 13th highest value on the stack -pub const SWAP12: Instruction = 0x9b; -/// swaps the highest and 14th highest value on the stack -pub const SWAP13: Instruction = 0x9c; -/// swaps the highest and 15th highest value on the stack -pub const SWAP14: Instruction = 0x9d; -/// swaps the highest and 16th highest value on the stack -pub const SWAP15: Instruction = 0x9e; -/// swaps the highest and 17th highest value on the stack -pub const SWAP16: Instruction = 0x9f; - -/// Makes a log entry; no topics. -pub const LOG0: Instruction = 0xa0; -/// Makes a log entry; 1 topic. -pub const LOG1: Instruction = 0xa1; -/// Makes a log entry; 2 topics. -pub const LOG2: Instruction = 0xa2; -/// Makes a log entry; 3 topics. -pub const LOG3: Instruction = 0xa3; -/// Makes a log entry; 4 topics. -pub const LOG4: Instruction = 0xa4; /// Maximal number of topics for log instructions pub const MAX_NO_OF_TOPICS : usize = 4; - -/// create a new account with associated code -pub const CREATE: Instruction = 0xf0; -/// message-call into an account -pub const CALL: Instruction = 0xf1; -/// message-call with another account's code only -pub const CALLCODE: Instruction = 0xf2; -/// halt execution returning output data -pub const RETURN: Instruction = 0xf3; -/// like CALLCODE but keeps caller's value and sender -pub const DELEGATECALL: Instruction = 0xf4; -/// create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160 -pub const CREATE2: Instruction = 0xfb; -/// stop execution and revert state changes. Return output data. -pub const REVERT: Instruction = 0xfd; -/// like CALL but it does not take value, nor modify the state -pub const STATICCALL: Instruction = 0xfa; -/// halt execution and register account for later deletion -pub const SUICIDE: Instruction = 0xff; From 319455d80101cc6f6b263a96d0ea640aa49a2d2c Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Jun 2018 15:25:26 +0800 Subject: [PATCH 02/10] Fix all compiling errors --- ethcore/evm/src/instructions.rs | 419 ++++++++++---------- ethcore/evm/src/interpreter/gasometer.rs | 6 +- ethcore/evm/src/interpreter/mod.rs | 169 ++++---- ethcore/evm/src/interpreter/shared_cache.rs | 16 +- ethcore/evm/src/lib.rs | 2 +- 5 files changed, 314 insertions(+), 298 deletions(-) diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index 20ba1d0ec32..01e80b3f6cc 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -20,7 +20,7 @@ pub use self::Instruction::*; /// Virtual machine bytecode instruction. #[repr(u8)] -#[derive(Eq, PartialEq, Debug)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug)] pub enum Instruction { /// halts execution STOP = 0x00, @@ -313,161 +313,205 @@ pub enum Instruction { impl Instruction { pub fn from_u8(value: u8) -> Option { match value { - 0x00 => Instruction::STOP, - 0x01 => Instruction::ADD, - 0x02 => Instruction::MUL, - 0x03 => Instruction::SUB, - 0x04 => Instruction::DIV, - 0x05 => Instruction::SDIV, - 0x06 => Instruction::MOD, - 0x07 => Instruction::SMOD, - 0x08 => Instruction::ADDMOD, - 0x09 => Instruction::MULMOD, - 0x0a => Instruction::EXP, - 0x0b => Instruction::SIGNEXTEND, - - 0x10 => Instruction::LT, - 0x11 => Instruction::GT, - 0x12 => Instruction::SLT, - 0x13 => Instruction::SGT, - 0x14 => Instruction::EQ, - 0x15 => Instruction::ISZERO, - 0x16 => Instruction::AND, - 0x17 => Instruction::OR, - 0x18 => Instruction::XOR, - 0x19 => Instruction::NOT, - 0x1a => Instruction::BYTE, - 0x1b => Instruction::SHL, - 0x1c => Instruction::SHR, - 0x1d => Instruction::SAR, - - 0x20 => Instruction::SHA3, - - 0x30 => Instruction::ADDRESS, - 0x31 => Instruction::BALANCE, - 0x32 => Instruction::ORIGIN, - 0x33 => Instruction::CALLER, - 0x34 => Instruction::CALLVALUE, - 0x35 => Instruction::CALLDATALOAD, - 0x36 => Instruction::CALLDATASIZE, - 0x37 => Instruction::CALLDATACOPY, - 0x38 => Instruction::CODESIZE, - 0x39 => Instruction::CODECOPY, - 0x3a => Instruction::GASPRICE, - 0x3b => Instruction::EXTCODESIZE, - 0x3c => Instruction::EXTCODECOPY, - 0x3d => Instruction::RETURNDATASIZE, - 0x3e => Instruction::RETURNDATACOPY, - - 0x40 => Instruction::BLOCKHASH, - 0x41 => Instruction::COINBASE, - 0x42 => Instruction::TIMESTAMP, - 0x43 => Instruction::NUMBER, - 0x44 => Instruction::DIFFICULTY, - 0x45 => Instruction::GASLIMIT, - - 0x50 => Instruction::POP, - 0x51 => Instruction::MLOAD, - 0x52 => Instruction::MSTORE, - 0x53 => Instruction::MSTORE8, - 0x54 => Instruction::SLOAD, - 0x55 => Instruction::SSTORE, - 0x56 => Instruction::JUMP, - 0x57 => Instruction::JUMPI, - 0x58 => Instruction::PC, - 0x59 => Instruction::MSIZE, - 0x5a => Instruction::GAS, - 0x5b => Instruction::JUMPDEST, - - 0x60 => Instruction::PUSH1, - 0x61 => Instruction::PUSH2, - 0x62 => Instruction::PUSH3, - 0x63 => Instruction::PUSH4, - 0x64 => Instruction::PUSH5, - 0x65 => Instruction::PUSH6, - 0x66 => Instruction::PUSH7, - 0x67 => Instruction::PUSH8, - 0x68 => Instruction::PUSH9, - 0x69 => Instruction::PUSH10, - 0x6a => Instruction::PUSH11, - 0x6b => Instruction::PUSH12, - 0x6c => Instruction::PUSH13, - 0x6d => Instruction::PUSH14, - 0x6e => Instruction::PUSH15, - 0x6f => Instruction::PUSH16, - 0x70 => Instruction::PUSH17, - 0x71 => Instruction::PUSH18, - 0x72 => Instruction::PUSH19, - 0x73 => Instruction::PUSH20, - 0x74 => Instruction::PUSH21, - 0x75 => Instruction::PUSH22, - 0x76 => Instruction::PUSH23, - 0x77 => Instruction::PUSH24, - 0x78 => Instruction::PUSH25, - 0x79 => Instruction::PUSH26, - 0x7a => Instruction::PUSH27, - 0x7b => Instruction::PUSH28, - 0x7c => Instruction::PUSH29, - 0x7d => Instruction::PUSH30, - 0x7e => Instruction::PUSH31, - 0x7f => Instruction::PUSH32, - - 0x80 => Instruction::DUP1, - 0x81 => Instruction::DUP2, - 0x82 => Instruction::DUP3, - 0x83 => Instruction::DUP4, - 0x84 => Instruction::DUP5, - 0x85 => Instruction::DUP6, - 0x86 => Instruction::DUP7, - 0x87 => Instruction::DUP8, - 0x88 => Instruction::DUP9, - 0x89 => Instruction::DUP10, - 0x8a => Instruction::DUP11, - 0x8b => Instruction::DUP12, - 0x8c => Instruction::DUP13, - 0x8d => Instruction::DUP14, - 0x8e => Instruction::DUP15, - 0x8f => Instruction::DUP16, - - 0x90 => Instruction::SWAP1, - 0x91 => Instruction::SWAP2, - 0x92 => Instruction::SWAP3, - 0x93 => Instruction::SWAP4, - 0x94 => Instruction::SWAP5, - 0x95 => Instruction::SWAP6, - 0x96 => Instruction::SWAP7, - 0x97 => Instruction::SWAP8, - 0x98 => Instruction::SWAP9, - 0x99 => Instruction::SWAP10, - 0x9a => Instruction::SWAP11, - 0x9b => Instruction::SWAP12, - 0x9c => Instruction::SWAP13, - 0x9d => Instruction::SWAP14, - 0x9e => Instruction::SWAP15, - 0x9f => Instruction::SWAP16, - - 0xa0 => Instruction::LOG0, - 0xa1 => Instruction::LOG1, - 0xa2 => Instruction::LOG2, - 0xa3 => Instruction::LOG3, - 0xa4 => Instruction::LOG4, - - 0xf0 => Instruction::CREATE, - 0xf1 => Instruction::CALL, - 0xf2 => Instruction::CALLCODE, - 0xf3 => Instruction::RETURN, - 0xf4 => Instruction::DELEGATECALL, - 0xfb => Instruction::CREATE2, - 0xfd => Instruction::REVERT, - 0xfa => Instruction::STATICCALL, - 0xff => Instruction::SUICIDE, + 0x00 => Some(Instruction::STOP), + 0x01 => Some(Instruction::ADD), + 0x02 => Some(Instruction::MUL), + 0x03 => Some(Instruction::SUB), + 0x04 => Some(Instruction::DIV), + 0x05 => Some(Instruction::SDIV), + 0x06 => Some(Instruction::MOD), + 0x07 => Some(Instruction::SMOD), + 0x08 => Some(Instruction::ADDMOD), + 0x09 => Some(Instruction::MULMOD), + 0x0a => Some(Instruction::EXP), + 0x0b => Some(Instruction::SIGNEXTEND), + + 0x10 => Some(Instruction::LT), + 0x11 => Some(Instruction::GT), + 0x12 => Some(Instruction::SLT), + 0x13 => Some(Instruction::SGT), + 0x14 => Some(Instruction::EQ), + 0x15 => Some(Instruction::ISZERO), + 0x16 => Some(Instruction::AND), + 0x17 => Some(Instruction::OR), + 0x18 => Some(Instruction::XOR), + 0x19 => Some(Instruction::NOT), + 0x1a => Some(Instruction::BYTE), + 0x1b => Some(Instruction::SHL), + 0x1c => Some(Instruction::SHR), + 0x1d => Some(Instruction::SAR), + + 0x20 => Some(Instruction::SHA3), + + 0x30 => Some(Instruction::ADDRESS), + 0x31 => Some(Instruction::BALANCE), + 0x32 => Some(Instruction::ORIGIN), + 0x33 => Some(Instruction::CALLER), + 0x34 => Some(Instruction::CALLVALUE), + 0x35 => Some(Instruction::CALLDATALOAD), + 0x36 => Some(Instruction::CALLDATASIZE), + 0x37 => Some(Instruction::CALLDATACOPY), + 0x38 => Some(Instruction::CODESIZE), + 0x39 => Some(Instruction::CODECOPY), + 0x3a => Some(Instruction::GASPRICE), + 0x3b => Some(Instruction::EXTCODESIZE), + 0x3c => Some(Instruction::EXTCODECOPY), + 0x3d => Some(Instruction::RETURNDATASIZE), + 0x3e => Some(Instruction::RETURNDATACOPY), + + 0x40 => Some(Instruction::BLOCKHASH), + 0x41 => Some(Instruction::COINBASE), + 0x42 => Some(Instruction::TIMESTAMP), + 0x43 => Some(Instruction::NUMBER), + 0x44 => Some(Instruction::DIFFICULTY), + 0x45 => Some(Instruction::GASLIMIT), + + 0x50 => Some(Instruction::POP), + 0x51 => Some(Instruction::MLOAD), + 0x52 => Some(Instruction::MSTORE), + 0x53 => Some(Instruction::MSTORE8), + 0x54 => Some(Instruction::SLOAD), + 0x55 => Some(Instruction::SSTORE), + 0x56 => Some(Instruction::JUMP), + 0x57 => Some(Instruction::JUMPI), + 0x58 => Some(Instruction::PC), + 0x59 => Some(Instruction::MSIZE), + 0x5a => Some(Instruction::GAS), + 0x5b => Some(Instruction::JUMPDEST), + + 0x60 => Some(Instruction::PUSH1), + 0x61 => Some(Instruction::PUSH2), + 0x62 => Some(Instruction::PUSH3), + 0x63 => Some(Instruction::PUSH4), + 0x64 => Some(Instruction::PUSH5), + 0x65 => Some(Instruction::PUSH6), + 0x66 => Some(Instruction::PUSH7), + 0x67 => Some(Instruction::PUSH8), + 0x68 => Some(Instruction::PUSH9), + 0x69 => Some(Instruction::PUSH10), + 0x6a => Some(Instruction::PUSH11), + 0x6b => Some(Instruction::PUSH12), + 0x6c => Some(Instruction::PUSH13), + 0x6d => Some(Instruction::PUSH14), + 0x6e => Some(Instruction::PUSH15), + 0x6f => Some(Instruction::PUSH16), + 0x70 => Some(Instruction::PUSH17), + 0x71 => Some(Instruction::PUSH18), + 0x72 => Some(Instruction::PUSH19), + 0x73 => Some(Instruction::PUSH20), + 0x74 => Some(Instruction::PUSH21), + 0x75 => Some(Instruction::PUSH22), + 0x76 => Some(Instruction::PUSH23), + 0x77 => Some(Instruction::PUSH24), + 0x78 => Some(Instruction::PUSH25), + 0x79 => Some(Instruction::PUSH26), + 0x7a => Some(Instruction::PUSH27), + 0x7b => Some(Instruction::PUSH28), + 0x7c => Some(Instruction::PUSH29), + 0x7d => Some(Instruction::PUSH30), + 0x7e => Some(Instruction::PUSH31), + 0x7f => Some(Instruction::PUSH32), + + 0x80 => Some(Instruction::DUP1), + 0x81 => Some(Instruction::DUP2), + 0x82 => Some(Instruction::DUP3), + 0x83 => Some(Instruction::DUP4), + 0x84 => Some(Instruction::DUP5), + 0x85 => Some(Instruction::DUP6), + 0x86 => Some(Instruction::DUP7), + 0x87 => Some(Instruction::DUP8), + 0x88 => Some(Instruction::DUP9), + 0x89 => Some(Instruction::DUP10), + 0x8a => Some(Instruction::DUP11), + 0x8b => Some(Instruction::DUP12), + 0x8c => Some(Instruction::DUP13), + 0x8d => Some(Instruction::DUP14), + 0x8e => Some(Instruction::DUP15), + 0x8f => Some(Instruction::DUP16), + + 0x90 => Some(Instruction::SWAP1), + 0x91 => Some(Instruction::SWAP2), + 0x92 => Some(Instruction::SWAP3), + 0x93 => Some(Instruction::SWAP4), + 0x94 => Some(Instruction::SWAP5), + 0x95 => Some(Instruction::SWAP6), + 0x96 => Some(Instruction::SWAP7), + 0x97 => Some(Instruction::SWAP8), + 0x98 => Some(Instruction::SWAP9), + 0x99 => Some(Instruction::SWAP10), + 0x9a => Some(Instruction::SWAP11), + 0x9b => Some(Instruction::SWAP12), + 0x9c => Some(Instruction::SWAP13), + 0x9d => Some(Instruction::SWAP14), + 0x9e => Some(Instruction::SWAP15), + 0x9f => Some(Instruction::SWAP16), + + 0xa0 => Some(Instruction::LOG0), + 0xa1 => Some(Instruction::LOG1), + 0xa2 => Some(Instruction::LOG2), + 0xa3 => Some(Instruction::LOG3), + 0xa4 => Some(Instruction::LOG4), + + 0xf0 => Some(Instruction::CREATE), + 0xf1 => Some(Instruction::CALL), + 0xf2 => Some(Instruction::CALLCODE), + 0xf3 => Some(Instruction::RETURN), + 0xf4 => Some(Instruction::DELEGATECALL), + 0xfb => Some(Instruction::CREATE2), + 0xfd => Some(Instruction::REVERT), + 0xfa => Some(Instruction::STATICCALL), + 0xff => Some(Instruction::SUICIDE), + + _ => None, } } -} -/// Returns true if given instruction is `PUSHN` instruction. -pub fn is_push(i: Instruction) -> bool { - i >= PUSH1 && i <= PUSH32 + /// Returns true if given instruction is `PUSHN` instruction. + pub fn is_push(&self) -> bool { + *self >= PUSH1 && *self <= PUSH32 + } + + /// Returns number of bytes to read for `PUSHN` instruction + /// PUSH1 -> 1 + pub fn push_bytes(&self) -> Option { + if self.is_push() { + Some(((*self as u8) - (PUSH1 as u8) + 1) as usize) + } else { + None + } + } + + + /// Returns stack position of item to duplicate + /// DUP1 -> 0 + pub fn dup_position(&self) -> Option { + if *self >= DUP1 && *self <= DUP16 { + Some(((*self as u8) - (DUP1 as u8)) as usize) + } else { + None + } + } + + + /// Returns stack position of item to SWAP top with + /// SWAP1 -> 1 + pub fn swap_position(&self) -> Option { + if *self >= SWAP1 && *self <= SWAP16 { + Some(((*self as u8) - (SWAP1 as u8) + 1) as usize) + } else { + None + } + } + + /// Returns number of topics to take from stack + /// LOG0 -> 0 + pub fn log_topics(&self) -> Option { + if *self >= LOG0 && *self <= LOG4 { + Some(((*self as u8) - (LOG0 as u8)) as usize) + } else { + None + } + } } #[test] @@ -477,22 +521,6 @@ fn test_is_push() { assert!(!is_push(DUP1)); } -/// Returns number of bytes to read for `PUSHN` instruction -/// PUSH1 -> 1 -pub fn get_push_bytes(i: Instruction) -> usize { - assert!(is_push(i), "Only for PUSH instructions."); - (i - PUSH1 + 1) as usize -} - -/// Returns number of bytes to read for `PUSHN` instruction or 0. -pub fn push_bytes(i: Instruction) -> usize { - if is_push(i) { - get_push_bytes(i) - } else { - 0 - } -} - #[test] fn test_get_push_bytes() { assert_eq!(get_push_bytes(PUSH1), 1); @@ -500,13 +528,6 @@ fn test_get_push_bytes() { assert_eq!(get_push_bytes(PUSH32), 32); } -/// Returns stack position of item to duplicate -/// DUP1 -> 0 -pub fn get_dup_position(i: Instruction) -> usize { - assert!(i >= DUP1 && i <= DUP16); - (i - DUP1) as usize -} - #[test] fn test_get_dup_position() { assert_eq!(get_dup_position(DUP1), 0); @@ -514,13 +535,6 @@ fn test_get_dup_position() { assert_eq!(get_dup_position(DUP10), 9); } -/// Returns stack position of item to SWAP top with -/// SWAP1 -> 1 -pub fn get_swap_position(i: Instruction) -> usize { - assert!(i >= SWAP1 && i <= SWAP16); - (i - SWAP1 + 1) as usize -} - #[test] fn test_get_swap_position() { assert_eq!(get_swap_position(SWAP1), 1); @@ -528,13 +542,6 @@ fn test_get_swap_position() { assert_eq!(get_swap_position(SWAP10), 10); } -/// Returns number of topics to take from stack -/// LOG0 -> 0 -pub fn get_log_topics (i: Instruction) -> usize { - assert!(i >= LOG0 && i <= LOG4); - (i - LOG0) as usize -} - #[test] fn test_get_log_topics() { assert_eq!(get_log_topics(LOG0), 0); @@ -564,24 +571,26 @@ pub enum GasPriceTier { Invalid } -impl Default for GasPriceTier { - fn default() -> Self { - GasPriceTier::Invalid +impl GasPriceTier { + /// Returns the index in schedule for specific `GasPriceTier` + pub fn idx(&self) -> usize { + match self { + &GasPriceTier::Zero => 0, + &GasPriceTier::Base => 1, + &GasPriceTier::VeryLow => 2, + &GasPriceTier::Low => 3, + &GasPriceTier::Mid => 4, + &GasPriceTier::High => 5, + &GasPriceTier::Ext => 6, + &GasPriceTier::Special => 7, + &GasPriceTier::Invalid => 8 + } } } -/// Returns the index in schedule for specific `GasPriceTier` -pub fn get_tier_idx (tier: GasPriceTier) -> usize { - match tier { - GasPriceTier::Zero => 0, - GasPriceTier::Base => 1, - GasPriceTier::VeryLow => 2, - GasPriceTier::Low => 3, - GasPriceTier::Mid => 4, - GasPriceTier::High => 5, - GasPriceTier::Ext => 6, - GasPriceTier::Special => 7, - GasPriceTier::Invalid => 8 +impl Default for GasPriceTier { + fn default() -> Self { + GasPriceTier::Invalid } } diff --git a/ethcore/evm/src/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs index 85ea8ee487e..a11a4028d79 100644 --- a/ethcore/evm/src/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -113,7 +113,7 @@ impl Gasometer { current_mem_size: usize, ) -> vm::Result> { let schedule = ext.schedule(); - let tier = instructions::get_tier_idx(info.tier); + let tier = info.tier.idx(); let default_gas = Gas::from(schedule.tier_step_gas[tier]); let cost = match instruction { @@ -179,8 +179,8 @@ impl Gasometer { instructions::EXTCODECOPY => { Request::GasMemCopy(schedule.extcodecopy_base_gas.into(), mem_needed(stack.peek(1), stack.peek(3))?, Gas::from_u256(*stack.peek(3))?) }, - instructions::LOG0...instructions::LOG4 => { - let no_of_topics = instructions::get_log_topics(instruction); + instructions::LOG0 | instructions::LOG1 | instructions::LOG2 | instructions::LOG3 | instructions::LOG4 => { + let no_of_topics = instruction.log_topics().expect("log_topcis always return some for LOG* instructions; qed"); let log_gas = schedule.log_gas + schedule.log_topic_gas * no_of_topics; let data_gas = overflowing!(Gas::from_u256(*stack.peek(1))?.overflow_mul(Gas::from(schedule.log_data_gas))); diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index ef9b3fb9734..1900a4c5731 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -64,7 +64,6 @@ struct CodeReader<'a> { } impl<'a> CodeReader<'a> { - /// Create new code reader - starting at position 0. fn new(code: &'a [u8]) -> Self { CodeReader { @@ -81,7 +80,7 @@ impl<'a> CodeReader<'a> { U256::from(&self.code[pos..max]) } - fn len (&self) -> usize { + fn len(&self) -> usize { self.code.len() } } @@ -127,21 +126,28 @@ impl vm::Vm for Interpreter { let infos = &*instructions::INSTRUCTIONS; while reader.position < code.len() { - let instruction = code[reader.position]; + let instruction = Instruction::from_u8(code[reader.position]); reader.position += 1; // TODO: make compile-time removable if too much of a performance hit. do_trace = do_trace && ext.trace_next_instruction( - reader.position - 1, instruction, gasometer.current_gas.as_u256(), + reader.position - 1, code[reader.position], gasometer.current_gas.as_u256(), ); + if instruction.is_none() { + return Err(vm::Error::BadInstruction { + instruction: code[reader.position] + }); + } + let instruction = instruction.expect("None case is checked above; qed"); + let info = &infos[instruction as usize]; self.verify_instruction(ext, instruction, info, &stack)?; // Calculate gas cost let requirements = gasometer.requirements(ext, instruction, info, &stack, self.mem.size())?; if do_trace { - ext.trace_prepare_execute(reader.position - 1, instruction, requirements.gas_cost.as_u256()); + ext.trace_prepare_execute(reader.position - 1, instruction as u8, requirements.gas_cost.as_u256()); } gasometer.verify_gas(&requirements.gas_cost)?; @@ -227,14 +233,12 @@ impl Interpreter { ((instruction == instructions::SHL || instruction == instructions::SHR || instruction == instructions::SAR) && !schedule.have_bitwise_shifting) { return Err(vm::Error::BadInstruction { - instruction: instruction + instruction: instruction as u8 }); } if info.tier == instructions::GasPriceTier::Invalid { - return Err(vm::Error::BadInstruction { - instruction: instruction - }); + panic!("A instruction is defined in Instruction enum, but it is not found in InstructionInfo struct; this indicates a logic failure in the code."); } if !stack.has(info.args) { @@ -396,7 +400,7 @@ impl Interpreter { }, instructions::DELEGATECALL => (¶ms.sender, ¶ms.address, true, CallType::DelegateCall), instructions::STATICCALL => (¶ms.address, &code_address, true, CallType::StaticCall), - _ => panic!(format!("Unexpected instruction {} in CALL branch.", instruction)) + _ => panic!(format!("Unexpected instruction {:?} in CALL branch.", instruction)) }; // clear return data buffer before creating new call frame. @@ -453,8 +457,8 @@ impl Interpreter { ext.suicide(&u256_to_address(&address))?; return Ok(InstructionResult::StopExecution); }, - instructions::LOG0...instructions::LOG4 => { - let no_of_topics = instructions::get_log_topics(instruction); + instructions::LOG0 | instructions::LOG1 | instructions::LOG2 | instructions::LOG3 | instructions::LOG4 => { + let no_of_topics = instruction.log_topics().expect("log_topics always return some for LOG* instructions; qed"); let offset = stack.pop_back(); let size = stack.pop_back(); @@ -464,8 +468,15 @@ impl Interpreter { .collect(); ext.log(topics, self.mem.read_slice(offset, size))?; }, - instructions::PUSH1...instructions::PUSH32 => { - let bytes = instructions::get_push_bytes(instruction); + instructions::PUSH1 | instructions::PUSH2 | instructions::PUSH3 | instructions::PUSH4 | + instructions::PUSH5 | instructions::PUSH6 | instructions::PUSH7 | instructions::PUSH8 | + instructions::PUSH9 | instructions::PUSH10 | instructions::PUSH11 | instructions::PUSH12 | + instructions::PUSH13 | instructions::PUSH14 | instructions::PUSH15 | instructions::PUSH16 | + instructions::PUSH17 | instructions::PUSH18 | instructions::PUSH19 | instructions::PUSH20 | + instructions::PUSH21 | instructions::PUSH22 | instructions::PUSH23 | instructions::PUSH24 | + instructions::PUSH25 | instructions::PUSH26 | instructions::PUSH27 | instructions::PUSH28 | + instructions::PUSH29 | instructions::PUSH30 | instructions::PUSH31 | instructions::PUSH32 => { + let bytes = instruction.push_bytes().expect("push_bytes always return some for PUSH* instructions"); let val = code.read(bytes); stack.push(val); }, @@ -609,73 +620,22 @@ impl Interpreter { instructions::GASLIMIT => { stack.push(ext.env_info().gas_limit.clone()); }, - _ => { - self.exec_stack_instruction(instruction, stack)?; - } - }; - Ok(InstructionResult::Ok) - } - - fn copy_data_to_memory(mem: &mut Vec, stack: &mut Stack, source: &[u8]) { - let dest_offset = stack.pop_back(); - let source_offset = stack.pop_back(); - let size = stack.pop_back(); - let source_size = U256::from(source.len()); - - let output_end = match source_offset > source_size || size > source_size || source_offset + size > source_size { - true => { - let zero_slice = if source_offset > source_size { - mem.writeable_slice(dest_offset, size) - } else { - mem.writeable_slice(dest_offset + source_size - source_offset, source_offset + size - source_size) - }; - for i in zero_slice.iter_mut() { - *i = 0; - } - source.len() - }, - false => (size.low_u64() + source_offset.low_u64()) as usize - }; - if source_offset < source_size { - let output_begin = source_offset.low_u64() as usize; - mem.write_slice(dest_offset, &source[output_begin..output_end]); - } - } - - fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> vm::Result { - let jump = jump_u.low_u64() as usize; - - if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u { - Ok(jump) - } else { - Err(vm::Error::BadJumpDestination { - destination: jump - }) - } - } - - fn is_zero(&self, val: &U256) -> bool { - val.is_zero() - } - - fn bool_to_u256(&self, val: bool) -> U256 { - if val { - U256::one() - } else { - U256::zero() - } - } + // Stack instructions - fn exec_stack_instruction(&self, instruction: Instruction, stack: &mut Stack) -> vm::Result<()> { - match instruction { - instructions::DUP1...instructions::DUP16 => { - let position = instructions::get_dup_position(instruction); + instructions::DUP1 | instructions::DUP2 | instructions::DUP3 | instructions::DUP4 | + instructions::DUP5 | instructions::DUP6 | instructions::DUP7 | instructions::DUP8 | + instructions::DUP9 | instructions::DUP10 | instructions::DUP11 | instructions::DUP12 | + instructions::DUP13 | instructions::DUP14 | instructions::DUP15 | instructions::DUP16 => { + let position = instruction.dup_position().expect("dup_position always return some for DUP* instructions"); let val = stack.peek(position).clone(); stack.push(val); }, - instructions::SWAP1...instructions::SWAP16 => { - let position = instructions::get_swap_position(instruction); + instructions::SWAP1 | instructions::SWAP2 | instructions::SWAP3 | instructions::SWAP4 | + instructions::SWAP5 | instructions::SWAP6 | instructions::SWAP7 | instructions::SWAP8 | + instructions::SWAP9 | instructions::SWAP10 | instructions::SWAP11 | instructions::SWAP12 | + instructions::SWAP13 | instructions::SWAP14 | instructions::SWAP15 | instructions::SWAP16 => { + let position = instruction.swap_position().expect("swap_position always return some for SWAP* instructions"); stack.swap_with_top(position) }, instructions::POP => { @@ -923,15 +883,60 @@ impl Interpreter { }; stack.push(result); }, - _ => { - return Err(vm::Error::BadInstruction { - instruction: instruction - }); - } + }; + Ok(InstructionResult::Ok) + } + + fn copy_data_to_memory(mem: &mut Vec, stack: &mut Stack, source: &[u8]) { + let dest_offset = stack.pop_back(); + let source_offset = stack.pop_back(); + let size = stack.pop_back(); + let source_size = U256::from(source.len()); + + let output_end = match source_offset > source_size || size > source_size || source_offset + size > source_size { + true => { + let zero_slice = if source_offset > source_size { + mem.writeable_slice(dest_offset, size) + } else { + mem.writeable_slice(dest_offset + source_size - source_offset, source_offset + size - source_size) + }; + for i in zero_slice.iter_mut() { + *i = 0; + } + source.len() + }, + false => (size.low_u64() + source_offset.low_u64()) as usize + }; + + if source_offset < source_size { + let output_begin = source_offset.low_u64() as usize; + mem.write_slice(dest_offset, &source[output_begin..output_end]); } - Ok(()) } + fn verify_jump(&self, jump_u: U256, valid_jump_destinations: &BitSet) -> vm::Result { + let jump = jump_u.low_u64() as usize; + + if valid_jump_destinations.contains(jump) && U256::from(jump) == jump_u { + Ok(jump) + } else { + Err(vm::Error::BadJumpDestination { + destination: jump + }) + } + } + + fn is_zero(&self, val: &U256) -> bool { + val.is_zero() + } + + fn bool_to_u256(&self, val: bool) -> U256 { + if val { + U256::one() + } else { + U256::zero() + } + } } fn get_and_reset_sign(value: U256) -> (U256, bool) { diff --git a/ethcore/evm/src/interpreter/shared_cache.rs b/ethcore/evm/src/interpreter/shared_cache.rs index d4e992c90e8..0f090e30c7c 100644 --- a/ethcore/evm/src/interpreter/shared_cache.rs +++ b/ethcore/evm/src/interpreter/shared_cache.rs @@ -21,7 +21,7 @@ use ethereum_types::H256; use parking_lot::Mutex; use memory_cache::MemoryLruCache; use bit_set::BitSet; -use super::super::instructions; +use super::super::instructions::{self, Instruction}; const DEFAULT_CACHE_SIZE: usize = 4 * 1024 * 1024; @@ -70,12 +70,14 @@ impl SharedCache { let mut position = 0; while position < code.len() { - let instruction = code[position]; - - if instruction == instructions::JUMPDEST { - jump_dests.insert(position); - } else if instructions::is_push(instruction) { - position += instructions::get_push_bytes(instruction); + let instruction = Instruction::from_u8(code[position]); + + if let Some(instruction) = instruction { + if instruction == instructions::JUMPDEST { + jump_dests.insert(position); + } else if instruction.is_push() { + position += instruction.push_bytes().expect("push_bytes always return some when is_push is true; qed"); + } } position += 1; } diff --git a/ethcore/evm/src/lib.rs b/ethcore/evm/src/lib.rs index 6eca25f42f5..cd326a317ec 100644 --- a/ethcore/evm/src/lib.rs +++ b/ethcore/evm/src/lib.rs @@ -52,6 +52,6 @@ pub use vm::{ GasLeft, ReturnData }; pub use self::evm::{Finalize, FinalizationResult, CostType}; -pub use self::instructions::{InstructionInfo, INSTRUCTIONS, push_bytes}; +pub use self::instructions::{InstructionInfo, Instruction}; pub use self::vmtype::VMType; pub use self::factory::Factory; From 2bc32c53633573b8bc58571b272234ba9f012059 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Jun 2018 15:50:19 +0800 Subject: [PATCH 03/10] Fix tests --- ethcore/evm/src/instructions.rs | 75 ++++++++++++++++-------------- ethcore/evm/src/interpreter/mod.rs | 7 +-- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index 01e80b3f6cc..dd2bb45747e 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -514,41 +514,6 @@ impl Instruction { } } -#[test] -fn test_is_push() { - assert!(is_push(PUSH1)); - assert!(is_push(PUSH32)); - assert!(!is_push(DUP1)); -} - -#[test] -fn test_get_push_bytes() { - assert_eq!(get_push_bytes(PUSH1), 1); - assert_eq!(get_push_bytes(PUSH3), 3); - assert_eq!(get_push_bytes(PUSH32), 32); -} - -#[test] -fn test_get_dup_position() { - assert_eq!(get_dup_position(DUP1), 0); - assert_eq!(get_dup_position(DUP5), 4); - assert_eq!(get_dup_position(DUP10), 9); -} - -#[test] -fn test_get_swap_position() { - assert_eq!(get_swap_position(SWAP1), 1); - assert_eq!(get_swap_position(SWAP5), 5); - assert_eq!(get_swap_position(SWAP10), 10); -} - -#[test] -fn test_get_log_topics() { - assert_eq!(get_log_topics(LOG0), 0); - assert_eq!(get_log_topics(LOG2), 2); - assert_eq!(get_log_topics(LOG4), 4); -} - #[derive(PartialEq, Clone, Copy)] pub enum GasPriceTier { /// 0 Zero @@ -767,3 +732,43 @@ lazy_static! { /// Maximal number of topics for log instructions pub const MAX_NO_OF_TOPICS : usize = 4; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_is_push() { + assert!(PUSH1.is_push()); + assert!(PUSH32.is_push()); + assert!(!DUP1.is_push()); + } + + #[test] + fn test_get_push_bytes() { + assert_eq!(PUSH1.push_bytes(), Some(1)); + assert_eq!(PUSH3.push_bytes(), Some(3)); + assert_eq!(PUSH32.push_bytes(), Some(32)); + } + + #[test] + fn test_get_dup_position() { + assert_eq!(DUP1.dup_position(), Some(0)); + assert_eq!(DUP5.dup_position(), Some(4)); + assert_eq!(DUP10.dup_position(), Some(9)); + } + + #[test] + fn test_get_swap_position() { + assert_eq!(SWAP1.swap_position(), Some(1)); + assert_eq!(SWAP5.swap_position(), Some(5)); + assert_eq!(SWAP10.swap_position(), Some(10)); + } + + #[test] + fn test_get_log_topics() { + assert_eq!(LOG0.log_topics(), Some(0)); + assert_eq!(LOG2.log_topics(), Some(2)); + assert_eq!(LOG4.log_topics(), Some(4)); + } +} diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 1900a4c5731..4f0776c1069 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -126,17 +126,18 @@ impl vm::Vm for Interpreter { let infos = &*instructions::INSTRUCTIONS; while reader.position < code.len() { - let instruction = Instruction::from_u8(code[reader.position]); + let opcode = code[reader.position]; + let instruction = Instruction::from_u8(opcode); reader.position += 1; // TODO: make compile-time removable if too much of a performance hit. do_trace = do_trace && ext.trace_next_instruction( - reader.position - 1, code[reader.position], gasometer.current_gas.as_u256(), + reader.position - 1, opcode, gasometer.current_gas.as_u256(), ); if instruction.is_none() { return Err(vm::Error::BadInstruction { - instruction: code[reader.position] + instruction: opcode }); } let instruction = instruction.expect("None case is checked above; qed"); From ea7811874435b3404ed9ab40bd51f8a49a8abfef Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Jun 2018 16:12:10 +0800 Subject: [PATCH 04/10] Access instruction info as a Instruction impl --- ethcore/evm/src/instructions.rs | 298 ++++++++++++++--------------- ethcore/evm/src/interpreter/mod.rs | 7 +- 2 files changed, 148 insertions(+), 157 deletions(-) diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index dd2bb45747e..dbcb3db93e6 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -512,6 +512,11 @@ impl Instruction { None } } + + /// Returns the instruction info. + pub fn info(&self) -> &'static InstructionInfo { + INSTRUCTIONS[*self as usize].as_ref().expect("A instruction is defined in Instruction enum, but it is not found in InstructionInfo struct; this indicates a logic failure in the code.") + } } #[derive(PartialEq, Clone, Copy)] @@ -532,8 +537,6 @@ pub enum GasPriceTier { Ext, /// Multiparam or otherwise special Special, - /// Invalid - Invalid } impl GasPriceTier { @@ -548,19 +551,12 @@ impl GasPriceTier { &GasPriceTier::High => 5, &GasPriceTier::Ext => 6, &GasPriceTier::Special => 7, - &GasPriceTier::Invalid => 8 } } } -impl Default for GasPriceTier { - fn default() -> Self { - GasPriceTier::Invalid - } -} - /// EVM instruction information. -#[derive(Copy, Clone, Default)] +#[derive(Copy, Clone)] pub struct InstructionInfo { /// Mnemonic name. pub name: &'static str, @@ -586,152 +582,152 @@ impl InstructionInfo { lazy_static! { /// Static instruction table. - pub static ref INSTRUCTIONS: [InstructionInfo; 0x100] = { - let mut arr = [InstructionInfo::default(); 0x100]; - arr[STOP as usize] = InstructionInfo::new("STOP", 0, 0, GasPriceTier::Zero); - arr[ADD as usize] = InstructionInfo::new("ADD", 2, 1, GasPriceTier::VeryLow); - arr[SUB as usize] = InstructionInfo::new("SUB", 2, 1, GasPriceTier::VeryLow); - arr[MUL as usize] = InstructionInfo::new("MUL", 2, 1, GasPriceTier::Low); - arr[DIV as usize] = InstructionInfo::new("DIV", 2, 1, GasPriceTier::Low); - arr[SDIV as usize] = InstructionInfo::new("SDIV", 2, 1, GasPriceTier::Low); - arr[MOD as usize] = InstructionInfo::new("MOD", 2, 1, GasPriceTier::Low); - arr[SMOD as usize] = InstructionInfo::new("SMOD", 2, 1, GasPriceTier::Low); - arr[EXP as usize] = InstructionInfo::new("EXP", 2, 1, GasPriceTier::Special); - arr[NOT as usize] = InstructionInfo::new("NOT", 1, 1, GasPriceTier::VeryLow); - arr[LT as usize] = InstructionInfo::new("LT", 2, 1, GasPriceTier::VeryLow); - arr[GT as usize] = InstructionInfo::new("GT", 2, 1, GasPriceTier::VeryLow); - arr[SLT as usize] = InstructionInfo::new("SLT", 2, 1, GasPriceTier::VeryLow); - arr[SGT as usize] = InstructionInfo::new("SGT", 2, 1, GasPriceTier::VeryLow); - arr[EQ as usize] = InstructionInfo::new("EQ", 2, 1, GasPriceTier::VeryLow); - arr[ISZERO as usize] = InstructionInfo::new("ISZERO", 1, 1, GasPriceTier::VeryLow); - arr[AND as usize] = InstructionInfo::new("AND", 2, 1, GasPriceTier::VeryLow); - arr[OR as usize] = InstructionInfo::new("OR", 2, 1, GasPriceTier::VeryLow); - arr[XOR as usize] = InstructionInfo::new("XOR", 2, 1, GasPriceTier::VeryLow); - arr[BYTE as usize] = InstructionInfo::new("BYTE", 2, 1, GasPriceTier::VeryLow); - arr[SHL as usize] = InstructionInfo::new("SHL", 2, 1, GasPriceTier::VeryLow); - arr[SHR as usize] = InstructionInfo::new("SHR", 2, 1, GasPriceTier::VeryLow); - arr[SAR as usize] = InstructionInfo::new("SAR", 2, 1, GasPriceTier::VeryLow); - arr[ADDMOD as usize] = InstructionInfo::new("ADDMOD", 3, 1, GasPriceTier::Mid); - arr[MULMOD as usize] = InstructionInfo::new("MULMOD", 3, 1, GasPriceTier::Mid); - arr[SIGNEXTEND as usize] = InstructionInfo::new("SIGNEXTEND", 2, 1, GasPriceTier::Low); - arr[RETURNDATASIZE as usize] = InstructionInfo::new("RETURNDATASIZE", 0, 1, GasPriceTier::Base); - arr[RETURNDATACOPY as usize] = InstructionInfo::new("RETURNDATACOPY", 3, 0, GasPriceTier::VeryLow); - arr[SHA3 as usize] = InstructionInfo::new("SHA3", 2, 1, GasPriceTier::Special); - arr[ADDRESS as usize] = InstructionInfo::new("ADDRESS", 0, 1, GasPriceTier::Base); - arr[BALANCE as usize] = InstructionInfo::new("BALANCE", 1, 1, GasPriceTier::Special); - arr[ORIGIN as usize] = InstructionInfo::new("ORIGIN", 0, 1, GasPriceTier::Base); - arr[CALLER as usize] = InstructionInfo::new("CALLER", 0, 1, GasPriceTier::Base); - arr[CALLVALUE as usize] = InstructionInfo::new("CALLVALUE", 0, 1, GasPriceTier::Base); - arr[CALLDATALOAD as usize] = InstructionInfo::new("CALLDATALOAD", 1, 1, GasPriceTier::VeryLow); - arr[CALLDATASIZE as usize] = InstructionInfo::new("CALLDATASIZE", 0, 1, GasPriceTier::Base); - arr[CALLDATACOPY as usize] = InstructionInfo::new("CALLDATACOPY", 3, 0, GasPriceTier::VeryLow); - arr[CODESIZE as usize] = InstructionInfo::new("CODESIZE", 0, 1, GasPriceTier::Base); - arr[CODECOPY as usize] = InstructionInfo::new("CODECOPY", 3, 0, GasPriceTier::VeryLow); - arr[GASPRICE as usize] = InstructionInfo::new("GASPRICE", 0, 1, GasPriceTier::Base); - arr[EXTCODESIZE as usize] = InstructionInfo::new("EXTCODESIZE", 1, 1, GasPriceTier::Special); - arr[EXTCODECOPY as usize] = InstructionInfo::new("EXTCODECOPY", 4, 0, GasPriceTier::Special); - arr[BLOCKHASH as usize] = InstructionInfo::new("BLOCKHASH", 1, 1, GasPriceTier::Ext); - arr[COINBASE as usize] = InstructionInfo::new("COINBASE", 0, 1, GasPriceTier::Base); - arr[TIMESTAMP as usize] = InstructionInfo::new("TIMESTAMP", 0, 1, GasPriceTier::Base); - arr[NUMBER as usize] = InstructionInfo::new("NUMBER", 0, 1, GasPriceTier::Base); - arr[DIFFICULTY as usize] = InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base); - arr[GASLIMIT as usize] = InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base); - arr[POP as usize] = InstructionInfo::new("POP", 1, 0, GasPriceTier::Base); - arr[MLOAD as usize] = InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow); - arr[MSTORE as usize] = InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow); - arr[MSTORE8 as usize] = InstructionInfo::new("MSTORE8", 2, 0, GasPriceTier::VeryLow); - arr[SLOAD as usize] = InstructionInfo::new("SLOAD", 1, 1, GasPriceTier::Special); - arr[SSTORE as usize] = InstructionInfo::new("SSTORE", 2, 0, GasPriceTier::Special); - arr[JUMP as usize] = InstructionInfo::new("JUMP", 1, 0, GasPriceTier::Mid); - arr[JUMPI as usize] = InstructionInfo::new("JUMPI", 2, 0, GasPriceTier::High); - arr[PC as usize] = InstructionInfo::new("PC", 0, 1, GasPriceTier::Base); - arr[MSIZE as usize] = InstructionInfo::new("MSIZE", 0, 1, GasPriceTier::Base); - arr[GAS as usize] = InstructionInfo::new("GAS", 0, 1, GasPriceTier::Base); - arr[JUMPDEST as usize] = InstructionInfo::new("JUMPDEST", 0, 0, GasPriceTier::Special); - arr[PUSH1 as usize] = InstructionInfo::new("PUSH1", 0, 1, GasPriceTier::VeryLow); - arr[PUSH2 as usize] = InstructionInfo::new("PUSH2", 0, 1, GasPriceTier::VeryLow); - arr[PUSH3 as usize] = InstructionInfo::new("PUSH3", 0, 1, GasPriceTier::VeryLow); - arr[PUSH4 as usize] = InstructionInfo::new("PUSH4", 0, 1, GasPriceTier::VeryLow); - arr[PUSH5 as usize] = InstructionInfo::new("PUSH5", 0, 1, GasPriceTier::VeryLow); - arr[PUSH6 as usize] = InstructionInfo::new("PUSH6", 0, 1, GasPriceTier::VeryLow); - arr[PUSH7 as usize] = InstructionInfo::new("PUSH7", 0, 1, GasPriceTier::VeryLow); - arr[PUSH8 as usize] = InstructionInfo::new("PUSH8", 0, 1, GasPriceTier::VeryLow); - arr[PUSH9 as usize] = InstructionInfo::new("PUSH9", 0, 1, GasPriceTier::VeryLow); - arr[PUSH10 as usize] = InstructionInfo::new("PUSH10", 0, 1, GasPriceTier::VeryLow); - arr[PUSH11 as usize] = InstructionInfo::new("PUSH11", 0, 1, GasPriceTier::VeryLow); - arr[PUSH12 as usize] = InstructionInfo::new("PUSH12", 0, 1, GasPriceTier::VeryLow); - arr[PUSH13 as usize] = InstructionInfo::new("PUSH13", 0, 1, GasPriceTier::VeryLow); - arr[PUSH14 as usize] = InstructionInfo::new("PUSH14", 0, 1, GasPriceTier::VeryLow); - arr[PUSH15 as usize] = InstructionInfo::new("PUSH15", 0, 1, GasPriceTier::VeryLow); - arr[PUSH16 as usize] = InstructionInfo::new("PUSH16", 0, 1, GasPriceTier::VeryLow); - arr[PUSH17 as usize] = InstructionInfo::new("PUSH17", 0, 1, GasPriceTier::VeryLow); - arr[PUSH18 as usize] = InstructionInfo::new("PUSH18", 0, 1, GasPriceTier::VeryLow); - arr[PUSH19 as usize] = InstructionInfo::new("PUSH19", 0, 1, GasPriceTier::VeryLow); - arr[PUSH20 as usize] = InstructionInfo::new("PUSH20", 0, 1, GasPriceTier::VeryLow); - arr[PUSH21 as usize] = InstructionInfo::new("PUSH21", 0, 1, GasPriceTier::VeryLow); - arr[PUSH22 as usize] = InstructionInfo::new("PUSH22", 0, 1, GasPriceTier::VeryLow); - arr[PUSH23 as usize] = InstructionInfo::new("PUSH23", 0, 1, GasPriceTier::VeryLow); - arr[PUSH24 as usize] = InstructionInfo::new("PUSH24", 0, 1, GasPriceTier::VeryLow); - arr[PUSH25 as usize] = InstructionInfo::new("PUSH25", 0, 1, GasPriceTier::VeryLow); - arr[PUSH26 as usize] = InstructionInfo::new("PUSH26", 0, 1, GasPriceTier::VeryLow); - arr[PUSH27 as usize] = InstructionInfo::new("PUSH27", 0, 1, GasPriceTier::VeryLow); - arr[PUSH28 as usize] = InstructionInfo::new("PUSH28", 0, 1, GasPriceTier::VeryLow); - arr[PUSH29 as usize] = InstructionInfo::new("PUSH29", 0, 1, GasPriceTier::VeryLow); - arr[PUSH30 as usize] = InstructionInfo::new("PUSH30", 0, 1, GasPriceTier::VeryLow); - arr[PUSH31 as usize] = InstructionInfo::new("PUSH31", 0, 1, GasPriceTier::VeryLow); - arr[PUSH32 as usize] = InstructionInfo::new("PUSH32", 0, 1, GasPriceTier::VeryLow); - arr[DUP1 as usize] = InstructionInfo::new("DUP1", 1, 2, GasPriceTier::VeryLow); - arr[DUP2 as usize] = InstructionInfo::new("DUP2", 2, 3, GasPriceTier::VeryLow); - arr[DUP3 as usize] = InstructionInfo::new("DUP3", 3, 4, GasPriceTier::VeryLow); - arr[DUP4 as usize] = InstructionInfo::new("DUP4", 4, 5, GasPriceTier::VeryLow); - arr[DUP5 as usize] = InstructionInfo::new("DUP5", 5, 6, GasPriceTier::VeryLow); - arr[DUP6 as usize] = InstructionInfo::new("DUP6", 6, 7, GasPriceTier::VeryLow); - arr[DUP7 as usize] = InstructionInfo::new("DUP7", 7, 8, GasPriceTier::VeryLow); - arr[DUP8 as usize] = InstructionInfo::new("DUP8", 8, 9, GasPriceTier::VeryLow); - arr[DUP9 as usize] = InstructionInfo::new("DUP9", 9, 10, GasPriceTier::VeryLow); - arr[DUP10 as usize] = InstructionInfo::new("DUP10", 10, 11, GasPriceTier::VeryLow); - arr[DUP11 as usize] = InstructionInfo::new("DUP11", 11, 12, GasPriceTier::VeryLow); - arr[DUP12 as usize] = InstructionInfo::new("DUP12", 12, 13, GasPriceTier::VeryLow); - arr[DUP13 as usize] = InstructionInfo::new("DUP13", 13, 14, GasPriceTier::VeryLow); - arr[DUP14 as usize] = InstructionInfo::new("DUP14", 14, 15, GasPriceTier::VeryLow); - arr[DUP15 as usize] = InstructionInfo::new("DUP15", 15, 16, GasPriceTier::VeryLow); - arr[DUP16 as usize] = InstructionInfo::new("DUP16", 16, 17, GasPriceTier::VeryLow); - arr[SWAP1 as usize] = InstructionInfo::new("SWAP1", 2, 2, GasPriceTier::VeryLow); - arr[SWAP2 as usize] = InstructionInfo::new("SWAP2", 3, 3, GasPriceTier::VeryLow); - arr[SWAP3 as usize] = InstructionInfo::new("SWAP3", 4, 4, GasPriceTier::VeryLow); - arr[SWAP4 as usize] = InstructionInfo::new("SWAP4", 5, 5, GasPriceTier::VeryLow); - arr[SWAP5 as usize] = InstructionInfo::new("SWAP5", 6, 6, GasPriceTier::VeryLow); - arr[SWAP6 as usize] = InstructionInfo::new("SWAP6", 7, 7, GasPriceTier::VeryLow); - arr[SWAP7 as usize] = InstructionInfo::new("SWAP7", 8, 8, GasPriceTier::VeryLow); - arr[SWAP8 as usize] = InstructionInfo::new("SWAP8", 9, 9, GasPriceTier::VeryLow); - arr[SWAP9 as usize] = InstructionInfo::new("SWAP9", 10, 10, GasPriceTier::VeryLow); - arr[SWAP10 as usize] = InstructionInfo::new("SWAP10", 11, 11, GasPriceTier::VeryLow); - arr[SWAP11 as usize] = InstructionInfo::new("SWAP11", 12, 12, GasPriceTier::VeryLow); - arr[SWAP12 as usize] = InstructionInfo::new("SWAP12", 13, 13, GasPriceTier::VeryLow); - arr[SWAP13 as usize] = InstructionInfo::new("SWAP13", 14, 14, GasPriceTier::VeryLow); - arr[SWAP14 as usize] = InstructionInfo::new("SWAP14", 15, 15, GasPriceTier::VeryLow); - arr[SWAP15 as usize] = InstructionInfo::new("SWAP15", 16, 16, GasPriceTier::VeryLow); - arr[SWAP16 as usize] = InstructionInfo::new("SWAP16", 17, 17, GasPriceTier::VeryLow); - arr[LOG0 as usize] = InstructionInfo::new("LOG0", 2, 0, GasPriceTier::Special); - arr[LOG1 as usize] = InstructionInfo::new("LOG1", 3, 0, GasPriceTier::Special); - arr[LOG2 as usize] = InstructionInfo::new("LOG2", 4, 0, GasPriceTier::Special); - arr[LOG3 as usize] = InstructionInfo::new("LOG3", 5, 0, GasPriceTier::Special); - arr[LOG4 as usize] = InstructionInfo::new("LOG4", 6, 0, GasPriceTier::Special); - arr[CREATE as usize] = InstructionInfo::new("CREATE", 3, 1, GasPriceTier::Special); - arr[CALL as usize] = InstructionInfo::new("CALL", 7, 1, GasPriceTier::Special); - arr[CALLCODE as usize] = InstructionInfo::new("CALLCODE", 7, 1, GasPriceTier::Special); - arr[RETURN as usize] = InstructionInfo::new("RETURN", 2, 0, GasPriceTier::Zero); - arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 6, 1, GasPriceTier::Special); - arr[STATICCALL as usize] = InstructionInfo::new("STATICCALL", 6, 1, GasPriceTier::Special); - arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 1, 0, GasPriceTier::Special); - arr[CREATE2 as usize] = InstructionInfo::new("CREATE2", 3, 1, GasPriceTier::Special); - arr[REVERT as usize] = InstructionInfo::new("REVERT", 2, 0, GasPriceTier::Zero); + static ref INSTRUCTIONS: [Option; 0x100] = { + let mut arr = [None; 0x100]; + arr[STOP as usize] = Some(InstructionInfo::new("STOP", 0, 0, GasPriceTier::Zero)); + arr[ADD as usize] = Some(InstructionInfo::new("ADD", 2, 1, GasPriceTier::VeryLow)); + arr[SUB as usize] = Some(InstructionInfo::new("SUB", 2, 1, GasPriceTier::VeryLow)); + arr[MUL as usize] = Some(InstructionInfo::new("MUL", 2, 1, GasPriceTier::Low)); + arr[DIV as usize] = Some(InstructionInfo::new("DIV", 2, 1, GasPriceTier::Low)); + arr[SDIV as usize] = Some(InstructionInfo::new("SDIV", 2, 1, GasPriceTier::Low)); + arr[MOD as usize] = Some(InstructionInfo::new("MOD", 2, 1, GasPriceTier::Low)); + arr[SMOD as usize] = Some(InstructionInfo::new("SMOD", 2, 1, GasPriceTier::Low)); + arr[EXP as usize] = Some(InstructionInfo::new("EXP", 2, 1, GasPriceTier::Special)); + arr[NOT as usize] = Some(InstructionInfo::new("NOT", 1, 1, GasPriceTier::VeryLow)); + arr[LT as usize] = Some(InstructionInfo::new("LT", 2, 1, GasPriceTier::VeryLow)); + arr[GT as usize] = Some(InstructionInfo::new("GT", 2, 1, GasPriceTier::VeryLow)); + arr[SLT as usize] = Some(InstructionInfo::new("SLT", 2, 1, GasPriceTier::VeryLow)); + arr[SGT as usize] = Some(InstructionInfo::new("SGT", 2, 1, GasPriceTier::VeryLow)); + arr[EQ as usize] = Some(InstructionInfo::new("EQ", 2, 1, GasPriceTier::VeryLow)); + arr[ISZERO as usize] = Some(InstructionInfo::new("ISZERO", 1, 1, GasPriceTier::VeryLow)); + arr[AND as usize] = Some(InstructionInfo::new("AND", 2, 1, GasPriceTier::VeryLow)); + arr[OR as usize] = Some(InstructionInfo::new("OR", 2, 1, GasPriceTier::VeryLow)); + arr[XOR as usize] = Some(InstructionInfo::new("XOR", 2, 1, GasPriceTier::VeryLow)); + arr[BYTE as usize] = Some(InstructionInfo::new("BYTE", 2, 1, GasPriceTier::VeryLow)); + arr[SHL as usize] = Some(InstructionInfo::new("SHL", 2, 1, GasPriceTier::VeryLow)); + arr[SHR as usize] = Some(InstructionInfo::new("SHR", 2, 1, GasPriceTier::VeryLow)); + arr[SAR as usize] = Some(InstructionInfo::new("SAR", 2, 1, GasPriceTier::VeryLow)); + arr[ADDMOD as usize] = Some(InstructionInfo::new("ADDMOD", 3, 1, GasPriceTier::Mid)); + arr[MULMOD as usize] = Some(InstructionInfo::new("MULMOD", 3, 1, GasPriceTier::Mid)); + arr[SIGNEXTEND as usize] = Some(InstructionInfo::new("SIGNEXTEND", 2, 1, GasPriceTier::Low)); + arr[RETURNDATASIZE as usize] = Some(InstructionInfo::new("RETURNDATASIZE", 0, 1, GasPriceTier::Base)); + arr[RETURNDATACOPY as usize] = Some(InstructionInfo::new("RETURNDATACOPY", 3, 0, GasPriceTier::VeryLow)); + arr[SHA3 as usize] = Some(InstructionInfo::new("SHA3", 2, 1, GasPriceTier::Special)); + arr[ADDRESS as usize] = Some(InstructionInfo::new("ADDRESS", 0, 1, GasPriceTier::Base)); + arr[BALANCE as usize] = Some(InstructionInfo::new("BALANCE", 1, 1, GasPriceTier::Special)); + arr[ORIGIN as usize] = Some(InstructionInfo::new("ORIGIN", 0, 1, GasPriceTier::Base)); + arr[CALLER as usize] = Some(InstructionInfo::new("CALLER", 0, 1, GasPriceTier::Base)); + arr[CALLVALUE as usize] = Some(InstructionInfo::new("CALLVALUE", 0, 1, GasPriceTier::Base)); + arr[CALLDATALOAD as usize] = Some(InstructionInfo::new("CALLDATALOAD", 1, 1, GasPriceTier::VeryLow)); + arr[CALLDATASIZE as usize] = Some(InstructionInfo::new("CALLDATASIZE", 0, 1, GasPriceTier::Base)); + arr[CALLDATACOPY as usize] = Some(InstructionInfo::new("CALLDATACOPY", 3, 0, GasPriceTier::VeryLow)); + arr[CODESIZE as usize] = Some(InstructionInfo::new("CODESIZE", 0, 1, GasPriceTier::Base)); + arr[CODECOPY as usize] = Some(InstructionInfo::new("CODECOPY", 3, 0, GasPriceTier::VeryLow)); + arr[GASPRICE as usize] = Some(InstructionInfo::new("GASPRICE", 0, 1, GasPriceTier::Base)); + arr[EXTCODESIZE as usize] = Some(InstructionInfo::new("EXTCODESIZE", 1, 1, GasPriceTier::Special)); + arr[EXTCODECOPY as usize] = Some(InstructionInfo::new("EXTCODECOPY", 4, 0, GasPriceTier::Special)); + arr[BLOCKHASH as usize] = Some(InstructionInfo::new("BLOCKHASH", 1, 1, GasPriceTier::Ext)); + arr[COINBASE as usize] = Some(InstructionInfo::new("COINBASE", 0, 1, GasPriceTier::Base)); + arr[TIMESTAMP as usize] = Some(InstructionInfo::new("TIMESTAMP", 0, 1, GasPriceTier::Base)); + arr[NUMBER as usize] = Some(InstructionInfo::new("NUMBER", 0, 1, GasPriceTier::Base)); + arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base)); + arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base)); + arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base)); + arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow)); + arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow)); + arr[MSTORE8 as usize] = Some(InstructionInfo::new("MSTORE8", 2, 0, GasPriceTier::VeryLow)); + arr[SLOAD as usize] = Some(InstructionInfo::new("SLOAD", 1, 1, GasPriceTier::Special)); + arr[SSTORE as usize] = Some(InstructionInfo::new("SSTORE", 2, 0, GasPriceTier::Special)); + arr[JUMP as usize] = Some(InstructionInfo::new("JUMP", 1, 0, GasPriceTier::Mid)); + arr[JUMPI as usize] = Some(InstructionInfo::new("JUMPI", 2, 0, GasPriceTier::High)); + arr[PC as usize] = Some(InstructionInfo::new("PC", 0, 1, GasPriceTier::Base)); + arr[MSIZE as usize] = Some(InstructionInfo::new("MSIZE", 0, 1, GasPriceTier::Base)); + arr[GAS as usize] = Some(InstructionInfo::new("GAS", 0, 1, GasPriceTier::Base)); + arr[JUMPDEST as usize] = Some(InstructionInfo::new("JUMPDEST", 0, 0, GasPriceTier::Special)); + arr[PUSH1 as usize] = Some(InstructionInfo::new("PUSH1", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH2 as usize] = Some(InstructionInfo::new("PUSH2", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH3 as usize] = Some(InstructionInfo::new("PUSH3", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH4 as usize] = Some(InstructionInfo::new("PUSH4", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH5 as usize] = Some(InstructionInfo::new("PUSH5", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH6 as usize] = Some(InstructionInfo::new("PUSH6", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH7 as usize] = Some(InstructionInfo::new("PUSH7", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH8 as usize] = Some(InstructionInfo::new("PUSH8", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH9 as usize] = Some(InstructionInfo::new("PUSH9", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH10 as usize] = Some(InstructionInfo::new("PUSH10", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH11 as usize] = Some(InstructionInfo::new("PUSH11", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH12 as usize] = Some(InstructionInfo::new("PUSH12", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH13 as usize] = Some(InstructionInfo::new("PUSH13", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH14 as usize] = Some(InstructionInfo::new("PUSH14", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH15 as usize] = Some(InstructionInfo::new("PUSH15", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH16 as usize] = Some(InstructionInfo::new("PUSH16", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH17 as usize] = Some(InstructionInfo::new("PUSH17", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH18 as usize] = Some(InstructionInfo::new("PUSH18", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH19 as usize] = Some(InstructionInfo::new("PUSH19", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH20 as usize] = Some(InstructionInfo::new("PUSH20", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH21 as usize] = Some(InstructionInfo::new("PUSH21", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH22 as usize] = Some(InstructionInfo::new("PUSH22", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH23 as usize] = Some(InstructionInfo::new("PUSH23", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH24 as usize] = Some(InstructionInfo::new("PUSH24", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH25 as usize] = Some(InstructionInfo::new("PUSH25", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH26 as usize] = Some(InstructionInfo::new("PUSH26", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH27 as usize] = Some(InstructionInfo::new("PUSH27", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH28 as usize] = Some(InstructionInfo::new("PUSH28", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH29 as usize] = Some(InstructionInfo::new("PUSH29", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH30 as usize] = Some(InstructionInfo::new("PUSH30", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH31 as usize] = Some(InstructionInfo::new("PUSH31", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH32 as usize] = Some(InstructionInfo::new("PUSH32", 0, 1, GasPriceTier::VeryLow)); + arr[DUP1 as usize] = Some(InstructionInfo::new("DUP1", 1, 2, GasPriceTier::VeryLow)); + arr[DUP2 as usize] = Some(InstructionInfo::new("DUP2", 2, 3, GasPriceTier::VeryLow)); + arr[DUP3 as usize] = Some(InstructionInfo::new("DUP3", 3, 4, GasPriceTier::VeryLow)); + arr[DUP4 as usize] = Some(InstructionInfo::new("DUP4", 4, 5, GasPriceTier::VeryLow)); + arr[DUP5 as usize] = Some(InstructionInfo::new("DUP5", 5, 6, GasPriceTier::VeryLow)); + arr[DUP6 as usize] = Some(InstructionInfo::new("DUP6", 6, 7, GasPriceTier::VeryLow)); + arr[DUP7 as usize] = Some(InstructionInfo::new("DUP7", 7, 8, GasPriceTier::VeryLow)); + arr[DUP8 as usize] = Some(InstructionInfo::new("DUP8", 8, 9, GasPriceTier::VeryLow)); + arr[DUP9 as usize] = Some(InstructionInfo::new("DUP9", 9, 10, GasPriceTier::VeryLow)); + arr[DUP10 as usize] = Some(InstructionInfo::new("DUP10", 10, 11, GasPriceTier::VeryLow)); + arr[DUP11 as usize] = Some(InstructionInfo::new("DUP11", 11, 12, GasPriceTier::VeryLow)); + arr[DUP12 as usize] = Some(InstructionInfo::new("DUP12", 12, 13, GasPriceTier::VeryLow)); + arr[DUP13 as usize] = Some(InstructionInfo::new("DUP13", 13, 14, GasPriceTier::VeryLow)); + arr[DUP14 as usize] = Some(InstructionInfo::new("DUP14", 14, 15, GasPriceTier::VeryLow)); + arr[DUP15 as usize] = Some(InstructionInfo::new("DUP15", 15, 16, GasPriceTier::VeryLow)); + arr[DUP16 as usize] = Some(InstructionInfo::new("DUP16", 16, 17, GasPriceTier::VeryLow)); + arr[SWAP1 as usize] = Some(InstructionInfo::new("SWAP1", 2, 2, GasPriceTier::VeryLow)); + arr[SWAP2 as usize] = Some(InstructionInfo::new("SWAP2", 3, 3, GasPriceTier::VeryLow)); + arr[SWAP3 as usize] = Some(InstructionInfo::new("SWAP3", 4, 4, GasPriceTier::VeryLow)); + arr[SWAP4 as usize] = Some(InstructionInfo::new("SWAP4", 5, 5, GasPriceTier::VeryLow)); + arr[SWAP5 as usize] = Some(InstructionInfo::new("SWAP5", 6, 6, GasPriceTier::VeryLow)); + arr[SWAP6 as usize] = Some(InstructionInfo::new("SWAP6", 7, 7, GasPriceTier::VeryLow)); + arr[SWAP7 as usize] = Some(InstructionInfo::new("SWAP7", 8, 8, GasPriceTier::VeryLow)); + arr[SWAP8 as usize] = Some(InstructionInfo::new("SWAP8", 9, 9, GasPriceTier::VeryLow)); + arr[SWAP9 as usize] = Some(InstructionInfo::new("SWAP9", 10, 10, GasPriceTier::VeryLow)); + arr[SWAP10 as usize] = Some(InstructionInfo::new("SWAP10", 11, 11, GasPriceTier::VeryLow)); + arr[SWAP11 as usize] = Some(InstructionInfo::new("SWAP11", 12, 12, GasPriceTier::VeryLow)); + arr[SWAP12 as usize] = Some(InstructionInfo::new("SWAP12", 13, 13, GasPriceTier::VeryLow)); + arr[SWAP13 as usize] = Some(InstructionInfo::new("SWAP13", 14, 14, GasPriceTier::VeryLow)); + arr[SWAP14 as usize] = Some(InstructionInfo::new("SWAP14", 15, 15, GasPriceTier::VeryLow)); + arr[SWAP15 as usize] = Some(InstructionInfo::new("SWAP15", 16, 16, GasPriceTier::VeryLow)); + arr[SWAP16 as usize] = Some(InstructionInfo::new("SWAP16", 17, 17, GasPriceTier::VeryLow)); + arr[LOG0 as usize] = Some(InstructionInfo::new("LOG0", 2, 0, GasPriceTier::Special)); + arr[LOG1 as usize] = Some(InstructionInfo::new("LOG1", 3, 0, GasPriceTier::Special)); + arr[LOG2 as usize] = Some(InstructionInfo::new("LOG2", 4, 0, GasPriceTier::Special)); + arr[LOG3 as usize] = Some(InstructionInfo::new("LOG3", 5, 0, GasPriceTier::Special)); + arr[LOG4 as usize] = Some(InstructionInfo::new("LOG4", 6, 0, GasPriceTier::Special)); + arr[CREATE as usize] = Some(InstructionInfo::new("CREATE", 3, 1, GasPriceTier::Special)); + arr[CALL as usize] = Some(InstructionInfo::new("CALL", 7, 1, GasPriceTier::Special)); + arr[CALLCODE as usize] = Some(InstructionInfo::new("CALLCODE", 7, 1, GasPriceTier::Special)); + arr[RETURN as usize] = Some(InstructionInfo::new("RETURN", 2, 0, GasPriceTier::Zero)); + arr[DELEGATECALL as usize] = Some(InstructionInfo::new("DELEGATECALL", 6, 1, GasPriceTier::Special)); + arr[STATICCALL as usize] = Some(InstructionInfo::new("STATICCALL", 6, 1, GasPriceTier::Special)); + arr[SUICIDE as usize] = Some(InstructionInfo::new("SUICIDE", 1, 0, GasPriceTier::Special)); + arr[CREATE2 as usize] = Some(InstructionInfo::new("CREATE2", 3, 1, GasPriceTier::Special)); + arr[REVERT as usize] = Some(InstructionInfo::new("REVERT", 2, 0, GasPriceTier::Zero)); arr }; } /// Maximal number of topics for log instructions -pub const MAX_NO_OF_TOPICS : usize = 4; +pub const MAX_NO_OF_TOPICS: usize = 4; #[cfg(test)] mod tests { diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 4f0776c1069..fc5bbe359f8 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -123,7 +123,6 @@ impl vm::Vm for Interpreter { let mut gasometer = Gasometer::::new(Cost::from_u256(params.gas)?); let mut stack = VecStack::with_capacity(ext.schedule().stack_limit, U256::zero()); let mut reader = CodeReader::new(code); - let infos = &*instructions::INSTRUCTIONS; while reader.position < code.len() { let opcode = code[reader.position]; @@ -142,7 +141,7 @@ impl vm::Vm for Interpreter { } let instruction = instruction.expect("None case is checked above; qed"); - let info = &infos[instruction as usize]; + let info = instruction.info(); self.verify_instruction(ext, instruction, info, &stack)?; // Calculate gas cost @@ -238,10 +237,6 @@ impl Interpreter { }); } - if info.tier == instructions::GasPriceTier::Invalid { - panic!("A instruction is defined in Instruction enum, but it is not found in InstructionInfo struct; this indicates a logic failure in the code."); - } - if !stack.has(info.args) { Err(vm::Error::StackUnderflow { instruction: info.name, From 7771696715aa7c21daf5998b611734062abbedf1 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Jun 2018 16:50:01 +0800 Subject: [PATCH 05/10] Use macro to avoid duplication in from_u8 --- ethcore/evm/src/instructions.rs | 759 +++++++++++++------------------- 1 file changed, 315 insertions(+), 444 deletions(-) diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index dbcb3db93e6..f2680c8bcb4 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -18,454 +18,325 @@ pub use self::Instruction::*; -/// Virtual machine bytecode instruction. -#[repr(u8)] -#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug)] -pub enum Instruction { - /// halts execution - STOP = 0x00, - /// addition operation - ADD = 0x01, - /// mulitplication operation - MUL = 0x02, - /// subtraction operation - SUB = 0x03, - /// integer division operation - DIV = 0x04, - /// signed integer division operation - SDIV = 0x05, - /// modulo remainder operation - MOD = 0x06, - /// signed modulo remainder operation - SMOD = 0x07, - /// unsigned modular addition - ADDMOD = 0x08, - /// unsigned modular multiplication - MULMOD = 0x09, - /// exponential operation - EXP = 0x0a, - /// extend length of signed integer - SIGNEXTEND = 0x0b, - - /// less-than comparision - LT = 0x10, - /// greater-than comparision - GT = 0x11, - /// signed less-than comparision - SLT = 0x12, - /// signed greater-than comparision - SGT = 0x13, - /// equality comparision - EQ = 0x14, - /// simple not operator - ISZERO = 0x15, - /// bitwise AND operation - AND = 0x16, - /// bitwise OR operation - OR = 0x17, - /// bitwise XOR operation - XOR = 0x18, - /// bitwise NOT opertation - NOT = 0x19, - /// retrieve single byte from word - BYTE = 0x1a, - /// shift left operation - SHL = 0x1b, - /// logical shift right operation - SHR = 0x1c, - /// arithmetic shift right operation - SAR = 0x1d, - - /// compute SHA3-256 hash - SHA3 = 0x20, - - /// get address of currently executing account - ADDRESS = 0x30, - /// get balance of the given account - BALANCE = 0x31, - /// get execution origination address - ORIGIN = 0x32, - /// get caller address - CALLER = 0x33, - /// get deposited value by the instruction/transaction responsible for this execution - CALLVALUE = 0x34, - /// get input data of current environment - CALLDATALOAD = 0x35, - /// get size of input data in current environment - CALLDATASIZE = 0x36, - /// copy input data in current environment to memory - CALLDATACOPY = 0x37, - /// get size of code running in current environment - CODESIZE = 0x38, - /// copy code running in current environment to memory - CODECOPY = 0x39, - /// get price of gas in current environment - GASPRICE = 0x3a, - /// get external code size (from another contract) - EXTCODESIZE = 0x3b, - /// copy external code (from another contract) - EXTCODECOPY = 0x3c, - /// get the size of the return data buffer for the last call - RETURNDATASIZE = 0x3d, - /// copy return data buffer to memory - RETURNDATACOPY = 0x3e, - - /// get hash of most recent complete block - BLOCKHASH = 0x40, - /// get the block's coinbase address - COINBASE = 0x41, - /// get the block's timestamp - TIMESTAMP = 0x42, - /// get the block's number - NUMBER = 0x43, - /// get the block's difficulty - DIFFICULTY = 0x44, - /// get the block's gas limit - GASLIMIT = 0x45, - - /// remove item from stack - POP = 0x50, - /// load word from memory - MLOAD = 0x51, - /// save word to memory - MSTORE = 0x52, - /// save byte to memory - MSTORE8 = 0x53, - /// load word from storage - SLOAD = 0x54, - /// save word to storage - SSTORE = 0x55, - /// alter the program counter - JUMP = 0x56, - /// conditionally alter the program counter - JUMPI = 0x57, - /// get the program counter - PC = 0x58, - /// get the size of active memory - MSIZE = 0x59, - /// get the amount of available gas - GAS = 0x5a, - /// set a potential jump destination - JUMPDEST = 0x5b, - - /// place 1 byte item on stack - PUSH1 = 0x60, - /// place 2 byte item on stack - PUSH2 = 0x61, - /// place 3 byte item on stack - PUSH3 = 0x62, - /// place 4 byte item on stack - PUSH4 = 0x63, - /// place 5 byte item on stack - PUSH5 = 0x64, - /// place 6 byte item on stack - PUSH6 = 0x65, - /// place 7 byte item on stack - PUSH7 = 0x66, - /// place 8 byte item on stack - PUSH8 = 0x67, - /// place 9 byte item on stack - PUSH9 = 0x68, - /// place 10 byte item on stack - PUSH10 = 0x69, - /// place 11 byte item on stack - PUSH11 = 0x6a, - /// place 12 byte item on stack - PUSH12 = 0x6b, - /// place 13 byte item on stack - PUSH13 = 0x6c, - /// place 14 byte item on stack - PUSH14 = 0x6d, - /// place 15 byte item on stack - PUSH15 = 0x6e, - /// place 16 byte item on stack - PUSH16 = 0x6f, - /// place 17 byte item on stack - PUSH17 = 0x70, - /// place 18 byte item on stack - PUSH18 = 0x71, - /// place 19 byte item on stack - PUSH19 = 0x72, - /// place 20 byte item on stack - PUSH20 = 0x73, - /// place 21 byte item on stack - PUSH21 = 0x74, - /// place 22 byte item on stack - PUSH22 = 0x75, - /// place 23 byte item on stack - PUSH23 = 0x76, - /// place 24 byte item on stack - PUSH24 = 0x77, - /// place 25 byte item on stack - PUSH25 = 0x78, - /// place 26 byte item on stack - PUSH26 = 0x79, - /// place 27 byte item on stack - PUSH27 = 0x7a, - /// place 28 byte item on stack - PUSH28 = 0x7b, - /// place 29 byte item on stack - PUSH29 = 0x7c, - /// place 30 byte item on stack - PUSH30 = 0x7d, - /// place 31 byte item on stack - PUSH31 = 0x7e, - /// place 32 byte item on stack - PUSH32 = 0x7f, - - /// copies the highest item in the stack to the top of the stack - DUP1 = 0x80, - /// copies the second highest item in the stack to the top of the stack - DUP2 = 0x81, - /// copies the third highest item in the stack to the top of the stack - DUP3 = 0x82, - /// copies the 4th highest item in the stack to the top of the stack - DUP4 = 0x83, - /// copies the 5th highest item in the stack to the top of the stack - DUP5 = 0x84, - /// copies the 6th highest item in the stack to the top of the stack - DUP6 = 0x85, - /// copies the 7th highest item in the stack to the top of the stack - DUP7 = 0x86, - /// copies the 8th highest item in the stack to the top of the stack - DUP8 = 0x87, - /// copies the 9th highest item in the stack to the top of the stack - DUP9 = 0x88, - /// copies the 10th highest item in the stack to the top of the stack - DUP10 = 0x89, - /// copies the 11th highest item in the stack to the top of the stack - DUP11 = 0x8a, - /// copies the 12th highest item in the stack to the top of the stack - DUP12 = 0x8b, - /// copies the 13th highest item in the stack to the top of the stack - DUP13 = 0x8c, - /// copies the 14th highest item in the stack to the top of the stack - DUP14 = 0x8d, - /// copies the 15th highest item in the stack to the top of the stack - DUP15 = 0x8e, - /// copies the 16th highest item in the stack to the top of the stack - DUP16 = 0x8f, - - /// swaps the highest and second highest value on the stack - SWAP1 = 0x90, - /// swaps the highest and third highest value on the stack - SWAP2 = 0x91, - /// swaps the highest and 4th highest value on the stack - SWAP3 = 0x92, - /// swaps the highest and 5th highest value on the stack - SWAP4 = 0x93, - /// swaps the highest and 6th highest value on the stack - SWAP5 = 0x94, - /// swaps the highest and 7th highest value on the stack - SWAP6 = 0x95, - /// swaps the highest and 8th highest value on the stack - SWAP7 = 0x96, - /// swaps the highest and 9th highest value on the stack - SWAP8 = 0x97, - /// swaps the highest and 10th highest value on the stack - SWAP9 = 0x98, - /// swaps the highest and 11th highest value on the stack - SWAP10 = 0x99, - /// swaps the highest and 12th highest value on the stack - SWAP11 = 0x9a, - /// swaps the highest and 13th highest value on the stack - SWAP12 = 0x9b, - /// swaps the highest and 14th highest value on the stack - SWAP13 = 0x9c, - /// swaps the highest and 15th highest value on the stack - SWAP14 = 0x9d, - /// swaps the highest and 16th highest value on the stack - SWAP15 = 0x9e, - /// swaps the highest and 17th highest value on the stack - SWAP16 = 0x9f, - - /// Makes a log entry, no topics. - LOG0 = 0xa0, - /// Makes a log entry, 1 topic. - LOG1 = 0xa1, - /// Makes a log entry, 2 topics. - LOG2 = 0xa2, - /// Makes a log entry, 3 topics. - LOG3 = 0xa3, - /// Makes a log entry, 4 topics. - LOG4 = 0xa4, - - /// create a new account with associated code - CREATE = 0xf0, - /// message-call into an account - CALL = 0xf1, - /// message-call with another account's code only - CALLCODE = 0xf2, - /// halt execution returning output data - RETURN = 0xf3, - /// like CALLCODE but keeps caller's value and sender - DELEGATECALL = 0xf4, - /// create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160 - CREATE2 = 0xfb, - /// stop execution and revert state changes. Return output data. - REVERT = 0xfd, - /// like CALL but it does not take value, nor modify the state - STATICCALL = 0xfa, - /// halt execution and register account for later deletion - SUICIDE = 0xff, +macro_rules! enum_with_from_u8 { + ( + $( #[$enum_attr:meta] )* + pub enum $name:ident { + $( $( #[$variant_attr:meta] )* $variant:ident = $discriminator:expr ),+, + } + ) => { + $( #[$enum_attr] )* + pub enum $name { + $( $( #[$variant_attr] )* $variant = $discriminator ),+, + } + + impl $name { + #[doc = "Convert from u8 to the given enum"] + pub fn from_u8(value: u8) -> Option { + match value { + $( $discriminator => Some($variant) ),+, + _ => None, + } + } + } + }; } -impl Instruction { - pub fn from_u8(value: u8) -> Option { - match value { - 0x00 => Some(Instruction::STOP), - 0x01 => Some(Instruction::ADD), - 0x02 => Some(Instruction::MUL), - 0x03 => Some(Instruction::SUB), - 0x04 => Some(Instruction::DIV), - 0x05 => Some(Instruction::SDIV), - 0x06 => Some(Instruction::MOD), - 0x07 => Some(Instruction::SMOD), - 0x08 => Some(Instruction::ADDMOD), - 0x09 => Some(Instruction::MULMOD), - 0x0a => Some(Instruction::EXP), - 0x0b => Some(Instruction::SIGNEXTEND), - - 0x10 => Some(Instruction::LT), - 0x11 => Some(Instruction::GT), - 0x12 => Some(Instruction::SLT), - 0x13 => Some(Instruction::SGT), - 0x14 => Some(Instruction::EQ), - 0x15 => Some(Instruction::ISZERO), - 0x16 => Some(Instruction::AND), - 0x17 => Some(Instruction::OR), - 0x18 => Some(Instruction::XOR), - 0x19 => Some(Instruction::NOT), - 0x1a => Some(Instruction::BYTE), - 0x1b => Some(Instruction::SHL), - 0x1c => Some(Instruction::SHR), - 0x1d => Some(Instruction::SAR), - - 0x20 => Some(Instruction::SHA3), - - 0x30 => Some(Instruction::ADDRESS), - 0x31 => Some(Instruction::BALANCE), - 0x32 => Some(Instruction::ORIGIN), - 0x33 => Some(Instruction::CALLER), - 0x34 => Some(Instruction::CALLVALUE), - 0x35 => Some(Instruction::CALLDATALOAD), - 0x36 => Some(Instruction::CALLDATASIZE), - 0x37 => Some(Instruction::CALLDATACOPY), - 0x38 => Some(Instruction::CODESIZE), - 0x39 => Some(Instruction::CODECOPY), - 0x3a => Some(Instruction::GASPRICE), - 0x3b => Some(Instruction::EXTCODESIZE), - 0x3c => Some(Instruction::EXTCODECOPY), - 0x3d => Some(Instruction::RETURNDATASIZE), - 0x3e => Some(Instruction::RETURNDATACOPY), - - 0x40 => Some(Instruction::BLOCKHASH), - 0x41 => Some(Instruction::COINBASE), - 0x42 => Some(Instruction::TIMESTAMP), - 0x43 => Some(Instruction::NUMBER), - 0x44 => Some(Instruction::DIFFICULTY), - 0x45 => Some(Instruction::GASLIMIT), - - 0x50 => Some(Instruction::POP), - 0x51 => Some(Instruction::MLOAD), - 0x52 => Some(Instruction::MSTORE), - 0x53 => Some(Instruction::MSTORE8), - 0x54 => Some(Instruction::SLOAD), - 0x55 => Some(Instruction::SSTORE), - 0x56 => Some(Instruction::JUMP), - 0x57 => Some(Instruction::JUMPI), - 0x58 => Some(Instruction::PC), - 0x59 => Some(Instruction::MSIZE), - 0x5a => Some(Instruction::GAS), - 0x5b => Some(Instruction::JUMPDEST), - - 0x60 => Some(Instruction::PUSH1), - 0x61 => Some(Instruction::PUSH2), - 0x62 => Some(Instruction::PUSH3), - 0x63 => Some(Instruction::PUSH4), - 0x64 => Some(Instruction::PUSH5), - 0x65 => Some(Instruction::PUSH6), - 0x66 => Some(Instruction::PUSH7), - 0x67 => Some(Instruction::PUSH8), - 0x68 => Some(Instruction::PUSH9), - 0x69 => Some(Instruction::PUSH10), - 0x6a => Some(Instruction::PUSH11), - 0x6b => Some(Instruction::PUSH12), - 0x6c => Some(Instruction::PUSH13), - 0x6d => Some(Instruction::PUSH14), - 0x6e => Some(Instruction::PUSH15), - 0x6f => Some(Instruction::PUSH16), - 0x70 => Some(Instruction::PUSH17), - 0x71 => Some(Instruction::PUSH18), - 0x72 => Some(Instruction::PUSH19), - 0x73 => Some(Instruction::PUSH20), - 0x74 => Some(Instruction::PUSH21), - 0x75 => Some(Instruction::PUSH22), - 0x76 => Some(Instruction::PUSH23), - 0x77 => Some(Instruction::PUSH24), - 0x78 => Some(Instruction::PUSH25), - 0x79 => Some(Instruction::PUSH26), - 0x7a => Some(Instruction::PUSH27), - 0x7b => Some(Instruction::PUSH28), - 0x7c => Some(Instruction::PUSH29), - 0x7d => Some(Instruction::PUSH30), - 0x7e => Some(Instruction::PUSH31), - 0x7f => Some(Instruction::PUSH32), - - 0x80 => Some(Instruction::DUP1), - 0x81 => Some(Instruction::DUP2), - 0x82 => Some(Instruction::DUP3), - 0x83 => Some(Instruction::DUP4), - 0x84 => Some(Instruction::DUP5), - 0x85 => Some(Instruction::DUP6), - 0x86 => Some(Instruction::DUP7), - 0x87 => Some(Instruction::DUP8), - 0x88 => Some(Instruction::DUP9), - 0x89 => Some(Instruction::DUP10), - 0x8a => Some(Instruction::DUP11), - 0x8b => Some(Instruction::DUP12), - 0x8c => Some(Instruction::DUP13), - 0x8d => Some(Instruction::DUP14), - 0x8e => Some(Instruction::DUP15), - 0x8f => Some(Instruction::DUP16), - - 0x90 => Some(Instruction::SWAP1), - 0x91 => Some(Instruction::SWAP2), - 0x92 => Some(Instruction::SWAP3), - 0x93 => Some(Instruction::SWAP4), - 0x94 => Some(Instruction::SWAP5), - 0x95 => Some(Instruction::SWAP6), - 0x96 => Some(Instruction::SWAP7), - 0x97 => Some(Instruction::SWAP8), - 0x98 => Some(Instruction::SWAP9), - 0x99 => Some(Instruction::SWAP10), - 0x9a => Some(Instruction::SWAP11), - 0x9b => Some(Instruction::SWAP12), - 0x9c => Some(Instruction::SWAP13), - 0x9d => Some(Instruction::SWAP14), - 0x9e => Some(Instruction::SWAP15), - 0x9f => Some(Instruction::SWAP16), - - 0xa0 => Some(Instruction::LOG0), - 0xa1 => Some(Instruction::LOG1), - 0xa2 => Some(Instruction::LOG2), - 0xa3 => Some(Instruction::LOG3), - 0xa4 => Some(Instruction::LOG4), - - 0xf0 => Some(Instruction::CREATE), - 0xf1 => Some(Instruction::CALL), - 0xf2 => Some(Instruction::CALLCODE), - 0xf3 => Some(Instruction::RETURN), - 0xf4 => Some(Instruction::DELEGATECALL), - 0xfb => Some(Instruction::CREATE2), - 0xfd => Some(Instruction::REVERT), - 0xfa => Some(Instruction::STATICCALL), - 0xff => Some(Instruction::SUICIDE), - - _ => None, - } +enum_with_from_u8! { + #[doc = "Virtual machine bytecode instruction."] + #[repr(u8)] + #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug)] + pub enum Instruction { + #[doc = "halts execution"] + STOP = 0x00, + #[doc = "addition operation"] + ADD = 0x01, + #[doc = "mulitplication operation"] + MUL = 0x02, + #[doc = "subtraction operation"] + SUB = 0x03, + #[doc = "integer division operation"] + DIV = 0x04, + #[doc = "signed integer division operation"] + SDIV = 0x05, + #[doc = "modulo remainder operation"] + MOD = 0x06, + #[doc = "signed modulo remainder operation"] + SMOD = 0x07, + #[doc = "unsigned modular addition"] + ADDMOD = 0x08, + #[doc = "unsigned modular multiplication"] + MULMOD = 0x09, + #[doc = "exponential operation"] + EXP = 0x0a, + #[doc = "extend length of signed integer"] + SIGNEXTEND = 0x0b, + + #[doc = "less-than comparision"] + LT = 0x10, + #[doc = "greater-than comparision"] + GT = 0x11, + #[doc = "signed less-than comparision"] + SLT = 0x12, + #[doc = "signed greater-than comparision"] + SGT = 0x13, + #[doc = "equality comparision"] + EQ = 0x14, + #[doc = "simple not operator"] + ISZERO = 0x15, + #[doc = "bitwise AND operation"] + AND = 0x16, + #[doc = "bitwise OR operation"] + OR = 0x17, + #[doc = "bitwise XOR operation"] + XOR = 0x18, + #[doc = "bitwise NOT opertation"] + NOT = 0x19, + #[doc = "retrieve single byte from word"] + BYTE = 0x1a, + #[doc = "shift left operation"] + SHL = 0x1b, + #[doc = "logical shift right operation"] + SHR = 0x1c, + #[doc = "arithmetic shift right operation"] + SAR = 0x1d, + + #[doc = "compute SHA3-256 hash"] + SHA3 = 0x20, + + #[doc = "get address of currently executing account"] + ADDRESS = 0x30, + #[doc = "get balance of the given account"] + BALANCE = 0x31, + #[doc = "get execution origination address"] + ORIGIN = 0x32, + #[doc = "get caller address"] + CALLER = 0x33, + #[doc = "get deposited value by the instruction/transaction responsible for this execution"] + CALLVALUE = 0x34, + #[doc = "get input data of current environment"] + CALLDATALOAD = 0x35, + #[doc = "get size of input data in current environment"] + CALLDATASIZE = 0x36, + #[doc = "copy input data in current environment to memory"] + CALLDATACOPY = 0x37, + #[doc = "get size of code running in current environment"] + CODESIZE = 0x38, + #[doc = "copy code running in current environment to memory"] + CODECOPY = 0x39, + #[doc = "get price of gas in current environment"] + GASPRICE = 0x3a, + #[doc = "get external code size (from another contract)"] + EXTCODESIZE = 0x3b, + #[doc = "copy external code (from another contract)"] + EXTCODECOPY = 0x3c, + #[doc = "get the size of the return data buffer for the last call"] + RETURNDATASIZE = 0x3d, + #[doc = "copy return data buffer to memory"] + RETURNDATACOPY = 0x3e, + + #[doc = "get hash of most recent complete block"] + BLOCKHASH = 0x40, + #[doc = "get the block's coinbase address"] + COINBASE = 0x41, + #[doc = "get the block's timestamp"] + TIMESTAMP = 0x42, + #[doc = "get the block's number"] + NUMBER = 0x43, + #[doc = "get the block's difficulty"] + DIFFICULTY = 0x44, + #[doc = "get the block's gas limit"] + GASLIMIT = 0x45, + + #[doc = "remove item from stack"] + POP = 0x50, + #[doc = "load word from memory"] + MLOAD = 0x51, + #[doc = "save word to memory"] + MSTORE = 0x52, + #[doc = "save byte to memory"] + MSTORE8 = 0x53, + #[doc = "load word from storage"] + SLOAD = 0x54, + #[doc = "save word to storage"] + SSTORE = 0x55, + #[doc = "alter the program counter"] + JUMP = 0x56, + #[doc = "conditionally alter the program counter"] + JUMPI = 0x57, + #[doc = "get the program counter"] + PC = 0x58, + #[doc = "get the size of active memory"] + MSIZE = 0x59, + #[doc = "get the amount of available gas"] + GAS = 0x5a, + #[doc = "set a potential jump destination"] + JUMPDEST = 0x5b, + + #[doc = "place 1 byte item on stack"] + PUSH1 = 0x60, + #[doc = "place 2 byte item on stack"] + PUSH2 = 0x61, + #[doc = "place 3 byte item on stack"] + PUSH3 = 0x62, + #[doc = "place 4 byte item on stack"] + PUSH4 = 0x63, + #[doc = "place 5 byte item on stack"] + PUSH5 = 0x64, + #[doc = "place 6 byte item on stack"] + PUSH6 = 0x65, + #[doc = "place 7 byte item on stack"] + PUSH7 = 0x66, + #[doc = "place 8 byte item on stack"] + PUSH8 = 0x67, + #[doc = "place 9 byte item on stack"] + PUSH9 = 0x68, + #[doc = "place 10 byte item on stack"] + PUSH10 = 0x69, + #[doc = "place 11 byte item on stack"] + PUSH11 = 0x6a, + #[doc = "place 12 byte item on stack"] + PUSH12 = 0x6b, + #[doc = "place 13 byte item on stack"] + PUSH13 = 0x6c, + #[doc = "place 14 byte item on stack"] + PUSH14 = 0x6d, + #[doc = "place 15 byte item on stack"] + PUSH15 = 0x6e, + #[doc = "place 16 byte item on stack"] + PUSH16 = 0x6f, + #[doc = "place 17 byte item on stack"] + PUSH17 = 0x70, + #[doc = "place 18 byte item on stack"] + PUSH18 = 0x71, + #[doc = "place 19 byte item on stack"] + PUSH19 = 0x72, + #[doc = "place 20 byte item on stack"] + PUSH20 = 0x73, + #[doc = "place 21 byte item on stack"] + PUSH21 = 0x74, + #[doc = "place 22 byte item on stack"] + PUSH22 = 0x75, + #[doc = "place 23 byte item on stack"] + PUSH23 = 0x76, + #[doc = "place 24 byte item on stack"] + PUSH24 = 0x77, + #[doc = "place 25 byte item on stack"] + PUSH25 = 0x78, + #[doc = "place 26 byte item on stack"] + PUSH26 = 0x79, + #[doc = "place 27 byte item on stack"] + PUSH27 = 0x7a, + #[doc = "place 28 byte item on stack"] + PUSH28 = 0x7b, + #[doc = "place 29 byte item on stack"] + PUSH29 = 0x7c, + #[doc = "place 30 byte item on stack"] + PUSH30 = 0x7d, + #[doc = "place 31 byte item on stack"] + PUSH31 = 0x7e, + #[doc = "place 32 byte item on stack"] + PUSH32 = 0x7f, + + #[doc = "copies the highest item in the stack to the top of the stack"] + DUP1 = 0x80, + #[doc = "copies the second highest item in the stack to the top of the stack"] + DUP2 = 0x81, + #[doc = "copies the third highest item in the stack to the top of the stack"] + DUP3 = 0x82, + #[doc = "copies the 4th highest item in the stack to the top of the stack"] + DUP4 = 0x83, + #[doc = "copies the 5th highest item in the stack to the top of the stack"] + DUP5 = 0x84, + #[doc = "copies the 6th highest item in the stack to the top of the stack"] + DUP6 = 0x85, + #[doc = "copies the 7th highest item in the stack to the top of the stack"] + DUP7 = 0x86, + #[doc = "copies the 8th highest item in the stack to the top of the stack"] + DUP8 = 0x87, + #[doc = "copies the 9th highest item in the stack to the top of the stack"] + DUP9 = 0x88, + #[doc = "copies the 10th highest item in the stack to the top of the stack"] + DUP10 = 0x89, + #[doc = "copies the 11th highest item in the stack to the top of the stack"] + DUP11 = 0x8a, + #[doc = "copies the 12th highest item in the stack to the top of the stack"] + DUP12 = 0x8b, + #[doc = "copies the 13th highest item in the stack to the top of the stack"] + DUP13 = 0x8c, + #[doc = "copies the 14th highest item in the stack to the top of the stack"] + DUP14 = 0x8d, + #[doc = "copies the 15th highest item in the stack to the top of the stack"] + DUP15 = 0x8e, + #[doc = "copies the 16th highest item in the stack to the top of the stack"] + DUP16 = 0x8f, + + #[doc = "swaps the highest and second highest value on the stack"] + SWAP1 = 0x90, + #[doc = "swaps the highest and third highest value on the stack"] + SWAP2 = 0x91, + #[doc = "swaps the highest and 4th highest value on the stack"] + SWAP3 = 0x92, + #[doc = "swaps the highest and 5th highest value on the stack"] + SWAP4 = 0x93, + #[doc = "swaps the highest and 6th highest value on the stack"] + SWAP5 = 0x94, + #[doc = "swaps the highest and 7th highest value on the stack"] + SWAP6 = 0x95, + #[doc = "swaps the highest and 8th highest value on the stack"] + SWAP7 = 0x96, + #[doc = "swaps the highest and 9th highest value on the stack"] + SWAP8 = 0x97, + #[doc = "swaps the highest and 10th highest value on the stack"] + SWAP9 = 0x98, + #[doc = "swaps the highest and 11th highest value on the stack"] + SWAP10 = 0x99, + #[doc = "swaps the highest and 12th highest value on the stack"] + SWAP11 = 0x9a, + #[doc = "swaps the highest and 13th highest value on the stack"] + SWAP12 = 0x9b, + #[doc = "swaps the highest and 14th highest value on the stack"] + SWAP13 = 0x9c, + #[doc = "swaps the highest and 15th highest value on the stack"] + SWAP14 = 0x9d, + #[doc = "swaps the highest and 16th highest value on the stack"] + SWAP15 = 0x9e, + #[doc = "swaps the highest and 17th highest value on the stack"] + SWAP16 = 0x9f, + + #[doc = "Makes a log entry, no topics."] + LOG0 = 0xa0, + #[doc = "Makes a log entry, 1 topic."] + LOG1 = 0xa1, + #[doc = "Makes a log entry, 2 topics."] + LOG2 = 0xa2, + #[doc = "Makes a log entry, 3 topics."] + LOG3 = 0xa3, + #[doc = "Makes a log entry, 4 topics."] + LOG4 = 0xa4, + + #[doc = "create a new account with associated code"] + CREATE = 0xf0, + #[doc = "message-call into an account"] + CALL = 0xf1, + #[doc = "message-call with another account's code only"] + CALLCODE = 0xf2, + #[doc = "halt execution returning output data"] + RETURN = 0xf3, + #[doc = "like CALLCODE but keeps caller's value and sender"] + DELEGATECALL = 0xf4, + #[doc = "create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160"] + CREATE2 = 0xfb, + #[doc = "stop execution and revert state changes. Return output data."] + REVERT = 0xfd, + #[doc = "like CALL but it does not take value, nor modify the state"] + STATICCALL = 0xfa, + #[doc = "halt execution and register account for later deletion"] + SUICIDE = 0xff, } +} +impl Instruction { /// Returns true if given instruction is `PUSHN` instruction. pub fn is_push(&self) -> bool { *self >= PUSH1 && *self <= PUSH32 From 75cb1457660c8a4927597fca5e605b97190c2db7 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Jun 2018 17:06:33 +0800 Subject: [PATCH 06/10] Use single space instead of multiple tabs to avoid formatting issue --- ethcore/evm/src/instructions.rs | 276 ++++++++++++++++---------------- 1 file changed, 138 insertions(+), 138 deletions(-) diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index f2680c8bcb4..52cd29c112f 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -455,144 +455,144 @@ lazy_static! { /// Static instruction table. static ref INSTRUCTIONS: [Option; 0x100] = { let mut arr = [None; 0x100]; - arr[STOP as usize] = Some(InstructionInfo::new("STOP", 0, 0, GasPriceTier::Zero)); - arr[ADD as usize] = Some(InstructionInfo::new("ADD", 2, 1, GasPriceTier::VeryLow)); - arr[SUB as usize] = Some(InstructionInfo::new("SUB", 2, 1, GasPriceTier::VeryLow)); - arr[MUL as usize] = Some(InstructionInfo::new("MUL", 2, 1, GasPriceTier::Low)); - arr[DIV as usize] = Some(InstructionInfo::new("DIV", 2, 1, GasPriceTier::Low)); - arr[SDIV as usize] = Some(InstructionInfo::new("SDIV", 2, 1, GasPriceTier::Low)); - arr[MOD as usize] = Some(InstructionInfo::new("MOD", 2, 1, GasPriceTier::Low)); - arr[SMOD as usize] = Some(InstructionInfo::new("SMOD", 2, 1, GasPriceTier::Low)); - arr[EXP as usize] = Some(InstructionInfo::new("EXP", 2, 1, GasPriceTier::Special)); - arr[NOT as usize] = Some(InstructionInfo::new("NOT", 1, 1, GasPriceTier::VeryLow)); - arr[LT as usize] = Some(InstructionInfo::new("LT", 2, 1, GasPriceTier::VeryLow)); - arr[GT as usize] = Some(InstructionInfo::new("GT", 2, 1, GasPriceTier::VeryLow)); - arr[SLT as usize] = Some(InstructionInfo::new("SLT", 2, 1, GasPriceTier::VeryLow)); - arr[SGT as usize] = Some(InstructionInfo::new("SGT", 2, 1, GasPriceTier::VeryLow)); - arr[EQ as usize] = Some(InstructionInfo::new("EQ", 2, 1, GasPriceTier::VeryLow)); - arr[ISZERO as usize] = Some(InstructionInfo::new("ISZERO", 1, 1, GasPriceTier::VeryLow)); - arr[AND as usize] = Some(InstructionInfo::new("AND", 2, 1, GasPriceTier::VeryLow)); - arr[OR as usize] = Some(InstructionInfo::new("OR", 2, 1, GasPriceTier::VeryLow)); - arr[XOR as usize] = Some(InstructionInfo::new("XOR", 2, 1, GasPriceTier::VeryLow)); - arr[BYTE as usize] = Some(InstructionInfo::new("BYTE", 2, 1, GasPriceTier::VeryLow)); - arr[SHL as usize] = Some(InstructionInfo::new("SHL", 2, 1, GasPriceTier::VeryLow)); - arr[SHR as usize] = Some(InstructionInfo::new("SHR", 2, 1, GasPriceTier::VeryLow)); - arr[SAR as usize] = Some(InstructionInfo::new("SAR", 2, 1, GasPriceTier::VeryLow)); - arr[ADDMOD as usize] = Some(InstructionInfo::new("ADDMOD", 3, 1, GasPriceTier::Mid)); - arr[MULMOD as usize] = Some(InstructionInfo::new("MULMOD", 3, 1, GasPriceTier::Mid)); - arr[SIGNEXTEND as usize] = Some(InstructionInfo::new("SIGNEXTEND", 2, 1, GasPriceTier::Low)); - arr[RETURNDATASIZE as usize] = Some(InstructionInfo::new("RETURNDATASIZE", 0, 1, GasPriceTier::Base)); - arr[RETURNDATACOPY as usize] = Some(InstructionInfo::new("RETURNDATACOPY", 3, 0, GasPriceTier::VeryLow)); - arr[SHA3 as usize] = Some(InstructionInfo::new("SHA3", 2, 1, GasPriceTier::Special)); - arr[ADDRESS as usize] = Some(InstructionInfo::new("ADDRESS", 0, 1, GasPriceTier::Base)); - arr[BALANCE as usize] = Some(InstructionInfo::new("BALANCE", 1, 1, GasPriceTier::Special)); - arr[ORIGIN as usize] = Some(InstructionInfo::new("ORIGIN", 0, 1, GasPriceTier::Base)); - arr[CALLER as usize] = Some(InstructionInfo::new("CALLER", 0, 1, GasPriceTier::Base)); - arr[CALLVALUE as usize] = Some(InstructionInfo::new("CALLVALUE", 0, 1, GasPriceTier::Base)); - arr[CALLDATALOAD as usize] = Some(InstructionInfo::new("CALLDATALOAD", 1, 1, GasPriceTier::VeryLow)); - arr[CALLDATASIZE as usize] = Some(InstructionInfo::new("CALLDATASIZE", 0, 1, GasPriceTier::Base)); - arr[CALLDATACOPY as usize] = Some(InstructionInfo::new("CALLDATACOPY", 3, 0, GasPriceTier::VeryLow)); - arr[CODESIZE as usize] = Some(InstructionInfo::new("CODESIZE", 0, 1, GasPriceTier::Base)); - arr[CODECOPY as usize] = Some(InstructionInfo::new("CODECOPY", 3, 0, GasPriceTier::VeryLow)); - arr[GASPRICE as usize] = Some(InstructionInfo::new("GASPRICE", 0, 1, GasPriceTier::Base)); - arr[EXTCODESIZE as usize] = Some(InstructionInfo::new("EXTCODESIZE", 1, 1, GasPriceTier::Special)); - arr[EXTCODECOPY as usize] = Some(InstructionInfo::new("EXTCODECOPY", 4, 0, GasPriceTier::Special)); - arr[BLOCKHASH as usize] = Some(InstructionInfo::new("BLOCKHASH", 1, 1, GasPriceTier::Ext)); - arr[COINBASE as usize] = Some(InstructionInfo::new("COINBASE", 0, 1, GasPriceTier::Base)); - arr[TIMESTAMP as usize] = Some(InstructionInfo::new("TIMESTAMP", 0, 1, GasPriceTier::Base)); - arr[NUMBER as usize] = Some(InstructionInfo::new("NUMBER", 0, 1, GasPriceTier::Base)); - arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base)); - arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base)); - arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base)); - arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow)); - arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow)); - arr[MSTORE8 as usize] = Some(InstructionInfo::new("MSTORE8", 2, 0, GasPriceTier::VeryLow)); - arr[SLOAD as usize] = Some(InstructionInfo::new("SLOAD", 1, 1, GasPriceTier::Special)); - arr[SSTORE as usize] = Some(InstructionInfo::new("SSTORE", 2, 0, GasPriceTier::Special)); - arr[JUMP as usize] = Some(InstructionInfo::new("JUMP", 1, 0, GasPriceTier::Mid)); - arr[JUMPI as usize] = Some(InstructionInfo::new("JUMPI", 2, 0, GasPriceTier::High)); - arr[PC as usize] = Some(InstructionInfo::new("PC", 0, 1, GasPriceTier::Base)); - arr[MSIZE as usize] = Some(InstructionInfo::new("MSIZE", 0, 1, GasPriceTier::Base)); - arr[GAS as usize] = Some(InstructionInfo::new("GAS", 0, 1, GasPriceTier::Base)); - arr[JUMPDEST as usize] = Some(InstructionInfo::new("JUMPDEST", 0, 0, GasPriceTier::Special)); - arr[PUSH1 as usize] = Some(InstructionInfo::new("PUSH1", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH2 as usize] = Some(InstructionInfo::new("PUSH2", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH3 as usize] = Some(InstructionInfo::new("PUSH3", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH4 as usize] = Some(InstructionInfo::new("PUSH4", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH5 as usize] = Some(InstructionInfo::new("PUSH5", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH6 as usize] = Some(InstructionInfo::new("PUSH6", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH7 as usize] = Some(InstructionInfo::new("PUSH7", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH8 as usize] = Some(InstructionInfo::new("PUSH8", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH9 as usize] = Some(InstructionInfo::new("PUSH9", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH10 as usize] = Some(InstructionInfo::new("PUSH10", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH11 as usize] = Some(InstructionInfo::new("PUSH11", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH12 as usize] = Some(InstructionInfo::new("PUSH12", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH13 as usize] = Some(InstructionInfo::new("PUSH13", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH14 as usize] = Some(InstructionInfo::new("PUSH14", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH15 as usize] = Some(InstructionInfo::new("PUSH15", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH16 as usize] = Some(InstructionInfo::new("PUSH16", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH17 as usize] = Some(InstructionInfo::new("PUSH17", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH18 as usize] = Some(InstructionInfo::new("PUSH18", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH19 as usize] = Some(InstructionInfo::new("PUSH19", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH20 as usize] = Some(InstructionInfo::new("PUSH20", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH21 as usize] = Some(InstructionInfo::new("PUSH21", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH22 as usize] = Some(InstructionInfo::new("PUSH22", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH23 as usize] = Some(InstructionInfo::new("PUSH23", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH24 as usize] = Some(InstructionInfo::new("PUSH24", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH25 as usize] = Some(InstructionInfo::new("PUSH25", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH26 as usize] = Some(InstructionInfo::new("PUSH26", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH27 as usize] = Some(InstructionInfo::new("PUSH27", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH28 as usize] = Some(InstructionInfo::new("PUSH28", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH29 as usize] = Some(InstructionInfo::new("PUSH29", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH30 as usize] = Some(InstructionInfo::new("PUSH30", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH31 as usize] = Some(InstructionInfo::new("PUSH31", 0, 1, GasPriceTier::VeryLow)); - arr[PUSH32 as usize] = Some(InstructionInfo::new("PUSH32", 0, 1, GasPriceTier::VeryLow)); - arr[DUP1 as usize] = Some(InstructionInfo::new("DUP1", 1, 2, GasPriceTier::VeryLow)); - arr[DUP2 as usize] = Some(InstructionInfo::new("DUP2", 2, 3, GasPriceTier::VeryLow)); - arr[DUP3 as usize] = Some(InstructionInfo::new("DUP3", 3, 4, GasPriceTier::VeryLow)); - arr[DUP4 as usize] = Some(InstructionInfo::new("DUP4", 4, 5, GasPriceTier::VeryLow)); - arr[DUP5 as usize] = Some(InstructionInfo::new("DUP5", 5, 6, GasPriceTier::VeryLow)); - arr[DUP6 as usize] = Some(InstructionInfo::new("DUP6", 6, 7, GasPriceTier::VeryLow)); - arr[DUP7 as usize] = Some(InstructionInfo::new("DUP7", 7, 8, GasPriceTier::VeryLow)); - arr[DUP8 as usize] = Some(InstructionInfo::new("DUP8", 8, 9, GasPriceTier::VeryLow)); - arr[DUP9 as usize] = Some(InstructionInfo::new("DUP9", 9, 10, GasPriceTier::VeryLow)); - arr[DUP10 as usize] = Some(InstructionInfo::new("DUP10", 10, 11, GasPriceTier::VeryLow)); - arr[DUP11 as usize] = Some(InstructionInfo::new("DUP11", 11, 12, GasPriceTier::VeryLow)); - arr[DUP12 as usize] = Some(InstructionInfo::new("DUP12", 12, 13, GasPriceTier::VeryLow)); - arr[DUP13 as usize] = Some(InstructionInfo::new("DUP13", 13, 14, GasPriceTier::VeryLow)); - arr[DUP14 as usize] = Some(InstructionInfo::new("DUP14", 14, 15, GasPriceTier::VeryLow)); - arr[DUP15 as usize] = Some(InstructionInfo::new("DUP15", 15, 16, GasPriceTier::VeryLow)); - arr[DUP16 as usize] = Some(InstructionInfo::new("DUP16", 16, 17, GasPriceTier::VeryLow)); - arr[SWAP1 as usize] = Some(InstructionInfo::new("SWAP1", 2, 2, GasPriceTier::VeryLow)); - arr[SWAP2 as usize] = Some(InstructionInfo::new("SWAP2", 3, 3, GasPriceTier::VeryLow)); - arr[SWAP3 as usize] = Some(InstructionInfo::new("SWAP3", 4, 4, GasPriceTier::VeryLow)); - arr[SWAP4 as usize] = Some(InstructionInfo::new("SWAP4", 5, 5, GasPriceTier::VeryLow)); - arr[SWAP5 as usize] = Some(InstructionInfo::new("SWAP5", 6, 6, GasPriceTier::VeryLow)); - arr[SWAP6 as usize] = Some(InstructionInfo::new("SWAP6", 7, 7, GasPriceTier::VeryLow)); - arr[SWAP7 as usize] = Some(InstructionInfo::new("SWAP7", 8, 8, GasPriceTier::VeryLow)); - arr[SWAP8 as usize] = Some(InstructionInfo::new("SWAP8", 9, 9, GasPriceTier::VeryLow)); - arr[SWAP9 as usize] = Some(InstructionInfo::new("SWAP9", 10, 10, GasPriceTier::VeryLow)); - arr[SWAP10 as usize] = Some(InstructionInfo::new("SWAP10", 11, 11, GasPriceTier::VeryLow)); - arr[SWAP11 as usize] = Some(InstructionInfo::new("SWAP11", 12, 12, GasPriceTier::VeryLow)); - arr[SWAP12 as usize] = Some(InstructionInfo::new("SWAP12", 13, 13, GasPriceTier::VeryLow)); - arr[SWAP13 as usize] = Some(InstructionInfo::new("SWAP13", 14, 14, GasPriceTier::VeryLow)); - arr[SWAP14 as usize] = Some(InstructionInfo::new("SWAP14", 15, 15, GasPriceTier::VeryLow)); - arr[SWAP15 as usize] = Some(InstructionInfo::new("SWAP15", 16, 16, GasPriceTier::VeryLow)); - arr[SWAP16 as usize] = Some(InstructionInfo::new("SWAP16", 17, 17, GasPriceTier::VeryLow)); - arr[LOG0 as usize] = Some(InstructionInfo::new("LOG0", 2, 0, GasPriceTier::Special)); - arr[LOG1 as usize] = Some(InstructionInfo::new("LOG1", 3, 0, GasPriceTier::Special)); - arr[LOG2 as usize] = Some(InstructionInfo::new("LOG2", 4, 0, GasPriceTier::Special)); - arr[LOG3 as usize] = Some(InstructionInfo::new("LOG3", 5, 0, GasPriceTier::Special)); - arr[LOG4 as usize] = Some(InstructionInfo::new("LOG4", 6, 0, GasPriceTier::Special)); - arr[CREATE as usize] = Some(InstructionInfo::new("CREATE", 3, 1, GasPriceTier::Special)); - arr[CALL as usize] = Some(InstructionInfo::new("CALL", 7, 1, GasPriceTier::Special)); - arr[CALLCODE as usize] = Some(InstructionInfo::new("CALLCODE", 7, 1, GasPriceTier::Special)); - arr[RETURN as usize] = Some(InstructionInfo::new("RETURN", 2, 0, GasPriceTier::Zero)); - arr[DELEGATECALL as usize] = Some(InstructionInfo::new("DELEGATECALL", 6, 1, GasPriceTier::Special)); - arr[STATICCALL as usize] = Some(InstructionInfo::new("STATICCALL", 6, 1, GasPriceTier::Special)); - arr[SUICIDE as usize] = Some(InstructionInfo::new("SUICIDE", 1, 0, GasPriceTier::Special)); - arr[CREATE2 as usize] = Some(InstructionInfo::new("CREATE2", 3, 1, GasPriceTier::Special)); - arr[REVERT as usize] = Some(InstructionInfo::new("REVERT", 2, 0, GasPriceTier::Zero)); + arr[STOP as usize] = Some(InstructionInfo::new("STOP", 0, 0, GasPriceTier::Zero)); + arr[ADD as usize] = Some(InstructionInfo::new("ADD", 2, 1, GasPriceTier::VeryLow)); + arr[SUB as usize] = Some(InstructionInfo::new("SUB", 2, 1, GasPriceTier::VeryLow)); + arr[MUL as usize] = Some(InstructionInfo::new("MUL", 2, 1, GasPriceTier::Low)); + arr[DIV as usize] = Some(InstructionInfo::new("DIV", 2, 1, GasPriceTier::Low)); + arr[SDIV as usize] = Some(InstructionInfo::new("SDIV", 2, 1, GasPriceTier::Low)); + arr[MOD as usize] = Some(InstructionInfo::new("MOD", 2, 1, GasPriceTier::Low)); + arr[SMOD as usize] = Some(InstructionInfo::new("SMOD", 2, 1, GasPriceTier::Low)); + arr[EXP as usize] = Some(InstructionInfo::new("EXP", 2, 1, GasPriceTier::Special)); + arr[NOT as usize] = Some(InstructionInfo::new("NOT", 1, 1, GasPriceTier::VeryLow)); + arr[LT as usize] = Some(InstructionInfo::new("LT", 2, 1, GasPriceTier::VeryLow)); + arr[GT as usize] = Some(InstructionInfo::new("GT", 2, 1, GasPriceTier::VeryLow)); + arr[SLT as usize] = Some(InstructionInfo::new("SLT", 2, 1, GasPriceTier::VeryLow)); + arr[SGT as usize] = Some(InstructionInfo::new("SGT", 2, 1, GasPriceTier::VeryLow)); + arr[EQ as usize] = Some(InstructionInfo::new("EQ", 2, 1, GasPriceTier::VeryLow)); + arr[ISZERO as usize] = Some(InstructionInfo::new("ISZERO", 1, 1, GasPriceTier::VeryLow)); + arr[AND as usize] = Some(InstructionInfo::new("AND", 2, 1, GasPriceTier::VeryLow)); + arr[OR as usize] = Some(InstructionInfo::new("OR", 2, 1, GasPriceTier::VeryLow)); + arr[XOR as usize] = Some(InstructionInfo::new("XOR", 2, 1, GasPriceTier::VeryLow)); + arr[BYTE as usize] = Some(InstructionInfo::new("BYTE", 2, 1, GasPriceTier::VeryLow)); + arr[SHL as usize] = Some(InstructionInfo::new("SHL", 2, 1, GasPriceTier::VeryLow)); + arr[SHR as usize] = Some(InstructionInfo::new("SHR", 2, 1, GasPriceTier::VeryLow)); + arr[SAR as usize] = Some(InstructionInfo::new("SAR", 2, 1, GasPriceTier::VeryLow)); + arr[ADDMOD as usize] = Some(InstructionInfo::new("ADDMOD", 3, 1, GasPriceTier::Mid)); + arr[MULMOD as usize] = Some(InstructionInfo::new("MULMOD", 3, 1, GasPriceTier::Mid)); + arr[SIGNEXTEND as usize] = Some(InstructionInfo::new("SIGNEXTEND", 2, 1, GasPriceTier::Low)); + arr[RETURNDATASIZE as usize] = Some(InstructionInfo::new("RETURNDATASIZE", 0, 1, GasPriceTier::Base)); + arr[RETURNDATACOPY as usize] = Some(InstructionInfo::new("RETURNDATACOPY", 3, 0, GasPriceTier::VeryLow)); + arr[SHA3 as usize] = Some(InstructionInfo::new("SHA3", 2, 1, GasPriceTier::Special)); + arr[ADDRESS as usize] = Some(InstructionInfo::new("ADDRESS", 0, 1, GasPriceTier::Base)); + arr[BALANCE as usize] = Some(InstructionInfo::new("BALANCE", 1, 1, GasPriceTier::Special)); + arr[ORIGIN as usize] = Some(InstructionInfo::new("ORIGIN", 0, 1, GasPriceTier::Base)); + arr[CALLER as usize] = Some(InstructionInfo::new("CALLER", 0, 1, GasPriceTier::Base)); + arr[CALLVALUE as usize] = Some(InstructionInfo::new("CALLVALUE", 0, 1, GasPriceTier::Base)); + arr[CALLDATALOAD as usize] = Some(InstructionInfo::new("CALLDATALOAD", 1, 1, GasPriceTier::VeryLow)); + arr[CALLDATASIZE as usize] = Some(InstructionInfo::new("CALLDATASIZE", 0, 1, GasPriceTier::Base)); + arr[CALLDATACOPY as usize] = Some(InstructionInfo::new("CALLDATACOPY", 3, 0, GasPriceTier::VeryLow)); + arr[CODESIZE as usize] = Some(InstructionInfo::new("CODESIZE", 0, 1, GasPriceTier::Base)); + arr[CODECOPY as usize] = Some(InstructionInfo::new("CODECOPY", 3, 0, GasPriceTier::VeryLow)); + arr[GASPRICE as usize] = Some(InstructionInfo::new("GASPRICE", 0, 1, GasPriceTier::Base)); + arr[EXTCODESIZE as usize] = Some(InstructionInfo::new("EXTCODESIZE", 1, 1, GasPriceTier::Special)); + arr[EXTCODECOPY as usize] = Some(InstructionInfo::new("EXTCODECOPY", 4, 0, GasPriceTier::Special)); + arr[BLOCKHASH as usize] = Some(InstructionInfo::new("BLOCKHASH", 1, 1, GasPriceTier::Ext)); + arr[COINBASE as usize] = Some(InstructionInfo::new("COINBASE", 0, 1, GasPriceTier::Base)); + arr[TIMESTAMP as usize] = Some(InstructionInfo::new("TIMESTAMP", 0, 1, GasPriceTier::Base)); + arr[NUMBER as usize] = Some(InstructionInfo::new("NUMBER", 0, 1, GasPriceTier::Base)); + arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base)); + arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base)); + arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base)); + arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow)); + arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow)); + arr[MSTORE8 as usize] = Some(InstructionInfo::new("MSTORE8", 2, 0, GasPriceTier::VeryLow)); + arr[SLOAD as usize] = Some(InstructionInfo::new("SLOAD", 1, 1, GasPriceTier::Special)); + arr[SSTORE as usize] = Some(InstructionInfo::new("SSTORE", 2, 0, GasPriceTier::Special)); + arr[JUMP as usize] = Some(InstructionInfo::new("JUMP", 1, 0, GasPriceTier::Mid)); + arr[JUMPI as usize] = Some(InstructionInfo::new("JUMPI", 2, 0, GasPriceTier::High)); + arr[PC as usize] = Some(InstructionInfo::new("PC", 0, 1, GasPriceTier::Base)); + arr[MSIZE as usize] = Some(InstructionInfo::new("MSIZE", 0, 1, GasPriceTier::Base)); + arr[GAS as usize] = Some(InstructionInfo::new("GAS", 0, 1, GasPriceTier::Base)); + arr[JUMPDEST as usize] = Some(InstructionInfo::new("JUMPDEST", 0, 0, GasPriceTier::Special)); + arr[PUSH1 as usize] = Some(InstructionInfo::new("PUSH1", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH2 as usize] = Some(InstructionInfo::new("PUSH2", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH3 as usize] = Some(InstructionInfo::new("PUSH3", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH4 as usize] = Some(InstructionInfo::new("PUSH4", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH5 as usize] = Some(InstructionInfo::new("PUSH5", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH6 as usize] = Some(InstructionInfo::new("PUSH6", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH7 as usize] = Some(InstructionInfo::new("PUSH7", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH8 as usize] = Some(InstructionInfo::new("PUSH8", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH9 as usize] = Some(InstructionInfo::new("PUSH9", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH10 as usize] = Some(InstructionInfo::new("PUSH10", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH11 as usize] = Some(InstructionInfo::new("PUSH11", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH12 as usize] = Some(InstructionInfo::new("PUSH12", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH13 as usize] = Some(InstructionInfo::new("PUSH13", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH14 as usize] = Some(InstructionInfo::new("PUSH14", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH15 as usize] = Some(InstructionInfo::new("PUSH15", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH16 as usize] = Some(InstructionInfo::new("PUSH16", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH17 as usize] = Some(InstructionInfo::new("PUSH17", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH18 as usize] = Some(InstructionInfo::new("PUSH18", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH19 as usize] = Some(InstructionInfo::new("PUSH19", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH20 as usize] = Some(InstructionInfo::new("PUSH20", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH21 as usize] = Some(InstructionInfo::new("PUSH21", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH22 as usize] = Some(InstructionInfo::new("PUSH22", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH23 as usize] = Some(InstructionInfo::new("PUSH23", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH24 as usize] = Some(InstructionInfo::new("PUSH24", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH25 as usize] = Some(InstructionInfo::new("PUSH25", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH26 as usize] = Some(InstructionInfo::new("PUSH26", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH27 as usize] = Some(InstructionInfo::new("PUSH27", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH28 as usize] = Some(InstructionInfo::new("PUSH28", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH29 as usize] = Some(InstructionInfo::new("PUSH29", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH30 as usize] = Some(InstructionInfo::new("PUSH30", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH31 as usize] = Some(InstructionInfo::new("PUSH31", 0, 1, GasPriceTier::VeryLow)); + arr[PUSH32 as usize] = Some(InstructionInfo::new("PUSH32", 0, 1, GasPriceTier::VeryLow)); + arr[DUP1 as usize] = Some(InstructionInfo::new("DUP1", 1, 2, GasPriceTier::VeryLow)); + arr[DUP2 as usize] = Some(InstructionInfo::new("DUP2", 2, 3, GasPriceTier::VeryLow)); + arr[DUP3 as usize] = Some(InstructionInfo::new("DUP3", 3, 4, GasPriceTier::VeryLow)); + arr[DUP4 as usize] = Some(InstructionInfo::new("DUP4", 4, 5, GasPriceTier::VeryLow)); + arr[DUP5 as usize] = Some(InstructionInfo::new("DUP5", 5, 6, GasPriceTier::VeryLow)); + arr[DUP6 as usize] = Some(InstructionInfo::new("DUP6", 6, 7, GasPriceTier::VeryLow)); + arr[DUP7 as usize] = Some(InstructionInfo::new("DUP7", 7, 8, GasPriceTier::VeryLow)); + arr[DUP8 as usize] = Some(InstructionInfo::new("DUP8", 8, 9, GasPriceTier::VeryLow)); + arr[DUP9 as usize] = Some(InstructionInfo::new("DUP9", 9, 10, GasPriceTier::VeryLow)); + arr[DUP10 as usize] = Some(InstructionInfo::new("DUP10", 10, 11, GasPriceTier::VeryLow)); + arr[DUP11 as usize] = Some(InstructionInfo::new("DUP11", 11, 12, GasPriceTier::VeryLow)); + arr[DUP12 as usize] = Some(InstructionInfo::new("DUP12", 12, 13, GasPriceTier::VeryLow)); + arr[DUP13 as usize] = Some(InstructionInfo::new("DUP13", 13, 14, GasPriceTier::VeryLow)); + arr[DUP14 as usize] = Some(InstructionInfo::new("DUP14", 14, 15, GasPriceTier::VeryLow)); + arr[DUP15 as usize] = Some(InstructionInfo::new("DUP15", 15, 16, GasPriceTier::VeryLow)); + arr[DUP16 as usize] = Some(InstructionInfo::new("DUP16", 16, 17, GasPriceTier::VeryLow)); + arr[SWAP1 as usize] = Some(InstructionInfo::new("SWAP1", 2, 2, GasPriceTier::VeryLow)); + arr[SWAP2 as usize] = Some(InstructionInfo::new("SWAP2", 3, 3, GasPriceTier::VeryLow)); + arr[SWAP3 as usize] = Some(InstructionInfo::new("SWAP3", 4, 4, GasPriceTier::VeryLow)); + arr[SWAP4 as usize] = Some(InstructionInfo::new("SWAP4", 5, 5, GasPriceTier::VeryLow)); + arr[SWAP5 as usize] = Some(InstructionInfo::new("SWAP5", 6, 6, GasPriceTier::VeryLow)); + arr[SWAP6 as usize] = Some(InstructionInfo::new("SWAP6", 7, 7, GasPriceTier::VeryLow)); + arr[SWAP7 as usize] = Some(InstructionInfo::new("SWAP7", 8, 8, GasPriceTier::VeryLow)); + arr[SWAP8 as usize] = Some(InstructionInfo::new("SWAP8", 9, 9, GasPriceTier::VeryLow)); + arr[SWAP9 as usize] = Some(InstructionInfo::new("SWAP9", 10, 10, GasPriceTier::VeryLow)); + arr[SWAP10 as usize] = Some(InstructionInfo::new("SWAP10", 11, 11, GasPriceTier::VeryLow)); + arr[SWAP11 as usize] = Some(InstructionInfo::new("SWAP11", 12, 12, GasPriceTier::VeryLow)); + arr[SWAP12 as usize] = Some(InstructionInfo::new("SWAP12", 13, 13, GasPriceTier::VeryLow)); + arr[SWAP13 as usize] = Some(InstructionInfo::new("SWAP13", 14, 14, GasPriceTier::VeryLow)); + arr[SWAP14 as usize] = Some(InstructionInfo::new("SWAP14", 15, 15, GasPriceTier::VeryLow)); + arr[SWAP15 as usize] = Some(InstructionInfo::new("SWAP15", 16, 16, GasPriceTier::VeryLow)); + arr[SWAP16 as usize] = Some(InstructionInfo::new("SWAP16", 17, 17, GasPriceTier::VeryLow)); + arr[LOG0 as usize] = Some(InstructionInfo::new("LOG0", 2, 0, GasPriceTier::Special)); + arr[LOG1 as usize] = Some(InstructionInfo::new("LOG1", 3, 0, GasPriceTier::Special)); + arr[LOG2 as usize] = Some(InstructionInfo::new("LOG2", 4, 0, GasPriceTier::Special)); + arr[LOG3 as usize] = Some(InstructionInfo::new("LOG3", 5, 0, GasPriceTier::Special)); + arr[LOG4 as usize] = Some(InstructionInfo::new("LOG4", 6, 0, GasPriceTier::Special)); + arr[CREATE as usize] = Some(InstructionInfo::new("CREATE", 3, 1, GasPriceTier::Special)); + arr[CALL as usize] = Some(InstructionInfo::new("CALL", 7, 1, GasPriceTier::Special)); + arr[CALLCODE as usize] = Some(InstructionInfo::new("CALLCODE", 7, 1, GasPriceTier::Special)); + arr[RETURN as usize] = Some(InstructionInfo::new("RETURN", 2, 0, GasPriceTier::Zero)); + arr[DELEGATECALL as usize] = Some(InstructionInfo::new("DELEGATECALL", 6, 1, GasPriceTier::Special)); + arr[STATICCALL as usize] = Some(InstructionInfo::new("STATICCALL", 6, 1, GasPriceTier::Special)); + arr[SUICIDE as usize] = Some(InstructionInfo::new("SUICIDE", 1, 0, GasPriceTier::Special)); + arr[CREATE2 as usize] = Some(InstructionInfo::new("CREATE2", 3, 1, GasPriceTier::Special)); + arr[REVERT as usize] = Some(InstructionInfo::new("REVERT", 2, 0, GasPriceTier::Zero)); arr }; } From 7067c7ae0f0db1359f93296c16d88998cbd5a525 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Jun 2018 17:37:32 +0800 Subject: [PATCH 07/10] Fix evmbin compile --- evmbin/src/display/json.rs | 7 ++++--- evmbin/src/display/std_json.rs | 9 +++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/evmbin/src/display/json.rs b/evmbin/src/display/json.rs index ccee9c37170..613be1d2243 100644 --- a/evmbin/src/display/json.rs +++ b/evmbin/src/display/json.rs @@ -121,13 +121,13 @@ impl trace::VMTracer for Informant { } fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem_diff: Option<(usize, &[u8])>, store_diff: Option<(U256, U256)>) { - let info = ::evm::INSTRUCTIONS[self.instruction as usize]; + let info = ::evm::Instruction::from_u8(self.instruction).map(|i| i.info()); let trace = format!( "{{\"pc\":{pc},\"op\":{op},\"opName\":\"{name}\",\"gas\":\"0x{gas:x}\",\"gasCost\":\"0x{gas_cost:x}\",\"memory\":{memory},\"stack\":{stack},\"storage\":{storage},\"depth\":{depth}}}", pc = self.pc, op = self.instruction, - name = info.name, + name = info.map(|i| i.name).unwrap_or(""), gas = gas_used.saturating_add(self.gas_cost), gas_cost = self.gas_cost, memory = self.memory(), @@ -141,7 +141,8 @@ impl trace::VMTracer for Informant { self.gas_used = gas_used; let len = self.stack.len(); - self.stack.truncate(if len > info.args { len - info.args } else { 0 }); + let info_args = info.map(|i| i.args).unwrap_or(0); + self.stack.truncate(if len > info_args { len - info_args } else { 0 }); self.stack.extend_from_slice(stack_push); // TODO [ToDr] Align memory? diff --git a/evmbin/src/display/std_json.rs b/evmbin/src/display/std_json.rs index 6c4dac1626a..b3533ea2c4e 100644 --- a/evmbin/src/display/std_json.rs +++ b/evmbin/src/display/std_json.rs @@ -118,7 +118,7 @@ impl trace::VMTracer for Informant { type Output = (); fn trace_next_instruction(&mut self, pc: usize, instruction: u8, current_gas: U256) -> bool { - let info = ::evm::INSTRUCTIONS[instruction as usize]; + let info = ::evm::Instruction::from_u8(instruction).map(|i| i.info()); self.instruction = instruction; let storage = self.storage(); let stack = self.stack(); @@ -128,7 +128,7 @@ impl trace::VMTracer for Informant { "{{\"pc\":{pc},\"op\":{op},\"opName\":\"{name}\",\"gas\":\"0x{gas:x}\",\"stack\":{stack},\"storage\":{storage},\"depth\":{depth}}}", pc = pc, op = instruction, - name = info.name, + name = info.map(|i| i.name).unwrap_or(""), gas = current_gas, stack = stack, storage = storage, @@ -142,10 +142,11 @@ impl trace::VMTracer for Informant { } fn trace_executed(&mut self, _gas_used: U256, stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, store_diff: Option<(U256, U256)>) { - let info = ::evm::INSTRUCTIONS[self.instruction as usize]; + let info = ::evm::Instruction::from_u8(self.instruction).map(|i| i.info()); let len = self.stack.len(); - self.stack.truncate(if len > info.args { len - info.args } else { 0 }); + let info_args = info.map(|i| i.args).unwrap_or(0); + self.stack.truncate(if len > info_args { len - info_args } else { 0 }); self.stack.extend_from_slice(stack_push); if let Some((pos, val)) = store_diff { From c6daaf7ad78117a23117f75f451d03e01c874a4d Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 18 Jun 2018 19:07:33 +0800 Subject: [PATCH 08/10] typo: indentation --- ethcore/evm/src/instructions.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ethcore/evm/src/instructions.rs b/ethcore/evm/src/instructions.rs index 52cd29c112f..7a41ed33c75 100644 --- a/ethcore/evm/src/instructions.rs +++ b/ethcore/evm/src/instructions.rs @@ -19,16 +19,16 @@ pub use self::Instruction::*; macro_rules! enum_with_from_u8 { - ( - $( #[$enum_attr:meta] )* - pub enum $name:ident { - $( $( #[$variant_attr:meta] )* $variant:ident = $discriminator:expr ),+, - } - ) => { - $( #[$enum_attr] )* - pub enum $name { - $( $( #[$variant_attr] )* $variant = $discriminator ),+, - } + ( + $( #[$enum_attr:meta] )* + pub enum $name:ident { + $( $( #[$variant_attr:meta] )* $variant:ident = $discriminator:expr ),+, + } + ) => { + $( #[$enum_attr] )* + pub enum $name { + $( $( #[$variant_attr] )* $variant = $discriminator ),+, + } impl $name { #[doc = "Convert from u8 to the given enum"] @@ -39,7 +39,7 @@ macro_rules! enum_with_from_u8 { } } } - }; + }; } enum_with_from_u8! { From a96e354f836e41de14ffa59e12d00c21cc7135af Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 20 Jun 2018 13:27:18 +0800 Subject: [PATCH 09/10] Use if let to remove an expect --- ethcore/evm/src/interpreter/shared_cache.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethcore/evm/src/interpreter/shared_cache.rs b/ethcore/evm/src/interpreter/shared_cache.rs index 0f090e30c7c..f4a7f47f90f 100644 --- a/ethcore/evm/src/interpreter/shared_cache.rs +++ b/ethcore/evm/src/interpreter/shared_cache.rs @@ -75,8 +75,8 @@ impl SharedCache { if let Some(instruction) = instruction { if instruction == instructions::JUMPDEST { jump_dests.insert(position); - } else if instruction.is_push() { - position += instruction.push_bytes().expect("push_bytes always return some when is_push is true; qed"); + } else if let Some(push_bytes) = instruction.push_bytes() { + position += push_bytes; } } position += 1; From 7e036b1c90f4fc2ae5cd4d6d8862d4e8b46592a0 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 26 Jun 2018 14:44:30 +0800 Subject: [PATCH 10/10] Address grumbles --- ethcore/evm/src/interpreter/gasometer.rs | 2 +- ethcore/evm/src/interpreter/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ethcore/evm/src/interpreter/gasometer.rs b/ethcore/evm/src/interpreter/gasometer.rs index a11a4028d79..dbb33383793 100644 --- a/ethcore/evm/src/interpreter/gasometer.rs +++ b/ethcore/evm/src/interpreter/gasometer.rs @@ -180,7 +180,7 @@ impl Gasometer { Request::GasMemCopy(schedule.extcodecopy_base_gas.into(), mem_needed(stack.peek(1), stack.peek(3))?, Gas::from_u256(*stack.peek(3))?) }, instructions::LOG0 | instructions::LOG1 | instructions::LOG2 | instructions::LOG3 | instructions::LOG4 => { - let no_of_topics = instruction.log_topics().expect("log_topcis always return some for LOG* instructions; qed"); + let no_of_topics = instruction.log_topics().expect("log_topics always return some for LOG* instructions; qed"); let log_gas = schedule.log_gas + schedule.log_topic_gas * no_of_topics; let data_gas = overflowing!(Gas::from_u256(*stack.peek(1))?.overflow_mul(Gas::from(schedule.log_data_gas))); diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index fc5bbe359f8..1119869138c 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -147,7 +147,7 @@ impl vm::Vm for Interpreter { // Calculate gas cost let requirements = gasometer.requirements(ext, instruction, info, &stack, self.mem.size())?; if do_trace { - ext.trace_prepare_execute(reader.position - 1, instruction as u8, requirements.gas_cost.as_u256()); + ext.trace_prepare_execute(reader.position - 1, opcode, requirements.gas_cost.as_u256()); } gasometer.verify_gas(&requirements.gas_cost)?;