github.com/quinndk/ethereum_read@v0.0.0-20181211143958-29c55eec3237/go-ethereum-master_read/core/vm/jump_table.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package vm
    18  
    19  import (
    20  	"errors"
    21  	"math/big"
    22  
    23  	"github.com/ethereum/go-ethereum/params"
    24  )
    25  
    26  type (
    27  	executionFunc       func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
    28  	gasFunc             func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
    29  	stackValidationFunc func(*Stack) error
    30  	memorySizeFunc      func(*Stack) *big.Int
    31  )
    32  
    33  var errGasUintOverflow = errors.New("gas uint64 overflow")
    34  
    35  type operation struct {
    36  	// execute is the operation function
    37  	// 操作函数
    38  	execute executionFunc
    39  	// gasCost is the gas function and returns the gas required for execution
    40  	// 计算操作需要多少gas的函数
    41  	gasCost gasFunc
    42  	// validateStack validates the stack (size) for the operation
    43  	// 验证操作的栈
    44  	validateStack stackValidationFunc
    45  	// memorySize returns the memory size required for the operation
    46  	// 操作需要的内存大小
    47  	memorySize memorySizeFunc
    48  
    49  	// 操作终止
    50  	halts   bool // indicates whether the operation should halt further execution
    51  	// 操作跳转
    52  	jumps   bool // indicates whether the program counter should not increment
    53  	// 是否写入
    54  	writes  bool // determines whether this a state modifying operation
    55  	// 操作是否有效
    56  	valid   bool // indication whether the retrieved operation is valid and known
    57  	// 出错回滚
    58  	reverts bool // determines whether the operation reverts state (implicitly halts)
    59  	// 操作返回
    60  	returns bool // determines whether the operations sets the return data content
    61  }
    62  
    63  var (
    64  	frontierInstructionSet       = newFrontierInstructionSet()
    65  	homesteadInstructionSet      = newHomesteadInstructionSet()
    66  	byzantiumInstructionSet      = newByzantiumInstructionSet()
    67  	constantinopleInstructionSet = newConstantinopleInstructionSet()
    68  )
    69  
    70  // NewConstantinopleInstructionSet returns the frontier, homestead
    71  // byzantium and contantinople instructions.
    72  func newConstantinopleInstructionSet() [256]operation {
    73  	// instructions that can be executed during the byzantium phase.
    74  	instructionSet := newByzantiumInstructionSet()
    75  	instructionSet[SHL] = operation{
    76  		execute:       opSHL,
    77  		gasCost:       constGasFunc(GasFastestStep),
    78  		validateStack: makeStackFunc(2, 1),
    79  		valid:         true,
    80  	}
    81  	instructionSet[SHR] = operation{
    82  		execute:       opSHR,
    83  		gasCost:       constGasFunc(GasFastestStep),
    84  		validateStack: makeStackFunc(2, 1),
    85  		valid:         true,
    86  	}
    87  	instructionSet[SAR] = operation{
    88  		execute:       opSAR,
    89  		gasCost:       constGasFunc(GasFastestStep),
    90  		validateStack: makeStackFunc(2, 1),
    91  		valid:         true,
    92  	}
    93  	return instructionSet
    94  }
    95  
    96  // NewByzantiumInstructionSet returns the frontier, homestead and
    97  // byzantium instructions.
    98  func newByzantiumInstructionSet() [256]operation {
    99  	// instructions that can be executed during the homestead phase.
   100  	instructionSet := newHomesteadInstructionSet()
   101  	instructionSet[STATICCALL] = operation{
   102  		execute:       opStaticCall,
   103  		gasCost:       gasStaticCall,
   104  		validateStack: makeStackFunc(6, 1),
   105  		memorySize:    memoryStaticCall,
   106  		valid:         true,
   107  		returns:       true,
   108  	}
   109  	instructionSet[RETURNDATASIZE] = operation{
   110  		execute:       opReturnDataSize,
   111  		gasCost:       constGasFunc(GasQuickStep),
   112  		validateStack: makeStackFunc(0, 1),
   113  		valid:         true,
   114  	}
   115  	instructionSet[RETURNDATACOPY] = operation{
   116  		execute:       opReturnDataCopy,
   117  		gasCost:       gasReturnDataCopy,
   118  		validateStack: makeStackFunc(3, 0),
   119  		memorySize:    memoryReturnDataCopy,
   120  		valid:         true,
   121  	}
   122  	instructionSet[REVERT] = operation{
   123  		execute:       opRevert,
   124  		gasCost:       gasRevert,
   125  		validateStack: makeStackFunc(2, 0),
   126  		memorySize:    memoryRevert,
   127  		valid:         true,
   128  		reverts:       true,
   129  		returns:       true,
   130  	}
   131  	return instructionSet
   132  }
   133  
   134  // NewHomesteadInstructionSet returns the frontier and homestead
   135  // instructions that can be executed during the homestead phase.
   136  func newHomesteadInstructionSet() [256]operation {
   137  	instructionSet := newFrontierInstructionSet()
   138  	instructionSet[DELEGATECALL] = operation{
   139  		execute:       opDelegateCall,
   140  		gasCost:       gasDelegateCall,
   141  		validateStack: makeStackFunc(6, 1),
   142  		memorySize:    memoryDelegateCall,
   143  		valid:         true,
   144  		returns:       true,
   145  	}
   146  	return instructionSet
   147  }
   148  
   149  // NewFrontierInstructionSet returns the frontier instructions
   150  // that can be executed during the frontier phase.
   151  func newFrontierInstructionSet() [256]operation {
   152  	return [256]operation{
   153  		STOP: {
   154  			execute:       opStop,
   155  			gasCost:       constGasFunc(0),
   156  			validateStack: makeStackFunc(0, 0),
   157  			halts:         true,
   158  			valid:         true,
   159  		},
   160  		ADD: {
   161  			execute:       opAdd,
   162  			gasCost:       constGasFunc(GasFastestStep),
   163  			validateStack: makeStackFunc(2, 1),
   164  			valid:         true,
   165  		},
   166  		MUL: {
   167  			execute:       opMul,
   168  			gasCost:       constGasFunc(GasFastStep),
   169  			validateStack: makeStackFunc(2, 1),
   170  			valid:         true,
   171  		},
   172  		SUB: {
   173  			execute:       opSub,
   174  			gasCost:       constGasFunc(GasFastestStep),
   175  			validateStack: makeStackFunc(2, 1),
   176  			valid:         true,
   177  		},
   178  		DIV: {
   179  			execute:       opDiv,
   180  			gasCost:       constGasFunc(GasFastStep),
   181  			validateStack: makeStackFunc(2, 1),
   182  			valid:         true,
   183  		},
   184  		SDIV: {
   185  			execute:       opSdiv,
   186  			gasCost:       constGasFunc(GasFastStep),
   187  			validateStack: makeStackFunc(2, 1),
   188  			valid:         true,
   189  		},
   190  		MOD: {
   191  			execute:       opMod,
   192  			gasCost:       constGasFunc(GasFastStep),
   193  			validateStack: makeStackFunc(2, 1),
   194  			valid:         true,
   195  		},
   196  		SMOD: {
   197  			execute:       opSmod,
   198  			gasCost:       constGasFunc(GasFastStep),
   199  			validateStack: makeStackFunc(2, 1),
   200  			valid:         true,
   201  		},
   202  		ADDMOD: {
   203  			execute:       opAddmod,
   204  			gasCost:       constGasFunc(GasMidStep),
   205  			validateStack: makeStackFunc(3, 1),
   206  			valid:         true,
   207  		},
   208  		MULMOD: {
   209  			execute:       opMulmod,
   210  			gasCost:       constGasFunc(GasMidStep),
   211  			validateStack: makeStackFunc(3, 1),
   212  			valid:         true,
   213  		},
   214  		EXP: {
   215  			execute:       opExp,
   216  			gasCost:       gasExp,
   217  			validateStack: makeStackFunc(2, 1),
   218  			valid:         true,
   219  		},
   220  		SIGNEXTEND: {
   221  			execute:       opSignExtend,
   222  			gasCost:       constGasFunc(GasFastStep),
   223  			validateStack: makeStackFunc(2, 1),
   224  			valid:         true,
   225  		},
   226  		LT: {
   227  			execute:       opLt,
   228  			gasCost:       constGasFunc(GasFastestStep),
   229  			validateStack: makeStackFunc(2, 1),
   230  			valid:         true,
   231  		},
   232  		GT: {
   233  			execute:       opGt,
   234  			gasCost:       constGasFunc(GasFastestStep),
   235  			validateStack: makeStackFunc(2, 1),
   236  			valid:         true,
   237  		},
   238  		SLT: {
   239  			execute:       opSlt,
   240  			gasCost:       constGasFunc(GasFastestStep),
   241  			validateStack: makeStackFunc(2, 1),
   242  			valid:         true,
   243  		},
   244  		SGT: {
   245  			execute:       opSgt,
   246  			gasCost:       constGasFunc(GasFastestStep),
   247  			validateStack: makeStackFunc(2, 1),
   248  			valid:         true,
   249  		},
   250  		EQ: {
   251  			execute:       opEq,
   252  			gasCost:       constGasFunc(GasFastestStep),
   253  			validateStack: makeStackFunc(2, 1),
   254  			valid:         true,
   255  		},
   256  		ISZERO: {
   257  			execute:       opIszero,
   258  			gasCost:       constGasFunc(GasFastestStep),
   259  			validateStack: makeStackFunc(1, 1),
   260  			valid:         true,
   261  		},
   262  		AND: {
   263  			execute:       opAnd,
   264  			gasCost:       constGasFunc(GasFastestStep),
   265  			validateStack: makeStackFunc(2, 1),
   266  			valid:         true,
   267  		},
   268  		XOR: {
   269  			execute:       opXor,
   270  			gasCost:       constGasFunc(GasFastestStep),
   271  			validateStack: makeStackFunc(2, 1),
   272  			valid:         true,
   273  		},
   274  		OR: {
   275  			execute:       opOr,
   276  			gasCost:       constGasFunc(GasFastestStep),
   277  			validateStack: makeStackFunc(2, 1),
   278  			valid:         true,
   279  		},
   280  		NOT: {
   281  			execute:       opNot,
   282  			gasCost:       constGasFunc(GasFastestStep),
   283  			validateStack: makeStackFunc(1, 1),
   284  			valid:         true,
   285  		},
   286  		BYTE: {
   287  			execute:       opByte,
   288  			gasCost:       constGasFunc(GasFastestStep),
   289  			validateStack: makeStackFunc(2, 1),
   290  			valid:         true,
   291  		},
   292  		SHA3: {
   293  			execute:       opSha3,
   294  			gasCost:       gasSha3,
   295  			validateStack: makeStackFunc(2, 1),
   296  			memorySize:    memorySha3,
   297  			valid:         true,
   298  		},
   299  		ADDRESS: {
   300  			execute:       opAddress,
   301  			gasCost:       constGasFunc(GasQuickStep),
   302  			validateStack: makeStackFunc(0, 1),
   303  			valid:         true,
   304  		},
   305  		BALANCE: {
   306  			execute:       opBalance,
   307  			gasCost:       gasBalance,
   308  			validateStack: makeStackFunc(1, 1),
   309  			valid:         true,
   310  		},
   311  		ORIGIN: {
   312  			execute:       opOrigin,
   313  			gasCost:       constGasFunc(GasQuickStep),
   314  			validateStack: makeStackFunc(0, 1),
   315  			valid:         true,
   316  		},
   317  		CALLER: {
   318  			execute:       opCaller,
   319  			gasCost:       constGasFunc(GasQuickStep),
   320  			validateStack: makeStackFunc(0, 1),
   321  			valid:         true,
   322  		},
   323  		CALLVALUE: {
   324  			execute:       opCallValue,
   325  			gasCost:       constGasFunc(GasQuickStep),
   326  			validateStack: makeStackFunc(0, 1),
   327  			valid:         true,
   328  		},
   329  		CALLDATALOAD: {
   330  			execute:       opCallDataLoad,
   331  			gasCost:       constGasFunc(GasFastestStep),
   332  			validateStack: makeStackFunc(1, 1),
   333  			valid:         true,
   334  		},
   335  		CALLDATASIZE: {
   336  			execute:       opCallDataSize,
   337  			gasCost:       constGasFunc(GasQuickStep),
   338  			validateStack: makeStackFunc(0, 1),
   339  			valid:         true,
   340  		},
   341  		CALLDATACOPY: {
   342  			execute:       opCallDataCopy,
   343  			gasCost:       gasCallDataCopy,
   344  			validateStack: makeStackFunc(3, 0),
   345  			memorySize:    memoryCallDataCopy,
   346  			valid:         true,
   347  		},
   348  		CODESIZE: {
   349  			execute:       opCodeSize,
   350  			gasCost:       constGasFunc(GasQuickStep),
   351  			validateStack: makeStackFunc(0, 1),
   352  			valid:         true,
   353  		},
   354  		CODECOPY: {
   355  			execute:       opCodeCopy,
   356  			gasCost:       gasCodeCopy,
   357  			validateStack: makeStackFunc(3, 0),
   358  			memorySize:    memoryCodeCopy,
   359  			valid:         true,
   360  		},
   361  		GASPRICE: {
   362  			execute:       opGasprice,
   363  			gasCost:       constGasFunc(GasQuickStep),
   364  			validateStack: makeStackFunc(0, 1),
   365  			valid:         true,
   366  		},
   367  		EXTCODESIZE: {
   368  			execute:       opExtCodeSize,
   369  			gasCost:       gasExtCodeSize,
   370  			validateStack: makeStackFunc(1, 1),
   371  			valid:         true,
   372  		},
   373  		EXTCODECOPY: {
   374  			execute:       opExtCodeCopy,
   375  			gasCost:       gasExtCodeCopy,
   376  			validateStack: makeStackFunc(4, 0),
   377  			memorySize:    memoryExtCodeCopy,
   378  			valid:         true,
   379  		},
   380  		BLOCKHASH: {
   381  			execute:       opBlockhash,
   382  			gasCost:       constGasFunc(GasExtStep),
   383  			validateStack: makeStackFunc(1, 1),
   384  			valid:         true,
   385  		},
   386  		COINBASE: {
   387  			execute:       opCoinbase,
   388  			gasCost:       constGasFunc(GasQuickStep),
   389  			validateStack: makeStackFunc(0, 1),
   390  			valid:         true,
   391  		},
   392  		TIMESTAMP: {
   393  			execute:       opTimestamp,
   394  			gasCost:       constGasFunc(GasQuickStep),
   395  			validateStack: makeStackFunc(0, 1),
   396  			valid:         true,
   397  		},
   398  		NUMBER: {
   399  			execute:       opNumber,
   400  			gasCost:       constGasFunc(GasQuickStep),
   401  			validateStack: makeStackFunc(0, 1),
   402  			valid:         true,
   403  		},
   404  		DIFFICULTY: {
   405  			execute:       opDifficulty,
   406  			gasCost:       constGasFunc(GasQuickStep),
   407  			validateStack: makeStackFunc(0, 1),
   408  			valid:         true,
   409  		},
   410  		GASLIMIT: {
   411  			execute:       opGasLimit,
   412  			gasCost:       constGasFunc(GasQuickStep),
   413  			validateStack: makeStackFunc(0, 1),
   414  			valid:         true,
   415  		},
   416  		POP: {
   417  			execute:       opPop,
   418  			gasCost:       constGasFunc(GasQuickStep),
   419  			validateStack: makeStackFunc(1, 0),
   420  			valid:         true,
   421  		},
   422  		MLOAD: {
   423  			execute:       opMload,
   424  			gasCost:       gasMLoad,
   425  			validateStack: makeStackFunc(1, 1),
   426  			memorySize:    memoryMLoad,
   427  			valid:         true,
   428  		},
   429  		MSTORE: {
   430  			execute:       opMstore,
   431  			gasCost:       gasMStore,
   432  			validateStack: makeStackFunc(2, 0),
   433  			memorySize:    memoryMStore,
   434  			valid:         true,
   435  		},
   436  		MSTORE8: {
   437  			execute:       opMstore8,
   438  			gasCost:       gasMStore8,
   439  			memorySize:    memoryMStore8,
   440  			validateStack: makeStackFunc(2, 0),
   441  
   442  			valid: true,
   443  		},
   444  		SLOAD: {
   445  			execute:       opSload,
   446  			gasCost:       gasSLoad,
   447  			validateStack: makeStackFunc(1, 1),
   448  			valid:         true,
   449  		},
   450  		SSTORE: {
   451  			execute:       opSstore,
   452  			gasCost:       gasSStore,
   453  			validateStack: makeStackFunc(2, 0),
   454  			valid:         true,
   455  			writes:        true,
   456  		},
   457  		JUMP: {
   458  			execute:       opJump,
   459  			gasCost:       constGasFunc(GasMidStep),
   460  			validateStack: makeStackFunc(1, 0),
   461  			jumps:         true,
   462  			valid:         true,
   463  		},
   464  		JUMPI: {
   465  			execute:       opJumpi,
   466  			gasCost:       constGasFunc(GasSlowStep),
   467  			validateStack: makeStackFunc(2, 0),
   468  			jumps:         true,
   469  			valid:         true,
   470  		},
   471  		PC: {
   472  			execute:       opPc,
   473  			gasCost:       constGasFunc(GasQuickStep),
   474  			validateStack: makeStackFunc(0, 1),
   475  			valid:         true,
   476  		},
   477  		MSIZE: {
   478  			execute:       opMsize,
   479  			gasCost:       constGasFunc(GasQuickStep),
   480  			validateStack: makeStackFunc(0, 1),
   481  			valid:         true,
   482  		},
   483  		GAS: {
   484  			execute:       opGas,
   485  			gasCost:       constGasFunc(GasQuickStep),
   486  			validateStack: makeStackFunc(0, 1),
   487  			valid:         true,
   488  		},
   489  		JUMPDEST: {
   490  			execute:       opJumpdest,
   491  			gasCost:       constGasFunc(params.JumpdestGas),
   492  			validateStack: makeStackFunc(0, 0),
   493  			valid:         true,
   494  		},
   495  		PUSH1: {
   496  			execute:       makePush(1, 1),
   497  			gasCost:       gasPush,
   498  			validateStack: makeStackFunc(0, 1),
   499  			valid:         true,
   500  		},
   501  		PUSH2: {
   502  			execute:       makePush(2, 2),
   503  			gasCost:       gasPush,
   504  			validateStack: makeStackFunc(0, 1),
   505  			valid:         true,
   506  		},
   507  		PUSH3: {
   508  			execute:       makePush(3, 3),
   509  			gasCost:       gasPush,
   510  			validateStack: makeStackFunc(0, 1),
   511  			valid:         true,
   512  		},
   513  		PUSH4: {
   514  			execute:       makePush(4, 4),
   515  			gasCost:       gasPush,
   516  			validateStack: makeStackFunc(0, 1),
   517  			valid:         true,
   518  		},
   519  		PUSH5: {
   520  			execute:       makePush(5, 5),
   521  			gasCost:       gasPush,
   522  			validateStack: makeStackFunc(0, 1),
   523  			valid:         true,
   524  		},
   525  		PUSH6: {
   526  			execute:       makePush(6, 6),
   527  			gasCost:       gasPush,
   528  			validateStack: makeStackFunc(0, 1),
   529  			valid:         true,
   530  		},
   531  		PUSH7: {
   532  			execute:       makePush(7, 7),
   533  			gasCost:       gasPush,
   534  			validateStack: makeStackFunc(0, 1),
   535  			valid:         true,
   536  		},
   537  		PUSH8: {
   538  			execute:       makePush(8, 8),
   539  			gasCost:       gasPush,
   540  			validateStack: makeStackFunc(0, 1),
   541  			valid:         true,
   542  		},
   543  		PUSH9: {
   544  			execute:       makePush(9, 9),
   545  			gasCost:       gasPush,
   546  			validateStack: makeStackFunc(0, 1),
   547  			valid:         true,
   548  		},
   549  		PUSH10: {
   550  			execute:       makePush(10, 10),
   551  			gasCost:       gasPush,
   552  			validateStack: makeStackFunc(0, 1),
   553  			valid:         true,
   554  		},
   555  		PUSH11: {
   556  			execute:       makePush(11, 11),
   557  			gasCost:       gasPush,
   558  			validateStack: makeStackFunc(0, 1),
   559  			valid:         true,
   560  		},
   561  		PUSH12: {
   562  			execute:       makePush(12, 12),
   563  			gasCost:       gasPush,
   564  			validateStack: makeStackFunc(0, 1),
   565  			valid:         true,
   566  		},
   567  		PUSH13: {
   568  			execute:       makePush(13, 13),
   569  			gasCost:       gasPush,
   570  			validateStack: makeStackFunc(0, 1),
   571  			valid:         true,
   572  		},
   573  		PUSH14: {
   574  			execute:       makePush(14, 14),
   575  			gasCost:       gasPush,
   576  			validateStack: makeStackFunc(0, 1),
   577  			valid:         true,
   578  		},
   579  		PUSH15: {
   580  			execute:       makePush(15, 15),
   581  			gasCost:       gasPush,
   582  			validateStack: makeStackFunc(0, 1),
   583  			valid:         true,
   584  		},
   585  		PUSH16: {
   586  			execute:       makePush(16, 16),
   587  			gasCost:       gasPush,
   588  			validateStack: makeStackFunc(0, 1),
   589  			valid:         true,
   590  		},
   591  		PUSH17: {
   592  			execute:       makePush(17, 17),
   593  			gasCost:       gasPush,
   594  			validateStack: makeStackFunc(0, 1),
   595  			valid:         true,
   596  		},
   597  		PUSH18: {
   598  			execute:       makePush(18, 18),
   599  			gasCost:       gasPush,
   600  			validateStack: makeStackFunc(0, 1),
   601  			valid:         true,
   602  		},
   603  		PUSH19: {
   604  			execute:       makePush(19, 19),
   605  			gasCost:       gasPush,
   606  			validateStack: makeStackFunc(0, 1),
   607  			valid:         true,
   608  		},
   609  		PUSH20: {
   610  			execute:       makePush(20, 20),
   611  			gasCost:       gasPush,
   612  			validateStack: makeStackFunc(0, 1),
   613  			valid:         true,
   614  		},
   615  		PUSH21: {
   616  			execute:       makePush(21, 21),
   617  			gasCost:       gasPush,
   618  			validateStack: makeStackFunc(0, 1),
   619  			valid:         true,
   620  		},
   621  		PUSH22: {
   622  			execute:       makePush(22, 22),
   623  			gasCost:       gasPush,
   624  			validateStack: makeStackFunc(0, 1),
   625  			valid:         true,
   626  		},
   627  		PUSH23: {
   628  			execute:       makePush(23, 23),
   629  			gasCost:       gasPush,
   630  			validateStack: makeStackFunc(0, 1),
   631  			valid:         true,
   632  		},
   633  		PUSH24: {
   634  			execute:       makePush(24, 24),
   635  			gasCost:       gasPush,
   636  			validateStack: makeStackFunc(0, 1),
   637  			valid:         true,
   638  		},
   639  		PUSH25: {
   640  			execute:       makePush(25, 25),
   641  			gasCost:       gasPush,
   642  			validateStack: makeStackFunc(0, 1),
   643  			valid:         true,
   644  		},
   645  		PUSH26: {
   646  			execute:       makePush(26, 26),
   647  			gasCost:       gasPush,
   648  			validateStack: makeStackFunc(0, 1),
   649  			valid:         true,
   650  		},
   651  		PUSH27: {
   652  			execute:       makePush(27, 27),
   653  			gasCost:       gasPush,
   654  			validateStack: makeStackFunc(0, 1),
   655  			valid:         true,
   656  		},
   657  		PUSH28: {
   658  			execute:       makePush(28, 28),
   659  			gasCost:       gasPush,
   660  			validateStack: makeStackFunc(0, 1),
   661  			valid:         true,
   662  		},
   663  		PUSH29: {
   664  			execute:       makePush(29, 29),
   665  			gasCost:       gasPush,
   666  			validateStack: makeStackFunc(0, 1),
   667  			valid:         true,
   668  		},
   669  		PUSH30: {
   670  			execute:       makePush(30, 30),
   671  			gasCost:       gasPush,
   672  			validateStack: makeStackFunc(0, 1),
   673  			valid:         true,
   674  		},
   675  		PUSH31: {
   676  			execute:       makePush(31, 31),
   677  			gasCost:       gasPush,
   678  			validateStack: makeStackFunc(0, 1),
   679  			valid:         true,
   680  		},
   681  		PUSH32: {
   682  			execute:       makePush(32, 32),
   683  			gasCost:       gasPush,
   684  			validateStack: makeStackFunc(0, 1),
   685  			valid:         true,
   686  		},
   687  		DUP1: {
   688  			execute:       makeDup(1),
   689  			gasCost:       gasDup,
   690  			validateStack: makeDupStackFunc(1),
   691  			valid:         true,
   692  		},
   693  		DUP2: {
   694  			execute:       makeDup(2),
   695  			gasCost:       gasDup,
   696  			validateStack: makeDupStackFunc(2),
   697  			valid:         true,
   698  		},
   699  		DUP3: {
   700  			execute:       makeDup(3),
   701  			gasCost:       gasDup,
   702  			validateStack: makeDupStackFunc(3),
   703  			valid:         true,
   704  		},
   705  		DUP4: {
   706  			execute:       makeDup(4),
   707  			gasCost:       gasDup,
   708  			validateStack: makeDupStackFunc(4),
   709  			valid:         true,
   710  		},
   711  		DUP5: {
   712  			execute:       makeDup(5),
   713  			gasCost:       gasDup,
   714  			validateStack: makeDupStackFunc(5),
   715  			valid:         true,
   716  		},
   717  		DUP6: {
   718  			execute:       makeDup(6),
   719  			gasCost:       gasDup,
   720  			validateStack: makeDupStackFunc(6),
   721  			valid:         true,
   722  		},
   723  		DUP7: {
   724  			execute:       makeDup(7),
   725  			gasCost:       gasDup,
   726  			validateStack: makeDupStackFunc(7),
   727  			valid:         true,
   728  		},
   729  		DUP8: {
   730  			execute:       makeDup(8),
   731  			gasCost:       gasDup,
   732  			validateStack: makeDupStackFunc(8),
   733  			valid:         true,
   734  		},
   735  		DUP9: {
   736  			execute:       makeDup(9),
   737  			gasCost:       gasDup,
   738  			validateStack: makeDupStackFunc(9),
   739  			valid:         true,
   740  		},
   741  		DUP10: {
   742  			execute:       makeDup(10),
   743  			gasCost:       gasDup,
   744  			validateStack: makeDupStackFunc(10),
   745  			valid:         true,
   746  		},
   747  		DUP11: {
   748  			execute:       makeDup(11),
   749  			gasCost:       gasDup,
   750  			validateStack: makeDupStackFunc(11),
   751  			valid:         true,
   752  		},
   753  		DUP12: {
   754  			execute:       makeDup(12),
   755  			gasCost:       gasDup,
   756  			validateStack: makeDupStackFunc(12),
   757  			valid:         true,
   758  		},
   759  		DUP13: {
   760  			execute:       makeDup(13),
   761  			gasCost:       gasDup,
   762  			validateStack: makeDupStackFunc(13),
   763  			valid:         true,
   764  		},
   765  		DUP14: {
   766  			execute:       makeDup(14),
   767  			gasCost:       gasDup,
   768  			validateStack: makeDupStackFunc(14),
   769  			valid:         true,
   770  		},
   771  		DUP15: {
   772  			execute:       makeDup(15),
   773  			gasCost:       gasDup,
   774  			validateStack: makeDupStackFunc(15),
   775  			valid:         true,
   776  		},
   777  		DUP16: {
   778  			execute:       makeDup(16),
   779  			gasCost:       gasDup,
   780  			validateStack: makeDupStackFunc(16),
   781  			valid:         true,
   782  		},
   783  		SWAP1: {
   784  			execute:       makeSwap(1),
   785  			gasCost:       gasSwap,
   786  			validateStack: makeSwapStackFunc(2),
   787  			valid:         true,
   788  		},
   789  		SWAP2: {
   790  			execute:       makeSwap(2),
   791  			gasCost:       gasSwap,
   792  			validateStack: makeSwapStackFunc(3),
   793  			valid:         true,
   794  		},
   795  		SWAP3: {
   796  			execute:       makeSwap(3),
   797  			gasCost:       gasSwap,
   798  			validateStack: makeSwapStackFunc(4),
   799  			valid:         true,
   800  		},
   801  		SWAP4: {
   802  			execute:       makeSwap(4),
   803  			gasCost:       gasSwap,
   804  			validateStack: makeSwapStackFunc(5),
   805  			valid:         true,
   806  		},
   807  		SWAP5: {
   808  			execute:       makeSwap(5),
   809  			gasCost:       gasSwap,
   810  			validateStack: makeSwapStackFunc(6),
   811  			valid:         true,
   812  		},
   813  		SWAP6: {
   814  			execute:       makeSwap(6),
   815  			gasCost:       gasSwap,
   816  			validateStack: makeSwapStackFunc(7),
   817  			valid:         true,
   818  		},
   819  		SWAP7: {
   820  			execute:       makeSwap(7),
   821  			gasCost:       gasSwap,
   822  			validateStack: makeSwapStackFunc(8),
   823  			valid:         true,
   824  		},
   825  		SWAP8: {
   826  			execute:       makeSwap(8),
   827  			gasCost:       gasSwap,
   828  			validateStack: makeSwapStackFunc(9),
   829  			valid:         true,
   830  		},
   831  		SWAP9: {
   832  			execute:       makeSwap(9),
   833  			gasCost:       gasSwap,
   834  			validateStack: makeSwapStackFunc(10),
   835  			valid:         true,
   836  		},
   837  		SWAP10: {
   838  			execute:       makeSwap(10),
   839  			gasCost:       gasSwap,
   840  			validateStack: makeSwapStackFunc(11),
   841  			valid:         true,
   842  		},
   843  		SWAP11: {
   844  			execute:       makeSwap(11),
   845  			gasCost:       gasSwap,
   846  			validateStack: makeSwapStackFunc(12),
   847  			valid:         true,
   848  		},
   849  		SWAP12: {
   850  			execute:       makeSwap(12),
   851  			gasCost:       gasSwap,
   852  			validateStack: makeSwapStackFunc(13),
   853  			valid:         true,
   854  		},
   855  		SWAP13: {
   856  			execute:       makeSwap(13),
   857  			gasCost:       gasSwap,
   858  			validateStack: makeSwapStackFunc(14),
   859  			valid:         true,
   860  		},
   861  		SWAP14: {
   862  			execute:       makeSwap(14),
   863  			gasCost:       gasSwap,
   864  			validateStack: makeSwapStackFunc(15),
   865  			valid:         true,
   866  		},
   867  		SWAP15: {
   868  			execute:       makeSwap(15),
   869  			gasCost:       gasSwap,
   870  			validateStack: makeSwapStackFunc(16),
   871  			valid:         true,
   872  		},
   873  		SWAP16: {
   874  			execute:       makeSwap(16),
   875  			gasCost:       gasSwap,
   876  			validateStack: makeSwapStackFunc(17),
   877  			valid:         true,
   878  		},
   879  		LOG0: {
   880  			execute:       makeLog(0),
   881  			gasCost:       makeGasLog(0),
   882  			validateStack: makeStackFunc(2, 0),
   883  			memorySize:    memoryLog,
   884  			valid:         true,
   885  			writes:        true,
   886  		},
   887  		LOG1: {
   888  			execute:       makeLog(1),
   889  			gasCost:       makeGasLog(1),
   890  			validateStack: makeStackFunc(3, 0),
   891  			memorySize:    memoryLog,
   892  			valid:         true,
   893  			writes:        true,
   894  		},
   895  		LOG2: {
   896  			execute:       makeLog(2),
   897  			gasCost:       makeGasLog(2),
   898  			validateStack: makeStackFunc(4, 0),
   899  			memorySize:    memoryLog,
   900  			valid:         true,
   901  			writes:        true,
   902  		},
   903  		LOG3: {
   904  			execute:       makeLog(3),
   905  			gasCost:       makeGasLog(3),
   906  			validateStack: makeStackFunc(5, 0),
   907  			memorySize:    memoryLog,
   908  			valid:         true,
   909  			writes:        true,
   910  		},
   911  		LOG4: {
   912  			execute:       makeLog(4),
   913  			gasCost:       makeGasLog(4),
   914  			validateStack: makeStackFunc(6, 0),
   915  			memorySize:    memoryLog,
   916  			valid:         true,
   917  			writes:        true,
   918  		},
   919  		CREATE: {
   920  			execute:       opCreate,
   921  			gasCost:       gasCreate,
   922  			validateStack: makeStackFunc(3, 1),
   923  			memorySize:    memoryCreate,
   924  			valid:         true,
   925  			writes:        true,
   926  			returns:       true,
   927  		},
   928  		CALL: {
   929  			execute:       opCall,
   930  			gasCost:       gasCall,
   931  			validateStack: makeStackFunc(7, 1),
   932  			memorySize:    memoryCall,
   933  			valid:         true,
   934  			returns:       true,
   935  		},
   936  		CALLCODE: {
   937  			execute:       opCallCode,
   938  			gasCost:       gasCallCode,
   939  			validateStack: makeStackFunc(7, 1),
   940  			memorySize:    memoryCall,
   941  			valid:         true,
   942  			returns:       true,
   943  		},
   944  		RETURN: {
   945  			execute:       opReturn,
   946  			gasCost:       gasReturn,
   947  			validateStack: makeStackFunc(2, 0),
   948  			memorySize:    memoryReturn,
   949  			halts:         true,
   950  			valid:         true,
   951  		},
   952  		SELFDESTRUCT: {
   953  			execute:       opSuicide,
   954  			gasCost:       gasSuicide,
   955  			validateStack: makeStackFunc(1, 0),
   956  			halts:         true,
   957  			valid:         true,
   958  			writes:        true,
   959  		},
   960  	}
   961  }