From e5b7430e92935945b62158b21ceaf6c695104a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20IRMAK?= Date: Sun, 22 Jun 2025 14:14:10 +0300 Subject: [PATCH] core/vm: remove pointers from JumpTable --- core/vm/eips.go | 54 ++++++++++++++--------------- core/vm/interpreter.go | 8 ++--- core/vm/jump_table.go | 79 ++++++++++++++++-------------------------- 3 files changed, 61 insertions(+), 80 deletions(-) diff --git a/core/vm/eips.go b/core/vm/eips.go index caa73e4391..851cbbb6e1 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -81,7 +81,7 @@ func enable1884(jt *JumpTable) { jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 // New opcode - jt[SELFBALANCE] = &operation{ + jt[SELFBALANCE] = operation{ execute: opSelfBalance, constantGas: GasFastStep, } @@ -96,7 +96,7 @@ func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) // - Adds an opcode that returns the current chain’s EIP-155 unique identifier func enable1344(jt *JumpTable) { // New opcode - jt[CHAINID] = &operation{ + jt[CHAINID] = operation{ execute: opChainID, constantGas: GasQuickStep, } @@ -165,7 +165,7 @@ func enable3529(jt *JumpTable) { // - Adds an opcode that returns the current block's base fee. func enable3198(jt *JumpTable) { // New opcode - jt[BASEFEE] = &operation{ + jt[BASEFEE] = operation{ execute: opBaseFee, constantGas: GasQuickStep, } @@ -175,12 +175,12 @@ func enable3198(jt *JumpTable) { // - Adds TLOAD that reads from transient storage // - Adds TSTORE that writes to transient storage func enable1153(jt *JumpTable) { - jt[TLOAD] = &operation{ + jt[TLOAD] = operation{ execute: opTload, constantGas: params.WarmStorageReadCostEIP2929, } - jt[TSTORE] = &operation{ + jt[TSTORE] = operation{ execute: opTstore, constantGas: params.WarmStorageReadCostEIP2929, } @@ -222,7 +222,7 @@ func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] // enable3855 applies EIP-3855 (PUSH0 opcode) func enable3855(jt *JumpTable) { // New opcode - jt[PUSH0] = &operation{ + jt[PUSH0] = operation{ execute: opPush0, constantGas: GasQuickStep, } @@ -243,7 +243,7 @@ func enable3860(jt *JumpTable) { // enable5656 enables EIP-5656 (MCOPY opcode) // https://eips.ethereum.org/EIPS/eip-5656 func enable5656(jt *JumpTable) { - jt[MCOPY] = &operation{ + jt[MCOPY] = operation{ execute: opMcopy, constantGas: GasFastestStep, } @@ -314,7 +314,7 @@ func opCLZ(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte // enable4844 applies EIP-4844 (BLOBHASH opcode) func enable4844(jt *JumpTable) { - jt[BLOBHASH] = &operation{ + jt[BLOBHASH] = operation{ execute: opBlobHash, constantGas: GasFastestStep, } @@ -322,7 +322,7 @@ func enable4844(jt *JumpTable) { // enable7939 enables EIP-7939 (CLZ opcode) func enable7939(jt *JumpTable) { - jt[CLZ] = &operation{ + jt[CLZ] = operation{ execute: opCLZ, constantGas: GasFastStep, } @@ -330,7 +330,7 @@ func enable7939(jt *JumpTable) { // enable7516 applies EIP-7516 (BLOBBASEFEE opcode) func enable7516(jt *JumpTable) { - jt[BLOBBASEFEE] = &operation{ + jt[BLOBBASEFEE] = operation{ execute: opBlobBaseFee, constantGas: GasQuickStep, } @@ -338,7 +338,7 @@ func enable7516(jt *JumpTable) { // enable6780 applies EIP-6780 (deactivate SELFDESTRUCT) func enable6780(jt *JumpTable) { - jt[SELFDESTRUCT] = &operation{ + jt[SELFDESTRUCT] = operation{ execute: opSelfdestructEIP6780, constantGas: params.SelfdestructGasEIP150, } @@ -440,71 +440,71 @@ func makePushEIP4762(size uint64, pushByteSize int) executionFunc { } func enable4762(jt *JumpTable) { - jt[SSTORE] = &operation{ + jt[SSTORE] = operation{ execute: opSstoreEIP4762, } - jt[SLOAD] = &operation{ + jt[SLOAD] = operation{ execute: opSLoadEIP4762, } - jt[BALANCE] = &operation{ + jt[BALANCE] = operation{ execute: opBalanceEIP4762, } - jt[EXTCODESIZE] = &operation{ + jt[EXTCODESIZE] = operation{ execute: opExtCodeSizeEIP4762, } - jt[EXTCODEHASH] = &operation{ + jt[EXTCODEHASH] = operation{ execute: opExtCodeHashEIP4762, } - jt[EXTCODECOPY] = &operation{ + jt[EXTCODECOPY] = operation{ execute: opExtCodeCopyEIP4762, } - jt[CODECOPY] = &operation{ + jt[CODECOPY] = operation{ execute: opCodeCopyEIP4762, constantGas: GasFastestStep, } - jt[SELFDESTRUCT] = &operation{ + jt[SELFDESTRUCT] = operation{ execute: opSelfdestructEIP4762, constantGas: params.SelfdestructGasEIP150, } - jt[CREATE] = &operation{ + jt[CREATE] = operation{ execute: opCreateEIP3860, constantGas: params.CreateNGasEip4762, } - jt[CREATE2] = &operation{ + jt[CREATE2] = operation{ execute: opCreate2EIP3860, constantGas: params.CreateNGasEip4762, } - jt[CALL] = &operation{ + jt[CALL] = operation{ execute: opCallEIP4762, } - jt[CALLCODE] = &operation{ + jt[CALLCODE] = operation{ execute: opCallCodeEIP4762, } - jt[STATICCALL] = &operation{ + jt[STATICCALL] = operation{ execute: opStaticCallEIP4762, } - jt[DELEGATECALL] = &operation{ + jt[DELEGATECALL] = operation{ execute: opDelegateCallEIP4762, } - jt[PUSH1] = &operation{ + jt[PUSH1] = operation{ execute: opPush1EIP4762, constantGas: GasFastestStep, } for i := 1; i < 32; i++ { - jt[PUSH1+OpCode(i)] = &operation{ + jt[PUSH1+OpCode(i)] = operation{ execute: makePushEIP4762(uint64(i+1), i+1), constantGas: GasFastestStep, } diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index d3b1c083c4..43cebe1b58 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -149,8 +149,8 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter { } } if evm.Config.Tracer.HooksVM() { - for _, op := range table { - op.execute = executeWithTracer(&evm.Config.Tracer, op.execute) + for i := range table { + table[i].execute = executeWithTracer(&evm.Config.Tracer, table[i].execute) } } @@ -163,7 +163,7 @@ func executeWithTracer(tracer *tracing.Hooks, execF executionFunc) executionFunc return func(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) { pcCopy := *pc op := callContext.Contract.GetOp(pcCopy) - operation := interpreter.table[op] + operation := &interpreter.table[op] cost := operation.constantGas gasCopy := callContext.Contract.Gas + cost @@ -263,7 +263,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // Get the operation from the jump table op = contract.GetOp(pc) - operation := jumpTable[op] + operation := &jumpTable[op] cost = operation.constantGas // For tracing // for tracing: this gas consumption event is emitted in the executeWithTracer wrapper. if contract.Gas < cost { diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 18a9f47058..7314f2446a 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -17,8 +17,6 @@ package vm import ( - "fmt" - "github.com/ethereum/go-ethereum/params" ) @@ -28,8 +26,6 @@ type operation struct { // execute is the operation function execute executionFunc constantGas uint64 - // undefined denotes if the instruction is not officially defined in the jump table - undefined bool } var ( @@ -51,33 +47,24 @@ var ( ) // JumpTable contains the EVM opcodes supported at a given fork. -type JumpTable [256]*operation - -func validate(jt JumpTable) JumpTable { - for i, op := range jt { - if op == nil { - panic(fmt.Sprintf("op %#x is not set", i)) - } - } - return jt -} +type JumpTable [256]operation func newVerkleInstructionSet() JumpTable { instructionSet := newShanghaiInstructionSet() enable4762(&instructionSet) - return validate(instructionSet) + return instructionSet } func newOsakaInstructionSet() JumpTable { instructionSet := newPragueInstructionSet() enable7939(&instructionSet) // EIP-7939 (CLZ opcode) - return validate(instructionSet) + return instructionSet } func newPragueInstructionSet() JumpTable { instructionSet := newCancunInstructionSet() enable7702(&instructionSet) // EIP-7702 Setcode transaction type - return validate(instructionSet) + return instructionSet } func newCancunInstructionSet() JumpTable { @@ -87,7 +74,7 @@ func newCancunInstructionSet() JumpTable { enable1153(&instructionSet) // EIP-1153 "Transient Storage" enable5656(&instructionSet) // EIP-5656 (MCOPY opcode) enable6780(&instructionSet) // EIP-6780 SELFDESTRUCT only in same transaction - return validate(instructionSet) + return instructionSet } func newShanghaiInstructionSet() JumpTable { @@ -95,16 +82,16 @@ func newShanghaiInstructionSet() JumpTable { enable3855(&instructionSet) // PUSH0 instruction enable3860(&instructionSet) // Limit and meter initcode - return validate(instructionSet) + return instructionSet } func newMergeInstructionSet() JumpTable { instructionSet := newLondonInstructionSet() - instructionSet[PREVRANDAO] = &operation{ + instructionSet[PREVRANDAO] = operation{ execute: opRandom, constantGas: GasQuickStep, } - return validate(instructionSet) + return instructionSet } // newLondonInstructionSet returns the frontier, homestead, byzantium, @@ -113,7 +100,7 @@ func newLondonInstructionSet() JumpTable { instructionSet := newBerlinInstructionSet() enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529 enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198 - return validate(instructionSet) + return instructionSet } // newBerlinInstructionSet returns the frontier, homestead, byzantium, @@ -121,7 +108,7 @@ func newLondonInstructionSet() JumpTable { func newBerlinInstructionSet() JumpTable { instructionSet := newIstanbulInstructionSet() enable2929(&instructionSet) // Gas cost increases for state access opcodes https://eips.ethereum.org/EIPS/eip-2929 - return validate(instructionSet) + return instructionSet } // newIstanbulInstructionSet returns the frontier, homestead, byzantium, @@ -133,63 +120,63 @@ func newIstanbulInstructionSet() JumpTable { enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884 enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200 - return validate(instructionSet) + return instructionSet } // newConstantinopleInstructionSet returns the frontier, homestead, // byzantium and constantinople instructions. func newConstantinopleInstructionSet() JumpTable { instructionSet := newByzantiumInstructionSet() - instructionSet[SHL] = &operation{ + instructionSet[SHL] = operation{ execute: opSHL, constantGas: GasFastestStep, } - instructionSet[SHR] = &operation{ + instructionSet[SHR] = operation{ execute: opSHR, constantGas: GasFastestStep, } - instructionSet[SAR] = &operation{ + instructionSet[SAR] = operation{ execute: opSAR, constantGas: GasFastestStep, } - instructionSet[EXTCODEHASH] = &operation{ + instructionSet[EXTCODEHASH] = operation{ execute: opExtCodeHashConstantinople, constantGas: params.ExtcodeHashGasConstantinople, } - instructionSet[CREATE2] = &operation{ + instructionSet[CREATE2] = operation{ execute: opCreate2Constantinople, constantGas: params.Create2Gas, } - return validate(instructionSet) + return instructionSet } // newByzantiumInstructionSet returns the frontier, homestead and // byzantium instructions. func newByzantiumInstructionSet() JumpTable { instructionSet := newSpuriousDragonInstructionSet() - instructionSet[STATICCALL] = &operation{ + instructionSet[STATICCALL] = operation{ execute: opStaticCallByzantium, constantGas: params.CallGasEIP150, } - instructionSet[RETURNDATASIZE] = &operation{ + instructionSet[RETURNDATASIZE] = operation{ execute: opReturnDataSize, constantGas: GasQuickStep, } - instructionSet[RETURNDATACOPY] = &operation{ + instructionSet[RETURNDATACOPY] = operation{ execute: opReturnDataCopy, constantGas: GasFastestStep, } - instructionSet[REVERT] = &operation{ + instructionSet[REVERT] = operation{ execute: opRevert, } - return validate(instructionSet) + return instructionSet } // EIP 158 a.k.a Spurious Dragon func newSpuriousDragonInstructionSet() JumpTable { instructionSet := newTangerineWhistleInstructionSet() instructionSet[EXP].execute = opExpEIP158 - return validate(instructionSet) + return instructionSet } // EIP 150 a.k.a Tangerine Whistle @@ -202,18 +189,18 @@ func newTangerineWhistleInstructionSet() JumpTable { instructionSet[CALL].constantGas = params.CallGasEIP150 instructionSet[CALLCODE].constantGas = params.CallGasEIP150 instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150 - return validate(instructionSet) + return instructionSet } // newHomesteadInstructionSet returns the frontier and homestead // instructions that can be executed during the homestead phase. func newHomesteadInstructionSet() JumpTable { instructionSet := newFrontierInstructionSet() - instructionSet[DELEGATECALL] = &operation{ + instructionSet[DELEGATECALL] = operation{ execute: opDelegateCallHomestead, constantGas: params.CallGasFrontier, } - return validate(instructionSet) + return instructionSet } // newFrontierInstructionSet returns the frontier instructions @@ -733,22 +720,16 @@ func newFrontierInstructionSet() JumpTable { } // Fill all unassigned slots with opUndefined. - for i, entry := range tbl { - if entry == nil { - tbl[i] = &operation{execute: opUndefined, undefined: true} + for i := range tbl { + if tbl[i].execute == nil { + tbl[i] = operation{execute: opUndefined} } } - return validate(tbl) + return tbl } func copyJumpTable(source *JumpTable) *JumpTable { dest := *source - for i, op := range source { - if op != nil { - opCopy := *op - dest[i] = &opCopy - } - } return &dest }