github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/core/vm/jump_table.go (about)

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