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