aboutsummaryrefslogtreecommitdiff
path: root/core/vm/jump_table.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm/jump_table.go')
-rw-r--r--core/vm/jump_table.go1183
1 files changed, 1183 insertions, 0 deletions
diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go
new file mode 100644
index 0000000..359b753
--- /dev/null
+++ b/core/vm/jump_table.go
@@ -0,0 +1,1183 @@
+// Copyright 2015 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package vm
+
+import (
+ "errors"
+
+ "github.com/ava-labs/coreth/params"
+)
+
+type (
+ executionFunc func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
+ gasFunc func(*EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
+ // memorySizeFunc returns the required size, and whether the operation overflowed a uint64
+ memorySizeFunc func(*Stack) (size uint64, overflow bool)
+)
+
+var errGasUintOverflow = errors.New("gas uint64 overflow")
+
+type operation struct {
+ // execute is the operation function
+ execute executionFunc
+ constantGas uint64
+ dynamicGas gasFunc
+ // minStack tells how many stack items are required
+ minStack int
+ // maxStack specifies the max length the stack can have for this operation
+ // to not overflow the stack.
+ maxStack int
+
+ // memorySize returns the memory size required for the operation
+ memorySize memorySizeFunc
+
+ halts bool // indicates whether the operation should halt further execution
+ jumps bool // indicates whether the program counter should not increment
+ writes bool // determines whether this a state modifying operation
+ valid bool // indication whether the retrieved operation is valid and known
+ reverts bool // determines whether the operation reverts state (implicitly halts)
+ returns bool // determines whether the operations sets the return data content
+}
+
+var (
+ frontierInstructionSet = newFrontierInstructionSet()
+ homesteadInstructionSet = newHomesteadInstructionSet()
+ tangerineWhistleInstructionSet = newTangerineWhistleInstructionSet()
+ spuriousDragonInstructionSet = newSpuriousDragonInstructionSet()
+ byzantiumInstructionSet = newByzantiumInstructionSet()
+ constantinopleInstructionSet = newConstantinopleInstructionSet()
+ istanbulInstructionSet = newIstanbulInstructionSet()
+)
+
+// JumpTable contains the EVM opcodes supported at a given fork.
+type JumpTable [256]operation
+
+// newIstanbulInstructionSet returns the frontier, homestead
+// byzantium, contantinople and petersburg instructions.
+func newIstanbulInstructionSet() JumpTable {
+ instructionSet := newConstantinopleInstructionSet()
+
+ enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344
+ enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884
+ enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200
+
+ return instructionSet
+}
+
+// newConstantinopleInstructionSet returns the frontier, homestead
+// byzantium and contantinople instructions.
+func newConstantinopleInstructionSet() JumpTable {
+ instructionSet := newByzantiumInstructionSet()
+ instructionSet[SHL] = operation{
+ execute: opSHL,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ }
+ instructionSet[SHR] = operation{
+ execute: opSHR,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ }
+ instructionSet[SAR] = operation{
+ execute: opSAR,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ }
+ instructionSet[EXTCODEHASH] = operation{
+ execute: opExtCodeHash,
+ constantGas: params.ExtcodeHashGasConstantinople,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ }
+ instructionSet[CREATE2] = operation{
+ execute: opCreate2,
+ constantGas: params.Create2Gas,
+ dynamicGas: gasCreate2,
+ minStack: minStack(4, 1),
+ maxStack: maxStack(4, 1),
+ memorySize: memoryCreate2,
+ valid: true,
+ writes: true,
+ returns: true,
+ }
+ return instructionSet
+}
+
+// newByzantiumInstructionSet returns the frontier, homestead and
+// byzantium instructions.
+func newByzantiumInstructionSet() JumpTable {
+ instructionSet := newSpuriousDragonInstructionSet()
+ instructionSet[STATICCALL] = operation{
+ execute: opStaticCall,
+ constantGas: params.CallGasEIP150,
+ dynamicGas: gasStaticCall,
+ minStack: minStack(6, 1),
+ maxStack: maxStack(6, 1),
+ memorySize: memoryStaticCall,
+ valid: true,
+ returns: true,
+ }
+ instructionSet[RETURNDATASIZE] = operation{
+ execute: opReturnDataSize,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ }
+ instructionSet[RETURNDATACOPY] = operation{
+ execute: opReturnDataCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasReturnDataCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryReturnDataCopy,
+ valid: true,
+ }
+ instructionSet[REVERT] = operation{
+ execute: opRevert,
+ dynamicGas: gasRevert,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryRevert,
+ valid: true,
+ reverts: true,
+ returns: true,
+ }
+ return instructionSet
+}
+
+// EIP 158 a.k.a Spurious Dragon
+func newSpuriousDragonInstructionSet() JumpTable {
+ instructionSet := newTangerineWhistleInstructionSet()
+ instructionSet[EXP].dynamicGas = gasExpEIP158
+ return instructionSet
+
+}
+
+// EIP 150 a.k.a Tangerine Whistle
+func newTangerineWhistleInstructionSet() JumpTable {
+ instructionSet := newHomesteadInstructionSet()
+ instructionSet[BALANCE].constantGas = params.BalanceGasEIP150
+ instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150
+ instructionSet[SLOAD].constantGas = params.SloadGasEIP150
+ instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150
+ instructionSet[CALL].constantGas = params.CallGasEIP150
+ instructionSet[CALLCODE].constantGas = params.CallGasEIP150
+ instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150
+ return instructionSet
+}
+
+// newHomesteadInstructionSet returns the frontier and homestead
+// instructions that can be executed during the homestead phase.
+func newHomesteadInstructionSet() JumpTable {
+ instructionSet := newFrontierInstructionSet()
+ instructionSet[DELEGATECALL] = operation{
+ execute: opDelegateCall,
+ dynamicGas: gasDelegateCall,
+ constantGas: params.CallGasFrontier,
+ minStack: minStack(6, 1),
+ maxStack: maxStack(6, 1),
+ memorySize: memoryDelegateCall,
+ valid: true,
+ returns: true,
+ }
+ return instructionSet
+}
+
+// newFrontierInstructionSet returns the frontier instructions
+// that can be executed during the frontier phase.
+func newFrontierInstructionSet() JumpTable {
+ return JumpTable{
+ STOP: {
+ execute: opStop,
+ constantGas: 0,
+ minStack: minStack(0, 0),
+ maxStack: maxStack(0, 0),
+ halts: true,
+ valid: true,
+ },
+ ADD: {
+ execute: opAdd,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ MUL: {
+ execute: opMul,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ SUB: {
+ execute: opSub,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ DIV: {
+ execute: opDiv,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ SDIV: {
+ execute: opSdiv,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ MOD: {
+ execute: opMod,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ SMOD: {
+ execute: opSmod,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ ADDMOD: {
+ execute: opAddmod,
+ constantGas: GasMidStep,
+ minStack: minStack(3, 1),
+ maxStack: maxStack(3, 1),
+ valid: true,
+ },
+ MULMOD: {
+ execute: opMulmod,
+ constantGas: GasMidStep,
+ minStack: minStack(3, 1),
+ maxStack: maxStack(3, 1),
+ valid: true,
+ },
+ EXP: {
+ execute: opExp,
+ dynamicGas: gasExpFrontier,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ SIGNEXTEND: {
+ execute: opSignExtend,
+ constantGas: GasFastStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ LT: {
+ execute: opLt,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ GT: {
+ execute: opGt,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ SLT: {
+ execute: opSlt,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ SGT: {
+ execute: opSgt,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ EQ: {
+ execute: opEq,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ ISZERO: {
+ execute: opIszero,
+ constantGas: GasFastestStep,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ },
+ AND: {
+ execute: opAnd,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ XOR: {
+ execute: opXor,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ OR: {
+ execute: opOr,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ NOT: {
+ execute: opNot,
+ constantGas: GasFastestStep,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ },
+ BYTE: {
+ execute: opByte,
+ constantGas: GasFastestStep,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ SHA3: {
+ execute: opSha3,
+ constantGas: params.Sha3Gas,
+ dynamicGas: gasSha3,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ memorySize: memorySha3,
+ valid: true,
+ },
+ ADDRESS: {
+ execute: opAddress,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ BALANCE: {
+ execute: opBalance,
+ constantGas: params.BalanceGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ },
+ BALANCEMC: {
+ execute: opBalanceMultiCoin,
+ constantGas: params.BalanceGasFrontier,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ valid: true,
+ },
+ ORIGIN: {
+ execute: opOrigin,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ CALLER: {
+ execute: opCaller,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ CALLVALUE: {
+ execute: opCallValue,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ CALLDATALOAD: {
+ execute: opCallDataLoad,
+ constantGas: GasFastestStep,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ },
+ CALLDATASIZE: {
+ execute: opCallDataSize,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ CALLDATACOPY: {
+ execute: opCallDataCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasCallDataCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryCallDataCopy,
+ valid: true,
+ },
+ CODESIZE: {
+ execute: opCodeSize,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ CODECOPY: {
+ execute: opCodeCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasCodeCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryCodeCopy,
+ valid: true,
+ },
+ GASPRICE: {
+ execute: opGasprice,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ EXTCODESIZE: {
+ execute: opExtCodeSize,
+ constantGas: params.ExtcodeSizeGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ },
+ EXTCODECOPY: {
+ execute: opExtCodeCopy,
+ constantGas: params.ExtcodeCopyBaseFrontier,
+ dynamicGas: gasExtCodeCopy,
+ minStack: minStack(4, 0),
+ maxStack: maxStack(4, 0),
+ memorySize: memoryExtCodeCopy,
+ valid: true,
+ },
+ BLOCKHASH: {
+ execute: opBlockhash,
+ constantGas: GasExtStep,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ },
+ COINBASE: {
+ execute: opCoinbase,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ TIMESTAMP: {
+ execute: opTimestamp,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ NUMBER: {
+ execute: opNumber,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ DIFFICULTY: {
+ execute: opDifficulty,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ GASLIMIT: {
+ execute: opGasLimit,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ POP: {
+ execute: opPop,
+ constantGas: GasQuickStep,
+ minStack: minStack(1, 0),
+ maxStack: maxStack(1, 0),
+ valid: true,
+ },
+ MLOAD: {
+ execute: opMload,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMLoad,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ memorySize: memoryMLoad,
+ valid: true,
+ },
+ MSTORE: {
+ execute: opMstore,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMStore,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryMStore,
+ valid: true,
+ },
+ MSTORE8: {
+ execute: opMstore8,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMStore8,
+ memorySize: memoryMStore8,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+
+ valid: true,
+ },
+ SLOAD: {
+ execute: opSload,
+ constantGas: params.SloadGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
+ },
+ SSTORE: {
+ execute: opSstore,
+ dynamicGas: gasSStore,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ valid: true,
+ writes: true,
+ },
+ JUMP: {
+ execute: opJump,
+ constantGas: GasMidStep,
+ minStack: minStack(1, 0),
+ maxStack: maxStack(1, 0),
+ jumps: true,
+ valid: true,
+ },
+ JUMPI: {
+ execute: opJumpi,
+ constantGas: GasSlowStep,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ jumps: true,
+ valid: true,
+ },
+ PC: {
+ execute: opPc,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ MSIZE: {
+ execute: opMsize,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ GAS: {
+ execute: opGas,
+ constantGas: GasQuickStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ JUMPDEST: {
+ execute: opJumpdest,
+ constantGas: params.JumpdestGas,
+ minStack: minStack(0, 0),
+ maxStack: maxStack(0, 0),
+ valid: true,
+ },
+ EMC: {
+ execute: opEMC,
+ constantGas: params.EMCGas,
+ minStack: minStack(0, 0),
+ maxStack: maxStack(0, 0),
+ valid: true,
+ },
+ PUSH1: {
+ execute: opPush1,
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH2: {
+ execute: makePush(2, 2),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH3: {
+ execute: makePush(3, 3),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH4: {
+ execute: makePush(4, 4),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH5: {
+ execute: makePush(5, 5),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH6: {
+ execute: makePush(6, 6),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH7: {
+ execute: makePush(7, 7),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH8: {
+ execute: makePush(8, 8),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH9: {
+ execute: makePush(9, 9),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH10: {
+ execute: makePush(10, 10),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH11: {
+ execute: makePush(11, 11),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH12: {
+ execute: makePush(12, 12),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH13: {
+ execute: makePush(13, 13),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH14: {
+ execute: makePush(14, 14),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH15: {
+ execute: makePush(15, 15),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH16: {
+ execute: makePush(16, 16),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH17: {
+ execute: makePush(17, 17),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH18: {
+ execute: makePush(18, 18),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH19: {
+ execute: makePush(19, 19),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH20: {
+ execute: makePush(20, 20),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH21: {
+ execute: makePush(21, 21),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH22: {
+ execute: makePush(22, 22),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH23: {
+ execute: makePush(23, 23),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH24: {
+ execute: makePush(24, 24),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH25: {
+ execute: makePush(25, 25),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH26: {
+ execute: makePush(26, 26),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH27: {
+ execute: makePush(27, 27),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH28: {
+ execute: makePush(28, 28),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH29: {
+ execute: makePush(29, 29),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH30: {
+ execute: makePush(30, 30),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH31: {
+ execute: makePush(31, 31),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ PUSH32: {
+ execute: makePush(32, 32),
+ constantGas: GasFastestStep,
+ minStack: minStack(0, 1),
+ maxStack: maxStack(0, 1),
+ valid: true,
+ },
+ DUP1: {
+ execute: makeDup(1),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(1),
+ maxStack: maxDupStack(1),
+ valid: true,
+ },
+ DUP2: {
+ execute: makeDup(2),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(2),
+ maxStack: maxDupStack(2),
+ valid: true,
+ },
+ DUP3: {
+ execute: makeDup(3),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(3),
+ maxStack: maxDupStack(3),
+ valid: true,
+ },
+ DUP4: {
+ execute: makeDup(4),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(4),
+ maxStack: maxDupStack(4),
+ valid: true,
+ },
+ DUP5: {
+ execute: makeDup(5),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(5),
+ maxStack: maxDupStack(5),
+ valid: true,
+ },
+ DUP6: {
+ execute: makeDup(6),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(6),
+ maxStack: maxDupStack(6),
+ valid: true,
+ },
+ DUP7: {
+ execute: makeDup(7),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(7),
+ maxStack: maxDupStack(7),
+ valid: true,
+ },
+ DUP8: {
+ execute: makeDup(8),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(8),
+ maxStack: maxDupStack(8),
+ valid: true,
+ },
+ DUP9: {
+ execute: makeDup(9),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(9),
+ maxStack: maxDupStack(9),
+ valid: true,
+ },
+ DUP10: {
+ execute: makeDup(10),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(10),
+ maxStack: maxDupStack(10),
+ valid: true,
+ },
+ DUP11: {
+ execute: makeDup(11),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(11),
+ maxStack: maxDupStack(11),
+ valid: true,
+ },
+ DUP12: {
+ execute: makeDup(12),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(12),
+ maxStack: maxDupStack(12),
+ valid: true,
+ },
+ DUP13: {
+ execute: makeDup(13),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(13),
+ maxStack: maxDupStack(13),
+ valid: true,
+ },
+ DUP14: {
+ execute: makeDup(14),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(14),
+ maxStack: maxDupStack(14),
+ valid: true,
+ },
+ DUP15: {
+ execute: makeDup(15),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(15),
+ maxStack: maxDupStack(15),
+ valid: true,
+ },
+ DUP16: {
+ execute: makeDup(16),
+ constantGas: GasFastestStep,
+ minStack: minDupStack(16),
+ maxStack: maxDupStack(16),
+ valid: true,
+ },
+ SWAP1: {
+ execute: makeSwap(1),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(2),
+ maxStack: maxSwapStack(2),
+ valid: true,
+ },
+ SWAP2: {
+ execute: makeSwap(2),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(3),
+ maxStack: maxSwapStack(3),
+ valid: true,
+ },
+ SWAP3: {
+ execute: makeSwap(3),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(4),
+ maxStack: maxSwapStack(4),
+ valid: true,
+ },
+ SWAP4: {
+ execute: makeSwap(4),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(5),
+ maxStack: maxSwapStack(5),
+ valid: true,
+ },
+ SWAP5: {
+ execute: makeSwap(5),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(6),
+ maxStack: maxSwapStack(6),
+ valid: true,
+ },
+ SWAP6: {
+ execute: makeSwap(6),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(7),
+ maxStack: maxSwapStack(7),
+ valid: true,
+ },
+ SWAP7: {
+ execute: makeSwap(7),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(8),
+ maxStack: maxSwapStack(8),
+ valid: true,
+ },
+ SWAP8: {
+ execute: makeSwap(8),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(9),
+ maxStack: maxSwapStack(9),
+ valid: true,
+ },
+ SWAP9: {
+ execute: makeSwap(9),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(10),
+ maxStack: maxSwapStack(10),
+ valid: true,
+ },
+ SWAP10: {
+ execute: makeSwap(10),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(11),
+ maxStack: maxSwapStack(11),
+ valid: true,
+ },
+ SWAP11: {
+ execute: makeSwap(11),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(12),
+ maxStack: maxSwapStack(12),
+ valid: true,
+ },
+ SWAP12: {
+ execute: makeSwap(12),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(13),
+ maxStack: maxSwapStack(13),
+ valid: true,
+ },
+ SWAP13: {
+ execute: makeSwap(13),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(14),
+ maxStack: maxSwapStack(14),
+ valid: true,
+ },
+ SWAP14: {
+ execute: makeSwap(14),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(15),
+ maxStack: maxSwapStack(15),
+ valid: true,
+ },
+ SWAP15: {
+ execute: makeSwap(15),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(16),
+ maxStack: maxSwapStack(16),
+ valid: true,
+ },
+ SWAP16: {
+ execute: makeSwap(16),
+ constantGas: GasFastestStep,
+ minStack: minSwapStack(17),
+ maxStack: maxSwapStack(17),
+ valid: true,
+ },
+ LOG0: {
+ execute: makeLog(0),
+ dynamicGas: makeGasLog(0),
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
+ },
+ LOG1: {
+ execute: makeLog(1),
+ dynamicGas: makeGasLog(1),
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
+ },
+ LOG2: {
+ execute: makeLog(2),
+ dynamicGas: makeGasLog(2),
+ minStack: minStack(4, 0),
+ maxStack: maxStack(4, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
+ },
+ LOG3: {
+ execute: makeLog(3),
+ dynamicGas: makeGasLog(3),
+ minStack: minStack(5, 0),
+ maxStack: maxStack(5, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
+ },
+ LOG4: {
+ execute: makeLog(4),
+ dynamicGas: makeGasLog(4),
+ minStack: minStack(6, 0),
+ maxStack: maxStack(6, 0),
+ memorySize: memoryLog,
+ valid: true,
+ writes: true,
+ },
+ CREATE: {
+ execute: opCreate,
+ constantGas: params.CreateGas,
+ dynamicGas: gasCreate,
+ minStack: minStack(3, 1),
+ maxStack: maxStack(3, 1),
+ memorySize: memoryCreate,
+ valid: true,
+ writes: true,
+ returns: true,
+ },
+ CALL: {
+ execute: opCall,
+ constantGas: params.CallGasFrontier,
+ dynamicGas: gasCall,
+ minStack: minStack(7, 1),
+ maxStack: maxStack(7, 1),
+ memorySize: memoryCall,
+ valid: true,
+ returns: true,
+ },
+ CALLEX: {
+ execute: opCallExpert,
+ constantGas: params.CallGasFrontier,
+ dynamicGas: gasCall,
+ minStack: minStack(9, 1),
+ maxStack: maxStack(9, 1),
+ memorySize: memoryCall,
+ valid: true,
+ returns: true,
+ },
+ CALLCODE: {
+ execute: opCallCode,
+ constantGas: params.CallGasFrontier,
+ dynamicGas: gasCallCode,
+ minStack: minStack(7, 1),
+ maxStack: maxStack(7, 1),
+ memorySize: memoryCall,
+ valid: true,
+ returns: true,
+ },
+ RETURN: {
+ execute: opReturn,
+ dynamicGas: gasReturn,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryReturn,
+ halts: true,
+ valid: true,
+ },
+ SELFDESTRUCT: {
+ execute: opSuicide,
+ dynamicGas: gasSelfdestruct,
+ minStack: minStack(1, 0),
+ maxStack: maxStack(1, 0),
+ halts: true,
+ valid: true,
+ writes: true,
+ },
+ }
+}