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