github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/core/vm/jump_table.go (about)

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