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