core/vm: remove pointers from JumpTable

no reason for them to be pointers since they are all non-nil.
Remove unused "undefined" bit as well.
This commit is contained in:
Ömer Faruk IRMAK 2025-06-22 14:14:10 +03:00
parent e6b9d0c2b6
commit db62f8a6a7
3 changed files with 43 additions and 55 deletions

View file

@ -81,7 +81,7 @@ func enable1884(jt *JumpTable) {
jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884
// New opcode // New opcode
jt[SELFBALANCE] = &operation{ jt[SELFBALANCE] = operation{
execute: opSelfBalance, execute: opSelfBalance,
constantGas: GasFastStep, constantGas: GasFastStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),
@ -99,7 +99,7 @@ func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
// - Adds an opcode that returns the current chains EIP-155 unique identifier // - Adds an opcode that returns the current chains EIP-155 unique identifier
func enable1344(jt *JumpTable) { func enable1344(jt *JumpTable) {
// New opcode // New opcode
jt[CHAINID] = &operation{ jt[CHAINID] = operation{
execute: opChainID, execute: opChainID,
constantGas: GasQuickStep, constantGas: GasQuickStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),
@ -171,7 +171,7 @@ func enable3529(jt *JumpTable) {
// - Adds an opcode that returns the current block's base fee. // - Adds an opcode that returns the current block's base fee.
func enable3198(jt *JumpTable) { func enable3198(jt *JumpTable) {
// New opcode // New opcode
jt[BASEFEE] = &operation{ jt[BASEFEE] = operation{
execute: opBaseFee, execute: opBaseFee,
constantGas: GasQuickStep, constantGas: GasQuickStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),
@ -183,14 +183,14 @@ func enable3198(jt *JumpTable) {
// - Adds TLOAD that reads from transient storage // - Adds TLOAD that reads from transient storage
// - Adds TSTORE that writes to transient storage // - Adds TSTORE that writes to transient storage
func enable1153(jt *JumpTable) { func enable1153(jt *JumpTable) {
jt[TLOAD] = &operation{ jt[TLOAD] = operation{
execute: opTload, execute: opTload,
constantGas: params.WarmStorageReadCostEIP2929, constantGas: params.WarmStorageReadCostEIP2929,
minStack: minStack(1, 1), minStack: minStack(1, 1),
maxStack: maxStack(1, 1), maxStack: maxStack(1, 1),
} }
jt[TSTORE] = &operation{ jt[TSTORE] = operation{
execute: opTstore, execute: opTstore,
constantGas: params.WarmStorageReadCostEIP2929, constantGas: params.WarmStorageReadCostEIP2929,
minStack: minStack(2, 0), minStack: minStack(2, 0),
@ -228,7 +228,7 @@ func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
// enable3855 applies EIP-3855 (PUSH0 opcode) // enable3855 applies EIP-3855 (PUSH0 opcode)
func enable3855(jt *JumpTable) { func enable3855(jt *JumpTable) {
// New opcode // New opcode
jt[PUSH0] = &operation{ jt[PUSH0] = operation{
execute: opPush0, execute: opPush0,
constantGas: GasQuickStep, constantGas: GasQuickStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),
@ -252,7 +252,7 @@ func enable3860(jt *JumpTable) {
// enable5656 enables EIP-5656 (MCOPY opcode) // enable5656 enables EIP-5656 (MCOPY opcode)
// https://eips.ethereum.org/EIPS/eip-5656 // https://eips.ethereum.org/EIPS/eip-5656
func enable5656(jt *JumpTable) { func enable5656(jt *JumpTable) {
jt[MCOPY] = &operation{ jt[MCOPY] = operation{
execute: opMcopy, execute: opMcopy,
constantGas: GasFastestStep, constantGas: GasFastestStep,
dynamicGas: gasMcopy, dynamicGas: gasMcopy,
@ -303,7 +303,7 @@ func opCLZ(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte
// enable4844 applies EIP-4844 (BLOBHASH opcode) // enable4844 applies EIP-4844 (BLOBHASH opcode)
func enable4844(jt *JumpTable) { func enable4844(jt *JumpTable) {
jt[BLOBHASH] = &operation{ jt[BLOBHASH] = operation{
execute: opBlobHash, execute: opBlobHash,
constantGas: GasFastestStep, constantGas: GasFastestStep,
minStack: minStack(1, 1), minStack: minStack(1, 1),
@ -313,7 +313,7 @@ func enable4844(jt *JumpTable) {
// enable7939 enables EIP-7939 (CLZ opcode) // enable7939 enables EIP-7939 (CLZ opcode)
func enable7939(jt *JumpTable) { func enable7939(jt *JumpTable) {
jt[CLZ] = &operation{ jt[CLZ] = operation{
execute: opCLZ, execute: opCLZ,
constantGas: GasFastStep, constantGas: GasFastStep,
minStack: minStack(1, 1), minStack: minStack(1, 1),
@ -323,7 +323,7 @@ func enable7939(jt *JumpTable) {
// enable7516 applies EIP-7516 (BLOBBASEFEE opcode) // enable7516 applies EIP-7516 (BLOBBASEFEE opcode)
func enable7516(jt *JumpTable) { func enable7516(jt *JumpTable) {
jt[BLOBBASEFEE] = &operation{ jt[BLOBBASEFEE] = operation{
execute: opBlobBaseFee, execute: opBlobBaseFee,
constantGas: GasQuickStep, constantGas: GasQuickStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),
@ -333,7 +333,7 @@ func enable7516(jt *JumpTable) {
// enable6780 applies EIP-6780 (deactivate SELFDESTRUCT) // enable6780 applies EIP-6780 (deactivate SELFDESTRUCT)
func enable6780(jt *JumpTable) { func enable6780(jt *JumpTable) {
jt[SELFDESTRUCT] = &operation{ jt[SELFDESTRUCT] = operation{
execute: opSelfdestruct6780, execute: opSelfdestruct6780,
dynamicGas: gasSelfdestructEIP3529, dynamicGas: gasSelfdestructEIP3529,
constantGas: params.SelfdestructGasEIP150, constantGas: params.SelfdestructGasEIP150,
@ -424,41 +424,41 @@ func makePushEIP4762(size uint64, pushByteSize int) executionFunc {
} }
func enable4762(jt *JumpTable) { func enable4762(jt *JumpTable) {
jt[SSTORE] = &operation{ jt[SSTORE] = operation{
dynamicGas: gasSStore4762, dynamicGas: gasSStore4762,
execute: opSstore, execute: opSstore,
minStack: minStack(2, 0), minStack: minStack(2, 0),
maxStack: maxStack(2, 0), maxStack: maxStack(2, 0),
} }
jt[SLOAD] = &operation{ jt[SLOAD] = operation{
dynamicGas: gasSLoad4762, dynamicGas: gasSLoad4762,
execute: opSload, execute: opSload,
minStack: minStack(1, 1), minStack: minStack(1, 1),
maxStack: maxStack(1, 1), maxStack: maxStack(1, 1),
} }
jt[BALANCE] = &operation{ jt[BALANCE] = operation{
execute: opBalance, execute: opBalance,
dynamicGas: gasBalance4762, dynamicGas: gasBalance4762,
minStack: minStack(1, 1), minStack: minStack(1, 1),
maxStack: maxStack(1, 1), maxStack: maxStack(1, 1),
} }
jt[EXTCODESIZE] = &operation{ jt[EXTCODESIZE] = operation{
execute: opExtCodeSize, execute: opExtCodeSize,
dynamicGas: gasExtCodeSize4762, dynamicGas: gasExtCodeSize4762,
minStack: minStack(1, 1), minStack: minStack(1, 1),
maxStack: maxStack(1, 1), maxStack: maxStack(1, 1),
} }
jt[EXTCODEHASH] = &operation{ jt[EXTCODEHASH] = operation{
execute: opExtCodeHash, execute: opExtCodeHash,
dynamicGas: gasExtCodeHash4762, dynamicGas: gasExtCodeHash4762,
minStack: minStack(1, 1), minStack: minStack(1, 1),
maxStack: maxStack(1, 1), maxStack: maxStack(1, 1),
} }
jt[EXTCODECOPY] = &operation{ jt[EXTCODECOPY] = operation{
execute: opExtCodeCopyEIP4762, execute: opExtCodeCopyEIP4762,
dynamicGas: gasExtCodeCopyEIP4762, dynamicGas: gasExtCodeCopyEIP4762,
minStack: minStack(4, 0), minStack: minStack(4, 0),
@ -466,7 +466,7 @@ func enable4762(jt *JumpTable) {
memorySize: memoryExtCodeCopy, memorySize: memoryExtCodeCopy,
} }
jt[CODECOPY] = &operation{ jt[CODECOPY] = operation{
execute: opCodeCopy, execute: opCodeCopy,
constantGas: GasFastestStep, constantGas: GasFastestStep,
dynamicGas: gasCodeCopyEip4762, dynamicGas: gasCodeCopyEip4762,
@ -475,7 +475,7 @@ func enable4762(jt *JumpTable) {
memorySize: memoryCodeCopy, memorySize: memoryCodeCopy,
} }
jt[SELFDESTRUCT] = &operation{ jt[SELFDESTRUCT] = operation{
execute: opSelfdestruct6780, execute: opSelfdestruct6780,
dynamicGas: gasSelfdestructEIP4762, dynamicGas: gasSelfdestructEIP4762,
constantGas: params.SelfdestructGasEIP150, constantGas: params.SelfdestructGasEIP150,
@ -483,7 +483,7 @@ func enable4762(jt *JumpTable) {
maxStack: maxStack(1, 0), maxStack: maxStack(1, 0),
} }
jt[CREATE] = &operation{ jt[CREATE] = operation{
execute: opCreate, execute: opCreate,
constantGas: params.CreateNGasEip4762, constantGas: params.CreateNGasEip4762,
dynamicGas: gasCreateEip3860, dynamicGas: gasCreateEip3860,
@ -492,7 +492,7 @@ func enable4762(jt *JumpTable) {
memorySize: memoryCreate, memorySize: memoryCreate,
} }
jt[CREATE2] = &operation{ jt[CREATE2] = operation{
execute: opCreate2, execute: opCreate2,
constantGas: params.CreateNGasEip4762, constantGas: params.CreateNGasEip4762,
dynamicGas: gasCreate2Eip3860, dynamicGas: gasCreate2Eip3860,
@ -501,7 +501,7 @@ func enable4762(jt *JumpTable) {
memorySize: memoryCreate2, memorySize: memoryCreate2,
} }
jt[CALL] = &operation{ jt[CALL] = operation{
execute: opCall, execute: opCall,
dynamicGas: gasCallEIP4762, dynamicGas: gasCallEIP4762,
minStack: minStack(7, 1), minStack: minStack(7, 1),
@ -509,7 +509,7 @@ func enable4762(jt *JumpTable) {
memorySize: memoryCall, memorySize: memoryCall,
} }
jt[CALLCODE] = &operation{ jt[CALLCODE] = operation{
execute: opCallCode, execute: opCallCode,
dynamicGas: gasCallCodeEIP4762, dynamicGas: gasCallCodeEIP4762,
minStack: minStack(7, 1), minStack: minStack(7, 1),
@ -517,7 +517,7 @@ func enable4762(jt *JumpTable) {
memorySize: memoryCall, memorySize: memoryCall,
} }
jt[STATICCALL] = &operation{ jt[STATICCALL] = operation{
execute: opStaticCall, execute: opStaticCall,
dynamicGas: gasStaticCallEIP4762, dynamicGas: gasStaticCallEIP4762,
minStack: minStack(6, 1), minStack: minStack(6, 1),
@ -525,7 +525,7 @@ func enable4762(jt *JumpTable) {
memorySize: memoryStaticCall, memorySize: memoryStaticCall,
} }
jt[DELEGATECALL] = &operation{ jt[DELEGATECALL] = operation{
execute: opDelegateCall, execute: opDelegateCall,
dynamicGas: gasDelegateCallEIP4762, dynamicGas: gasDelegateCallEIP4762,
minStack: minStack(6, 1), minStack: minStack(6, 1),
@ -533,14 +533,14 @@ func enable4762(jt *JumpTable) {
memorySize: memoryDelegateCall, memorySize: memoryDelegateCall,
} }
jt[PUSH1] = &operation{ jt[PUSH1] = operation{
execute: opPush1EIP4762, execute: opPush1EIP4762,
constantGas: GasFastestStep, constantGas: GasFastestStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),
maxStack: maxStack(0, 1), maxStack: maxStack(0, 1),
} }
for i := 1; i < 32; i++ { for i := 1; i < 32; i++ {
jt[PUSH1+OpCode(i)] = &operation{ jt[PUSH1+OpCode(i)] = operation{
execute: makePushEIP4762(uint64(i+1), i+1), execute: makePushEIP4762(uint64(i+1), i+1),
constantGas: GasFastestStep, constantGas: GasFastestStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),

View file

@ -251,7 +251,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// Get the operation from the jump table and validate the stack to ensure there are // Get the operation from the jump table and validate the stack to ensure there are
// enough stack items available to perform the operation. // enough stack items available to perform the operation.
op = contract.GetOp(pc) op = contract.GetOp(pc)
operation := jumpTable[op] operation := &jumpTable[op]
cost = operation.constantGas // For tracing cost = operation.constantGas // For tracing
// Validate stack // Validate stack
if sLen := stack.len(); sLen < operation.minStack { if sLen := stack.len(); sLen < operation.minStack {

View file

@ -42,9 +42,6 @@ type operation struct {
// memorySize returns the memory size required for the operation // memorySize returns the memory size required for the operation
memorySize memorySizeFunc memorySize memorySizeFunc
// undefined denotes if the instruction is not officially defined in the jump table
undefined bool
} }
var ( var (
@ -66,13 +63,10 @@ var (
) )
// JumpTable contains the EVM opcodes supported at a given fork. // JumpTable contains the EVM opcodes supported at a given fork.
type JumpTable [256]*operation type JumpTable [256]operation
func validate(jt JumpTable) JumpTable { func validate(jt JumpTable) JumpTable {
for i, op := range jt { for i, op := range jt {
if op == nil {
panic(fmt.Sprintf("op %#x is not set", i))
}
// The interpreter has an assumption that if the memorySize function is // The interpreter has an assumption that if the memorySize function is
// set, then the dynamicGas function is also set. This is a somewhat // set, then the dynamicGas function is also set. This is a somewhat
// arbitrary assumption, and can be removed if we need to -- but it // arbitrary assumption, and can be removed if we need to -- but it
@ -124,7 +118,7 @@ func newShanghaiInstructionSet() JumpTable {
func newMergeInstructionSet() JumpTable { func newMergeInstructionSet() JumpTable {
instructionSet := newLondonInstructionSet() instructionSet := newLondonInstructionSet()
instructionSet[PREVRANDAO] = &operation{ instructionSet[PREVRANDAO] = operation{
execute: opRandom, execute: opRandom,
constantGas: GasQuickStep, constantGas: GasQuickStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),
@ -166,31 +160,31 @@ func newIstanbulInstructionSet() JumpTable {
// byzantium and constantinople instructions. // byzantium and constantinople instructions.
func newConstantinopleInstructionSet() JumpTable { func newConstantinopleInstructionSet() JumpTable {
instructionSet := newByzantiumInstructionSet() instructionSet := newByzantiumInstructionSet()
instructionSet[SHL] = &operation{ instructionSet[SHL] = operation{
execute: opSHL, execute: opSHL,
constantGas: GasFastestStep, constantGas: GasFastestStep,
minStack: minStack(2, 1), minStack: minStack(2, 1),
maxStack: maxStack(2, 1), maxStack: maxStack(2, 1),
} }
instructionSet[SHR] = &operation{ instructionSet[SHR] = operation{
execute: opSHR, execute: opSHR,
constantGas: GasFastestStep, constantGas: GasFastestStep,
minStack: minStack(2, 1), minStack: minStack(2, 1),
maxStack: maxStack(2, 1), maxStack: maxStack(2, 1),
} }
instructionSet[SAR] = &operation{ instructionSet[SAR] = operation{
execute: opSAR, execute: opSAR,
constantGas: GasFastestStep, constantGas: GasFastestStep,
minStack: minStack(2, 1), minStack: minStack(2, 1),
maxStack: maxStack(2, 1), maxStack: maxStack(2, 1),
} }
instructionSet[EXTCODEHASH] = &operation{ instructionSet[EXTCODEHASH] = operation{
execute: opExtCodeHash, execute: opExtCodeHash,
constantGas: params.ExtcodeHashGasConstantinople, constantGas: params.ExtcodeHashGasConstantinople,
minStack: minStack(1, 1), minStack: minStack(1, 1),
maxStack: maxStack(1, 1), maxStack: maxStack(1, 1),
} }
instructionSet[CREATE2] = &operation{ instructionSet[CREATE2] = operation{
execute: opCreate2, execute: opCreate2,
constantGas: params.Create2Gas, constantGas: params.Create2Gas,
dynamicGas: gasCreate2, dynamicGas: gasCreate2,
@ -205,7 +199,7 @@ func newConstantinopleInstructionSet() JumpTable {
// byzantium instructions. // byzantium instructions.
func newByzantiumInstructionSet() JumpTable { func newByzantiumInstructionSet() JumpTable {
instructionSet := newSpuriousDragonInstructionSet() instructionSet := newSpuriousDragonInstructionSet()
instructionSet[STATICCALL] = &operation{ instructionSet[STATICCALL] = operation{
execute: opStaticCall, execute: opStaticCall,
constantGas: params.CallGasEIP150, constantGas: params.CallGasEIP150,
dynamicGas: gasStaticCall, dynamicGas: gasStaticCall,
@ -213,13 +207,13 @@ func newByzantiumInstructionSet() JumpTable {
maxStack: maxStack(6, 1), maxStack: maxStack(6, 1),
memorySize: memoryStaticCall, memorySize: memoryStaticCall,
} }
instructionSet[RETURNDATASIZE] = &operation{ instructionSet[RETURNDATASIZE] = operation{
execute: opReturnDataSize, execute: opReturnDataSize,
constantGas: GasQuickStep, constantGas: GasQuickStep,
minStack: minStack(0, 1), minStack: minStack(0, 1),
maxStack: maxStack(0, 1), maxStack: maxStack(0, 1),
} }
instructionSet[RETURNDATACOPY] = &operation{ instructionSet[RETURNDATACOPY] = operation{
execute: opReturnDataCopy, execute: opReturnDataCopy,
constantGas: GasFastestStep, constantGas: GasFastestStep,
dynamicGas: gasReturnDataCopy, dynamicGas: gasReturnDataCopy,
@ -227,7 +221,7 @@ func newByzantiumInstructionSet() JumpTable {
maxStack: maxStack(3, 0), maxStack: maxStack(3, 0),
memorySize: memoryReturnDataCopy, memorySize: memoryReturnDataCopy,
} }
instructionSet[REVERT] = &operation{ instructionSet[REVERT] = operation{
execute: opRevert, execute: opRevert,
dynamicGas: gasRevert, dynamicGas: gasRevert,
minStack: minStack(2, 0), minStack: minStack(2, 0),
@ -261,7 +255,7 @@ func newTangerineWhistleInstructionSet() JumpTable {
// instructions that can be executed during the homestead phase. // instructions that can be executed during the homestead phase.
func newHomesteadInstructionSet() JumpTable { func newHomesteadInstructionSet() JumpTable {
instructionSet := newFrontierInstructionSet() instructionSet := newFrontierInstructionSet()
instructionSet[DELEGATECALL] = &operation{ instructionSet[DELEGATECALL] = operation{
execute: opDelegateCall, execute: opDelegateCall,
dynamicGas: gasDelegateCall, dynamicGas: gasDelegateCall,
constantGas: params.CallGasFrontier, constantGas: params.CallGasFrontier,
@ -1084,9 +1078,9 @@ func newFrontierInstructionSet() JumpTable {
} }
// Fill all unassigned slots with opUndefined. // Fill all unassigned slots with opUndefined.
for i, entry := range tbl { for i := range tbl {
if entry == nil { if tbl[i].execute == nil {
tbl[i] = &operation{execute: opUndefined, maxStack: maxStack(0, 0), undefined: true} tbl[i] = operation{execute: opUndefined, maxStack: maxStack(0, 0)}
} }
} }
@ -1095,11 +1089,5 @@ func newFrontierInstructionSet() JumpTable {
func copyJumpTable(source *JumpTable) *JumpTable { func copyJumpTable(source *JumpTable) *JumpTable {
dest := *source dest := *source
for i, op := range source {
if op != nil {
opCopy := *op
dest[i] = &opCopy
}
}
return &dest return &dest
} }