github.com/amazechain/amc@v0.1.3/internal/vm/jump_table.go (about)

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