diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index ca15261a61..eb85ae6aff 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -48,808 +48,812 @@ type operation struct { valid bool } -var jumpTable = [256]operation{ - ADD: operation{ - execute: opAdd, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - SUB: operation{ - execute: opSub, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - MUL: operation{ - execute: opMul, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - DIV: operation{ - execute: opDiv, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - SDIV: operation{ - execute: opSdiv, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - MOD: operation{ - execute: opMod, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - SMOD: operation{ - execute: opSmod, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - EXP: operation{ - execute: opExp, - gasCost: gasExp, - validateStack: makeStackFunc(2, 1), - valid: true, - }, - SIGNEXTEND: operation{ - execute: opSignExtend, - gasCost: constGasFunc(GasFastStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - NOT: operation{ - execute: opNot, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(1, 1), - valid: true, - }, - LT: operation{ - execute: opLt, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - GT: operation{ - execute: opGt, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - SLT: operation{ - execute: opSlt, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - SGT: operation{ - execute: opSgt, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - EQ: operation{ - execute: opEq, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - ISZERO: operation{ - execute: opIszero, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(1, 1), - valid: true, - }, - AND: operation{ - execute: opAnd, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - OR: operation{ - execute: opOr, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - XOR: operation{ - execute: opXor, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - BYTE: operation{ - execute: opByte, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(2, 1), - valid: true, - }, - ADDMOD: operation{ - execute: opAddmod, - gasCost: constGasFunc(GasMidStep), - validateStack: makeStackFunc(3, 1), - valid: true, - }, - MULMOD: operation{ - execute: opMulmod, - gasCost: constGasFunc(GasMidStep), - validateStack: makeStackFunc(3, 1), - valid: true, - }, - SHA3: operation{ - execute: opSha3, - gasCost: gasSha3, - validateStack: makeStackFunc(2, 1), - memorySize: memorySha3, - valid: true, - }, - ADDRESS: operation{ - execute: opAddress, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - BALANCE: operation{ - execute: opBalance, - gasCost: gasBalance, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - ORIGIN: operation{ - execute: opOrigin, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - CALLER: operation{ - execute: opCaller, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - CALLVALUE: operation{ - execute: opCallValue, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - CALLDATALOAD: operation{ - execute: opCalldataLoad, - gasCost: constGasFunc(GasFastestStep), - validateStack: makeStackFunc(1, 1), - valid: true, - }, - CALLDATASIZE: operation{ - execute: opCalldataSize, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - CALLDATACOPY: operation{ - execute: opCalldataCopy, - gasCost: gasCalldataCopy, - validateStack: makeStackFunc(3, 1), - memorySize: memoryCalldataCopy, - valid: true, - }, - CODESIZE: operation{ - execute: opCodeSize, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - EXTCODESIZE: operation{ - execute: opExtCodeSize, - gasCost: gasExtCodeSize, - validateStack: makeStackFunc(1, 1), - valid: true, - }, - CODECOPY: operation{ - execute: opCodeCopy, - gasCost: gasCodeCopy, - validateStack: makeStackFunc(3, 0), - memorySize: memoryCodeCopy, - valid: true, - }, - EXTCODECOPY: operation{ - execute: opExtCodeCopy, - gasCost: gasExtCodeCopy, - validateStack: makeStackFunc(4, 0), - memorySize: memoryExtCodeCopy, - valid: true, - }, - GASPRICE: operation{ - execute: opGasprice, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - BLOCKHASH: operation{ - execute: opBlockhash, - gasCost: constGasFunc(GasExtStep), - validateStack: makeStackFunc(1, 1), - valid: true, - }, - COINBASE: operation{ - execute: opCoinbase, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - TIMESTAMP: operation{ - execute: opTimestamp, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - NUMBER: operation{ - execute: opNumber, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - DIFFICULTY: operation{ - execute: opDifficulty, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - GASLIMIT: operation{ - execute: opGasLimit, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - POP: operation{ - execute: opPop, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(1, 0), - valid: true, - }, - MLOAD: operation{ - execute: opMload, - gasCost: gasMLoad, - validateStack: makeStackFunc(1, 1), - memorySize: memoryMLoad, - valid: true, - }, - MSTORE: operation{ - execute: opMstore, - gasCost: gasMStore, - validateStack: makeStackFunc(2, 0), - memorySize: memoryMStore, - valid: true, - }, - MSTORE8: operation{ - execute: opMstore8, - gasCost: gasMStore8, - memorySize: memoryMStore8, - validateStack: makeStackFunc(2, 0), +var defaultJumpTable = NewJumpTable() - valid: true, - }, - SLOAD: operation{ - execute: opSload, - gasCost: gasSLoad, - validateStack: makeStackFunc(1, 1), - valid: true, - }, - SSTORE: operation{ - execute: opSstore, - gasCost: gasSStore, - validateStack: makeStackFunc(2, 0), - valid: true, - }, - JUMPDEST: operation{ - execute: opJumpdest, - gasCost: constGasFunc(params.JumpdestGas), - validateStack: makeStackFunc(0, 0), - valid: true, - }, - PC: operation{ - execute: opPc, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - MSIZE: operation{ - execute: opMsize, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - GAS: operation{ - execute: opGas, - gasCost: constGasFunc(GasQuickStep), - validateStack: makeStackFunc(0, 1), - valid: true, - }, - CREATE: operation{ - execute: opCreate, - gasCost: gasCreate, - validateStack: makeStackFunc(3, 1), - memorySize: memoryCreate, - valid: true, - }, - CALL: operation{ - execute: opCall, - gasCost: gasCall, - validateStack: makeStackFunc(7, 1), - memorySize: memoryCall, - valid: true, - }, - CALLCODE: operation{ - execute: opCallCode, - gasCost: gasCallCode, - validateStack: makeStackFunc(7, 1), - memorySize: memoryCall, - valid: true, - }, - DELEGATECALL: operation{ - execute: opDelegateCall, - gasCost: gasDelegateCall, - validateStack: makeStackFunc(6, 1), - memorySize: memoryDelegateCall, - valid: true, - }, - RETURN: operation{ - execute: opReturn, - gasCost: gasReturn, - validateStack: makeStackFunc(2, 0), - memorySize: memoryReturn, - halts: true, - valid: true, - }, - SUICIDE: operation{ - execute: opSuicide, - gasCost: gasSuicide, - validateStack: makeStackFunc(1, 0), - halts: true, - valid: true, - }, - JUMP: operation{ - execute: opJump, - gasCost: constGasFunc(GasMidStep), - validateStack: makeStackFunc(1, 0), - jumps: true, - valid: true, - }, - JUMPI: operation{ - execute: opJumpi, - gasCost: constGasFunc(GasSlowStep), - validateStack: makeStackFunc(2, 0), - jumps: true, - valid: true, - }, - STOP: operation{ - execute: opStop, - gasCost: constGasFunc(Zero), - validateStack: makeStackFunc(0, 0), - halts: true, - valid: true, - }, - LOG0: operation{ - execute: makeLog(0), - gasCost: makeGasLog(0), - validateStack: makeStackFunc(2, 0), - memorySize: memoryLog, - valid: true, - }, - LOG1: operation{ - execute: makeLog(1), - gasCost: makeGasLog(1), - validateStack: makeStackFunc(3, 0), - memorySize: memoryLog, - valid: true, - }, - LOG2: operation{ - execute: makeLog(2), - gasCost: makeGasLog(2), - validateStack: makeStackFunc(4, 0), - memorySize: memoryLog, - valid: true, - }, - LOG3: operation{ - execute: makeLog(3), - gasCost: makeGasLog(3), - validateStack: makeStackFunc(5, 0), - memorySize: memoryLog, - valid: true, - }, - LOG4: operation{ - execute: makeLog(4), - gasCost: makeGasLog(4), - validateStack: makeStackFunc(6, 0), - memorySize: memoryLog, - valid: true, - }, - SWAP1: operation{ - execute: makeSwap(1), - gasCost: gasSwap, - validateStack: makeStackFunc(2, 0), - valid: true, - }, - SWAP2: operation{ - execute: makeSwap(2), - gasCost: gasSwap, - validateStack: makeStackFunc(3, 0), - valid: true, - }, - SWAP3: operation{ - execute: makeSwap(3), - gasCost: gasSwap, - validateStack: makeStackFunc(4, 0), - valid: true, - }, - SWAP4: operation{ - execute: makeSwap(4), - gasCost: gasSwap, - validateStack: makeStackFunc(5, 0), - valid: true, - }, - SWAP5: operation{ - execute: makeSwap(5), - gasCost: gasSwap, - validateStack: makeStackFunc(6, 0), - valid: true, - }, - SWAP6: operation{ - execute: makeSwap(6), - gasCost: gasSwap, - validateStack: makeStackFunc(7, 0), - valid: true, - }, - SWAP7: operation{ - execute: makeSwap(7), - gasCost: gasSwap, - validateStack: makeStackFunc(8, 0), - valid: true, - }, - SWAP8: operation{ - execute: makeSwap(8), - gasCost: gasSwap, - validateStack: makeStackFunc(9, 0), - valid: true, - }, - SWAP9: operation{ - execute: makeSwap(9), - gasCost: gasSwap, - validateStack: makeStackFunc(10, 0), - valid: true, - }, - SWAP10: operation{ - execute: makeSwap(10), - gasCost: gasSwap, - validateStack: makeStackFunc(11, 0), - valid: true, - }, - SWAP11: operation{ - execute: makeSwap(11), - gasCost: gasSwap, - validateStack: makeStackFunc(12, 0), - valid: true, - }, - SWAP12: operation{ - execute: makeSwap(12), - gasCost: gasSwap, - validateStack: makeStackFunc(13, 0), - valid: true, - }, - SWAP13: operation{ - execute: makeSwap(13), - gasCost: gasSwap, - validateStack: makeStackFunc(14, 0), - valid: true, - }, - SWAP14: operation{ - execute: makeSwap(14), - gasCost: gasSwap, - validateStack: makeStackFunc(15, 0), - valid: true, - }, - SWAP15: operation{ - execute: makeSwap(15), - gasCost: gasSwap, - validateStack: makeStackFunc(16, 0), - valid: true, - }, - SWAP16: operation{ - execute: makeSwap(16), - gasCost: gasSwap, - validateStack: makeStackFunc(17, 0), - valid: true, - }, - PUSH1: operation{ - execute: makePush(1, big.NewInt(1)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH2: operation{ - execute: makePush(2, big.NewInt(2)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH3: operation{ - execute: makePush(3, big.NewInt(3)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH4: operation{ - execute: makePush(4, big.NewInt(4)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH5: operation{ - execute: makePush(5, big.NewInt(5)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH6: operation{ - execute: makePush(6, big.NewInt(6)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH7: operation{ - execute: makePush(7, big.NewInt(7)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH8: operation{ - execute: makePush(8, big.NewInt(8)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH9: operation{ - execute: makePush(9, big.NewInt(9)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH10: operation{ - execute: makePush(10, big.NewInt(10)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH11: operation{ - execute: makePush(11, big.NewInt(11)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH12: operation{ - execute: makePush(12, big.NewInt(12)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH13: operation{ - execute: makePush(13, big.NewInt(13)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH14: operation{ - execute: makePush(14, big.NewInt(14)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH15: operation{ - execute: makePush(15, big.NewInt(15)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH16: operation{ - execute: makePush(16, big.NewInt(16)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH17: operation{ - execute: makePush(17, big.NewInt(17)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH18: operation{ - execute: makePush(18, big.NewInt(18)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH19: operation{ - execute: makePush(19, big.NewInt(19)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH20: operation{ - execute: makePush(20, big.NewInt(20)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH21: operation{ - execute: makePush(21, big.NewInt(21)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH22: operation{ - execute: makePush(22, big.NewInt(22)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH23: operation{ - execute: makePush(23, big.NewInt(23)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH24: operation{ - execute: makePush(24, big.NewInt(24)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH25: operation{ - execute: makePush(25, big.NewInt(25)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH26: operation{ - execute: makePush(26, big.NewInt(26)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH27: operation{ - execute: makePush(27, big.NewInt(27)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH28: operation{ - execute: makePush(28, big.NewInt(28)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH29: operation{ - execute: makePush(29, big.NewInt(29)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH30: operation{ - execute: makePush(30, big.NewInt(30)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH31: operation{ - execute: makePush(31, big.NewInt(31)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - PUSH32: operation{ - execute: makePush(32, big.NewInt(32)), - gasCost: gasPush, - validateStack: makeStackFunc(0, 1), - valid: true, - }, - DUP1: operation{ - execute: makeDup(1), - gasCost: gasDup, - validateStack: makeStackFunc(1, 1), - valid: true, - }, - DUP2: operation{ - execute: makeDup(2), - gasCost: gasDup, - validateStack: makeStackFunc(2, 1), - valid: true, - }, - DUP3: operation{ - execute: makeDup(3), - gasCost: gasDup, - validateStack: makeStackFunc(3, 1), - valid: true, - }, - DUP4: operation{ - execute: makeDup(4), - gasCost: gasDup, - validateStack: makeStackFunc(4, 1), - valid: true, - }, - DUP5: operation{ - execute: makeDup(5), - gasCost: gasDup, - validateStack: makeStackFunc(5, 1), - valid: true, - }, - DUP6: operation{ - execute: makeDup(6), - gasCost: gasDup, - validateStack: makeStackFunc(6, 1), - valid: true, - }, - DUP7: operation{ - execute: makeDup(7), - gasCost: gasDup, - validateStack: makeStackFunc(7, 1), - valid: true, - }, - DUP8: operation{ - execute: makeDup(8), - gasCost: gasDup, - validateStack: makeStackFunc(8, 1), - valid: true, - }, - DUP9: operation{ - execute: makeDup(9), - gasCost: gasDup, - validateStack: makeStackFunc(9, 1), - valid: true, - }, - DUP10: operation{ - execute: makeDup(10), - gasCost: gasDup, - validateStack: makeStackFunc(10, 1), - valid: true, - }, - DUP11: operation{ - execute: makeDup(11), - gasCost: gasDup, - validateStack: makeStackFunc(11, 1), - valid: true, - }, - DUP12: operation{ - execute: makeDup(12), - gasCost: gasDup, - validateStack: makeStackFunc(12, 1), - valid: true, - }, - DUP13: operation{ - execute: makeDup(13), - gasCost: gasDup, - validateStack: makeStackFunc(13, 1), - valid: true, - }, - DUP14: operation{ - execute: makeDup(14), - gasCost: gasDup, - validateStack: makeStackFunc(14, 1), - valid: true, - }, - DUP15: operation{ - execute: makeDup(15), - gasCost: gasDup, - validateStack: makeStackFunc(15, 1), - valid: true, - }, - DUP16: operation{ - execute: makeDup(16), - gasCost: gasDup, - validateStack: makeStackFunc(16, 1), - valid: true, - }, +func NewJumpTable() [256]operation { + return [256]operation{ + ADD: operation{ + execute: opAdd, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + SUB: operation{ + execute: opSub, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + MUL: operation{ + execute: opMul, + gasCost: constGasFunc(GasFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + DIV: operation{ + execute: opDiv, + gasCost: constGasFunc(GasFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + SDIV: operation{ + execute: opSdiv, + gasCost: constGasFunc(GasFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + MOD: operation{ + execute: opMod, + gasCost: constGasFunc(GasFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + SMOD: operation{ + execute: opSmod, + gasCost: constGasFunc(GasFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + EXP: operation{ + execute: opExp, + gasCost: gasExp, + validateStack: makeStackFunc(2, 1), + valid: true, + }, + SIGNEXTEND: operation{ + execute: opSignExtend, + gasCost: constGasFunc(GasFastStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + NOT: operation{ + execute: opNot, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(1, 1), + valid: true, + }, + LT: operation{ + execute: opLt, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + GT: operation{ + execute: opGt, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + SLT: operation{ + execute: opSlt, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + SGT: operation{ + execute: opSgt, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + EQ: operation{ + execute: opEq, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + ISZERO: operation{ + execute: opIszero, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(1, 1), + valid: true, + }, + AND: operation{ + execute: opAnd, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + OR: operation{ + execute: opOr, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + XOR: operation{ + execute: opXor, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + BYTE: operation{ + execute: opByte, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 1), + valid: true, + }, + ADDMOD: operation{ + execute: opAddmod, + gasCost: constGasFunc(GasMidStep), + validateStack: makeStackFunc(3, 1), + valid: true, + }, + MULMOD: operation{ + execute: opMulmod, + gasCost: constGasFunc(GasMidStep), + validateStack: makeStackFunc(3, 1), + valid: true, + }, + SHA3: operation{ + execute: opSha3, + gasCost: gasSha3, + validateStack: makeStackFunc(2, 1), + memorySize: memorySha3, + valid: true, + }, + ADDRESS: operation{ + execute: opAddress, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + BALANCE: operation{ + execute: opBalance, + gasCost: gasBalance, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + ORIGIN: operation{ + execute: opOrigin, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + CALLER: operation{ + execute: opCaller, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + CALLVALUE: operation{ + execute: opCallValue, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + CALLDATALOAD: operation{ + execute: opCalldataLoad, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(1, 1), + valid: true, + }, + CALLDATASIZE: operation{ + execute: opCalldataSize, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + CALLDATACOPY: operation{ + execute: opCalldataCopy, + gasCost: gasCalldataCopy, + validateStack: makeStackFunc(3, 1), + memorySize: memoryCalldataCopy, + valid: true, + }, + CODESIZE: operation{ + execute: opCodeSize, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + EXTCODESIZE: operation{ + execute: opExtCodeSize, + gasCost: gasExtCodeSize, + validateStack: makeStackFunc(1, 1), + valid: true, + }, + CODECOPY: operation{ + execute: opCodeCopy, + gasCost: gasCodeCopy, + validateStack: makeStackFunc(3, 0), + memorySize: memoryCodeCopy, + valid: true, + }, + EXTCODECOPY: operation{ + execute: opExtCodeCopy, + gasCost: gasExtCodeCopy, + validateStack: makeStackFunc(4, 0), + memorySize: memoryExtCodeCopy, + valid: true, + }, + GASPRICE: operation{ + execute: opGasprice, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + BLOCKHASH: operation{ + execute: opBlockhash, + gasCost: constGasFunc(GasExtStep), + validateStack: makeStackFunc(1, 1), + valid: true, + }, + COINBASE: operation{ + execute: opCoinbase, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + TIMESTAMP: operation{ + execute: opTimestamp, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + NUMBER: operation{ + execute: opNumber, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + DIFFICULTY: operation{ + execute: opDifficulty, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + GASLIMIT: operation{ + execute: opGasLimit, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + POP: operation{ + execute: opPop, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(1, 0), + valid: true, + }, + MLOAD: operation{ + execute: opMload, + gasCost: gasMLoad, + validateStack: makeStackFunc(1, 1), + memorySize: memoryMLoad, + valid: true, + }, + MSTORE: operation{ + execute: opMstore, + gasCost: gasMStore, + validateStack: makeStackFunc(2, 0), + memorySize: memoryMStore, + valid: true, + }, + MSTORE8: operation{ + execute: opMstore8, + gasCost: gasMStore8, + memorySize: memoryMStore8, + validateStack: makeStackFunc(2, 0), + + valid: true, + }, + SLOAD: operation{ + execute: opSload, + gasCost: gasSLoad, + validateStack: makeStackFunc(1, 1), + valid: true, + }, + SSTORE: operation{ + execute: opSstore, + gasCost: gasSStore, + validateStack: makeStackFunc(2, 0), + valid: true, + }, + JUMPDEST: operation{ + execute: opJumpdest, + gasCost: constGasFunc(params.JumpdestGas), + validateStack: makeStackFunc(0, 0), + valid: true, + }, + PC: operation{ + execute: opPc, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + MSIZE: operation{ + execute: opMsize, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + GAS: operation{ + execute: opGas, + gasCost: constGasFunc(GasQuickStep), + validateStack: makeStackFunc(0, 1), + valid: true, + }, + CREATE: operation{ + execute: opCreate, + gasCost: gasCreate, + validateStack: makeStackFunc(3, 1), + memorySize: memoryCreate, + valid: true, + }, + CALL: operation{ + execute: opCall, + gasCost: gasCall, + validateStack: makeStackFunc(7, 1), + memorySize: memoryCall, + valid: true, + }, + CALLCODE: operation{ + execute: opCallCode, + gasCost: gasCallCode, + validateStack: makeStackFunc(7, 1), + memorySize: memoryCall, + valid: true, + }, + DELEGATECALL: operation{ + execute: opDelegateCall, + gasCost: gasDelegateCall, + validateStack: makeStackFunc(6, 1), + memorySize: memoryDelegateCall, + valid: true, + }, + RETURN: operation{ + execute: opReturn, + gasCost: gasReturn, + validateStack: makeStackFunc(2, 0), + memorySize: memoryReturn, + halts: true, + valid: true, + }, + SUICIDE: operation{ + execute: opSuicide, + gasCost: gasSuicide, + validateStack: makeStackFunc(1, 0), + halts: true, + valid: true, + }, + JUMP: operation{ + execute: opJump, + gasCost: constGasFunc(GasMidStep), + validateStack: makeStackFunc(1, 0), + jumps: true, + valid: true, + }, + JUMPI: operation{ + execute: opJumpi, + gasCost: constGasFunc(GasSlowStep), + validateStack: makeStackFunc(2, 0), + jumps: true, + valid: true, + }, + STOP: operation{ + execute: opStop, + gasCost: constGasFunc(Zero), + validateStack: makeStackFunc(0, 0), + halts: true, + valid: true, + }, + LOG0: operation{ + execute: makeLog(0), + gasCost: makeGasLog(0), + validateStack: makeStackFunc(2, 0), + memorySize: memoryLog, + valid: true, + }, + LOG1: operation{ + execute: makeLog(1), + gasCost: makeGasLog(1), + validateStack: makeStackFunc(3, 0), + memorySize: memoryLog, + valid: true, + }, + LOG2: operation{ + execute: makeLog(2), + gasCost: makeGasLog(2), + validateStack: makeStackFunc(4, 0), + memorySize: memoryLog, + valid: true, + }, + LOG3: operation{ + execute: makeLog(3), + gasCost: makeGasLog(3), + validateStack: makeStackFunc(5, 0), + memorySize: memoryLog, + valid: true, + }, + LOG4: operation{ + execute: makeLog(4), + gasCost: makeGasLog(4), + validateStack: makeStackFunc(6, 0), + memorySize: memoryLog, + valid: true, + }, + SWAP1: operation{ + execute: makeSwap(1), + gasCost: gasSwap, + validateStack: makeStackFunc(2, 0), + valid: true, + }, + SWAP2: operation{ + execute: makeSwap(2), + gasCost: gasSwap, + validateStack: makeStackFunc(3, 0), + valid: true, + }, + SWAP3: operation{ + execute: makeSwap(3), + gasCost: gasSwap, + validateStack: makeStackFunc(4, 0), + valid: true, + }, + SWAP4: operation{ + execute: makeSwap(4), + gasCost: gasSwap, + validateStack: makeStackFunc(5, 0), + valid: true, + }, + SWAP5: operation{ + execute: makeSwap(5), + gasCost: gasSwap, + validateStack: makeStackFunc(6, 0), + valid: true, + }, + SWAP6: operation{ + execute: makeSwap(6), + gasCost: gasSwap, + validateStack: makeStackFunc(7, 0), + valid: true, + }, + SWAP7: operation{ + execute: makeSwap(7), + gasCost: gasSwap, + validateStack: makeStackFunc(8, 0), + valid: true, + }, + SWAP8: operation{ + execute: makeSwap(8), + gasCost: gasSwap, + validateStack: makeStackFunc(9, 0), + valid: true, + }, + SWAP9: operation{ + execute: makeSwap(9), + gasCost: gasSwap, + validateStack: makeStackFunc(10, 0), + valid: true, + }, + SWAP10: operation{ + execute: makeSwap(10), + gasCost: gasSwap, + validateStack: makeStackFunc(11, 0), + valid: true, + }, + SWAP11: operation{ + execute: makeSwap(11), + gasCost: gasSwap, + validateStack: makeStackFunc(12, 0), + valid: true, + }, + SWAP12: operation{ + execute: makeSwap(12), + gasCost: gasSwap, + validateStack: makeStackFunc(13, 0), + valid: true, + }, + SWAP13: operation{ + execute: makeSwap(13), + gasCost: gasSwap, + validateStack: makeStackFunc(14, 0), + valid: true, + }, + SWAP14: operation{ + execute: makeSwap(14), + gasCost: gasSwap, + validateStack: makeStackFunc(15, 0), + valid: true, + }, + SWAP15: operation{ + execute: makeSwap(15), + gasCost: gasSwap, + validateStack: makeStackFunc(16, 0), + valid: true, + }, + SWAP16: operation{ + execute: makeSwap(16), + gasCost: gasSwap, + validateStack: makeStackFunc(17, 0), + valid: true, + }, + PUSH1: operation{ + execute: makePush(1, big.NewInt(1)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH2: operation{ + execute: makePush(2, big.NewInt(2)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH3: operation{ + execute: makePush(3, big.NewInt(3)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH4: operation{ + execute: makePush(4, big.NewInt(4)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH5: operation{ + execute: makePush(5, big.NewInt(5)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH6: operation{ + execute: makePush(6, big.NewInt(6)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH7: operation{ + execute: makePush(7, big.NewInt(7)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH8: operation{ + execute: makePush(8, big.NewInt(8)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH9: operation{ + execute: makePush(9, big.NewInt(9)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH10: operation{ + execute: makePush(10, big.NewInt(10)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH11: operation{ + execute: makePush(11, big.NewInt(11)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH12: operation{ + execute: makePush(12, big.NewInt(12)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH13: operation{ + execute: makePush(13, big.NewInt(13)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH14: operation{ + execute: makePush(14, big.NewInt(14)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH15: operation{ + execute: makePush(15, big.NewInt(15)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH16: operation{ + execute: makePush(16, big.NewInt(16)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH17: operation{ + execute: makePush(17, big.NewInt(17)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH18: operation{ + execute: makePush(18, big.NewInt(18)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH19: operation{ + execute: makePush(19, big.NewInt(19)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH20: operation{ + execute: makePush(20, big.NewInt(20)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH21: operation{ + execute: makePush(21, big.NewInt(21)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH22: operation{ + execute: makePush(22, big.NewInt(22)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH23: operation{ + execute: makePush(23, big.NewInt(23)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH24: operation{ + execute: makePush(24, big.NewInt(24)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH25: operation{ + execute: makePush(25, big.NewInt(25)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH26: operation{ + execute: makePush(26, big.NewInt(26)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH27: operation{ + execute: makePush(27, big.NewInt(27)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH28: operation{ + execute: makePush(28, big.NewInt(28)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH29: operation{ + execute: makePush(29, big.NewInt(29)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH30: operation{ + execute: makePush(30, big.NewInt(30)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH31: operation{ + execute: makePush(31, big.NewInt(31)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + PUSH32: operation{ + execute: makePush(32, big.NewInt(32)), + gasCost: gasPush, + validateStack: makeStackFunc(0, 1), + valid: true, + }, + DUP1: operation{ + execute: makeDup(1), + gasCost: gasDup, + validateStack: makeStackFunc(1, 1), + valid: true, + }, + DUP2: operation{ + execute: makeDup(2), + gasCost: gasDup, + validateStack: makeStackFunc(2, 1), + valid: true, + }, + DUP3: operation{ + execute: makeDup(3), + gasCost: gasDup, + validateStack: makeStackFunc(3, 1), + valid: true, + }, + DUP4: operation{ + execute: makeDup(4), + gasCost: gasDup, + validateStack: makeStackFunc(4, 1), + valid: true, + }, + DUP5: operation{ + execute: makeDup(5), + gasCost: gasDup, + validateStack: makeStackFunc(5, 1), + valid: true, + }, + DUP6: operation{ + execute: makeDup(6), + gasCost: gasDup, + validateStack: makeStackFunc(6, 1), + valid: true, + }, + DUP7: operation{ + execute: makeDup(7), + gasCost: gasDup, + validateStack: makeStackFunc(7, 1), + valid: true, + }, + DUP8: operation{ + execute: makeDup(8), + gasCost: gasDup, + validateStack: makeStackFunc(8, 1), + valid: true, + }, + DUP9: operation{ + execute: makeDup(9), + gasCost: gasDup, + validateStack: makeStackFunc(9, 1), + valid: true, + }, + DUP10: operation{ + execute: makeDup(10), + gasCost: gasDup, + validateStack: makeStackFunc(10, 1), + valid: true, + }, + DUP11: operation{ + execute: makeDup(11), + gasCost: gasDup, + validateStack: makeStackFunc(11, 1), + valid: true, + }, + DUP12: operation{ + execute: makeDup(12), + gasCost: gasDup, + validateStack: makeStackFunc(12, 1), + valid: true, + }, + DUP13: operation{ + execute: makeDup(13), + gasCost: gasDup, + validateStack: makeStackFunc(13, 1), + valid: true, + }, + DUP14: operation{ + execute: makeDup(14), + gasCost: gasDup, + validateStack: makeStackFunc(14, 1), + valid: true, + }, + DUP15: operation{ + execute: makeDup(15), + gasCost: gasDup, + validateStack: makeStackFunc(15, 1), + valid: true, + }, + DUP16: operation{ + execute: makeDup(16), + gasCost: gasDup, + validateStack: makeStackFunc(16, 1), + valid: true, + }, + } } diff --git a/core/vm/vm.go b/core/vm/vm.go index af0a82a6d3..56081f12c3 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -44,6 +44,10 @@ type Config struct { NoRecursion bool // Disable gas metering DisableGasMetering bool + // JumpTable contains the EVM instruction table. This + // may me left uninitialised and will be set the default + // table. + JumpTable [256]operation } // Interpreter is used to run Ethereum based contracts and will utilise the @@ -58,6 +62,13 @@ type Interpreter struct { // NewInterpreter returns a new instance of the Interpreter. func NewInterpreter(env *EVM, cfg Config) *Interpreter { + // We use the STOP instruction whether to see + // the jump table was initialised. If it was not + // we'll set the default jump table. + if !cfg.JumpTable[STOP].valid { + cfg.JumpTable = defaultJumpTable + } + return &Interpreter{ env: env, cfg: cfg, @@ -121,7 +132,7 @@ func (evm *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err e op = contract.GetOp(pc) // get the operation from the jump table matching the opcode - operation := jumpTable[op] + operation := evm.cfg.JumpTable[op] // if the op is invalid abort the process and return an error if !operation.valid {