@@ -29,10 +29,7 @@ type Config struct {
29
29
Tracer EVMLogger // Opcode logger
30
30
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
31
31
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages
32
-
33
- JumpTable * JumpTable // EVM instruction table, automatically populated if unset
34
-
35
- ExtraEips []int // Additional EIPS that are to be enabled
32
+ ExtraEips []int // Additional EIPS that are to be enabled
36
33
}
37
34
38
35
// ScopeContext contains the things that are per-call, such as stack and memory,
@@ -45,8 +42,8 @@ type ScopeContext struct {
45
42
46
43
// EVMInterpreter represents an EVM interpreter
47
44
type EVMInterpreter struct {
48
- evm * EVM
49
- cfg Config
45
+ evm * EVM
46
+ table * JumpTable
50
47
51
48
hasher crypto.KeccakState // Keccak256 hasher instance shared across opcodes
52
49
hasherBuf common.Hash // Keccak256 hasher result array shared aross opcodes
@@ -56,55 +53,50 @@ type EVMInterpreter struct {
56
53
}
57
54
58
55
// NewEVMInterpreter returns a new instance of the Interpreter.
59
- func NewEVMInterpreter (evm * EVM , cfg Config ) * EVMInterpreter {
56
+ func NewEVMInterpreter (evm * EVM ) * EVMInterpreter {
60
57
// If jump table was not initialised we set the default one.
61
- if cfg .JumpTable == nil {
62
- switch {
63
- case evm .chainRules .IsEIP1559 :
64
- cfg .JumpTable = & eip1559InstructionSet
65
- case evm .chainRules .IsShanghai :
66
- cfg .JumpTable = & shanghaiInstructionSet
67
- case evm .chainRules .IsMerge :
68
- cfg .JumpTable = & mergeInstructionSet
69
- case evm .chainRules .IsLondon :
70
- cfg .JumpTable = & londonInstructionSet
71
- case evm .chainRules .IsBerlin :
72
- cfg .JumpTable = & berlinInstructionSet
73
- case evm .chainRules .IsIstanbul :
74
- cfg .JumpTable = & istanbulInstructionSet
75
- case evm .chainRules .IsConstantinople :
76
- cfg .JumpTable = & constantinopleInstructionSet
77
- case evm .chainRules .IsByzantium :
78
- cfg .JumpTable = & byzantiumInstructionSet
79
- case evm .chainRules .IsEIP158 :
80
- cfg .JumpTable = & spuriousDragonInstructionSet
81
- case evm .chainRules .IsEIP150 :
82
- cfg .JumpTable = & tangerineWhistleInstructionSet
83
- case evm .chainRules .IsHomestead :
84
- cfg .JumpTable = & homesteadInstructionSet
85
- default :
86
- cfg .JumpTable = & frontierInstructionSet
87
- }
88
- var extraEips []int
89
- if len (cfg .ExtraEips ) > 0 {
90
- // Deep-copy jumptable to prevent modification of opcodes in other tables
91
- cfg .JumpTable = copyJumpTable (cfg .JumpTable )
92
- }
93
- for _ , eip := range cfg .ExtraEips {
94
- if err := EnableEIP (eip , cfg .JumpTable ); err != nil {
95
- // Disable it, so caller can check if it's activated or not
96
- log .Error ("EIP activation failed" , "eip" , eip , "error" , err )
97
- } else {
98
- extraEips = append (extraEips , eip )
99
- }
100
- }
101
- cfg .ExtraEips = extraEips
58
+ var table * JumpTable
59
+ switch {
60
+ case evm .chainRules .IsEIP1559 :
61
+ table = & eip1559InstructionSet
62
+ case evm .chainRules .IsShanghai :
63
+ table = & shanghaiInstructionSet
64
+ case evm .chainRules .IsMerge :
65
+ table = & mergeInstructionSet
66
+ case evm .chainRules .IsLondon :
67
+ table = & londonInstructionSet
68
+ case evm .chainRules .IsBerlin :
69
+ table = & berlinInstructionSet
70
+ case evm .chainRules .IsIstanbul :
71
+ table = & istanbulInstructionSet
72
+ case evm .chainRules .IsConstantinople :
73
+ table = & constantinopleInstructionSet
74
+ case evm .chainRules .IsByzantium :
75
+ table = & byzantiumInstructionSet
76
+ case evm .chainRules .IsEIP158 :
77
+ table = & spuriousDragonInstructionSet
78
+ case evm .chainRules .IsEIP150 :
79
+ table = & tangerineWhistleInstructionSet
80
+ case evm .chainRules .IsHomestead :
81
+ table = & homesteadInstructionSet
82
+ default :
83
+ table = & frontierInstructionSet
102
84
}
103
-
104
- return & EVMInterpreter {
105
- evm : evm ,
106
- cfg : cfg ,
85
+ var extraEips []int
86
+ if len (evm .Config .ExtraEips ) > 0 {
87
+ // Deep-copy jumptable to prevent modification of opcodes in other tables
88
+ table = copyJumpTable (table )
89
+ }
90
+ for _ , eip := range evm .Config .ExtraEips {
91
+ if err := EnableEIP (eip , table ); err != nil {
92
+ // Disable it, so caller can check if it's activated or not
93
+ log .Error ("EIP activation failed" , "eip" , eip , "error" , err )
94
+ } else {
95
+ extraEips = append (extraEips , eip )
96
+ }
107
97
}
98
+ evm .Config .ExtraEips = extraEips
99
+ return & EVMInterpreter {evm : evm , table : table }
108
100
}
109
101
110
102
// Run loops and evaluates the contract's code with the given input data and returns
@@ -162,13 +154,13 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
162
154
}()
163
155
contract .Input = input
164
156
165
- if in .cfg .Debug {
157
+ if in .evm . Config .Debug {
166
158
defer func () {
167
159
if err != nil {
168
160
if ! logged {
169
- in .cfg .Tracer .CaptureState (in .evm , pcCopy , op , gasCopy , cost , callContext , in .returnData , in .evm .depth , err )
161
+ in .evm . Config .Tracer .CaptureState (in .evm , pcCopy , op , gasCopy , cost , callContext , in .returnData , in .evm .depth , err )
170
162
} else {
171
- in .cfg .Tracer .CaptureFault (in .evm , pcCopy , op , gasCopy , cost , callContext , in .evm .depth , err )
163
+ in .evm . Config .Tracer .CaptureFault (in .evm , pcCopy , op , gasCopy , cost , callContext , in .evm .depth , err )
172
164
}
173
165
}
174
166
}()
@@ -178,15 +170,15 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
178
170
// the execution of one of the operations or until the done flag is set by the
179
171
// parent context.
180
172
for {
181
- if in .cfg .Debug {
173
+ if in .evm . Config .Debug {
182
174
// Capture pre-execution values for tracing.
183
175
logged , pcCopy , gasCopy = false , pc , contract .Gas
184
176
}
185
177
186
178
// Get the operation from the jump table and validate the stack to ensure there are
187
179
// enough stack items available to perform the operation.
188
180
op = contract .GetOp (pc )
189
- operation := in .cfg . JumpTable [op ]
181
+ operation := in .table [op ]
190
182
cost = operation .constantGas // For tracing
191
183
// Validate stack
192
184
if sLen := stack .len (); sLen < operation .minStack {
@@ -224,15 +216,15 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
224
216
return nil , ErrOutOfGas
225
217
}
226
218
// Do tracing before memory expansion
227
- if in .cfg .Debug {
228
- in .cfg .Tracer .CaptureState (in .evm , pc , op , gasCopy , cost , callContext , in .returnData , in .evm .depth , err )
219
+ if in .evm . Config .Debug {
220
+ in .evm . Config .Tracer .CaptureState (in .evm , pc , op , gasCopy , cost , callContext , in .returnData , in .evm .depth , err )
229
221
logged = true
230
222
}
231
223
if memorySize > 0 {
232
224
mem .Resize (memorySize )
233
225
}
234
- } else if in .cfg .Debug {
235
- in .cfg .Tracer .CaptureState (in .evm , pc , op , gasCopy , cost , callContext , in .returnData , in .evm .depth , err )
226
+ } else if in .evm . Config .Debug {
227
+ in .evm . Config .Tracer .CaptureState (in .evm , pc , op , gasCopy , cost , callContext , in .returnData , in .evm .depth , err )
236
228
logged = true
237
229
}
238
230
// execute the operation
0 commit comments