1use crate::{
2 errors::{OpcodeResult, VMError},
3 opcode_handlers::{
4 OpInvalidHandler, OpStopHandler, OpcodeHandler, arithmetic::*, bitwise_comparison::*,
5 block::*, dup::*, environment::*, exchange::*, keccak::*, logging::*, push::*,
6 stack_memory_storage_flow::*, system::*,
7 },
8 vm::VM,
9};
10use ethrex_common::types::Fork;
11use std::cell::OnceCell;
12use strum::EnumString;
13
14#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, EnumString, Hash)]
15pub enum Opcode {
16 STOP = 0x00,
18 ADD = 0x01,
19 MUL = 0x02,
20 SUB = 0x03,
21 DIV = 0x04,
22 SDIV = 0x05,
23 MOD = 0x06,
24 SMOD = 0x07,
25 ADDMOD = 0x08,
26 MULMOD = 0x09,
27 EXP = 0x0A,
28 SIGNEXTEND = 0x0B,
29
30 LT = 0x10,
32 GT = 0x11,
33 SLT = 0x12,
34 SGT = 0x13,
35 EQ = 0x14,
36 ISZERO = 0x15,
37 AND = 0x16,
38 OR = 0x17,
39 XOR = 0x18,
40 NOT = 0x19,
41 BYTE = 0x1A,
42 SHL = 0x1B,
43 SHR = 0x1C,
44 SAR = 0x1D,
45 CLZ = 0x1E,
46
47 KECCAK256 = 0x20,
49
50 ADDRESS = 0x30,
52 BALANCE = 0x31,
53 ORIGIN = 0x32,
54 CALLER = 0x33,
55 CALLVALUE = 0x34,
56 CALLDATALOAD = 0x35,
57 CALLDATASIZE = 0x36,
58 CALLDATACOPY = 0x37,
59 CODESIZE = 0x38,
60 CODECOPY = 0x39,
61 GASPRICE = 0x3A,
62 EXTCODESIZE = 0x3B,
63 EXTCODECOPY = 0x3C,
64 RETURNDATASIZE = 0x3D,
65 RETURNDATACOPY = 0x3E,
66 EXTCODEHASH = 0x3F,
67
68 BLOCKHASH = 0x40,
70 COINBASE = 0x41,
71 TIMESTAMP = 0x42,
72 NUMBER = 0x43,
73 PREVRANDAO = 0x44,
74 GASLIMIT = 0x45,
75 CHAINID = 0x46,
76 SELFBALANCE = 0x47,
77 BASEFEE = 0x48,
78 BLOBHASH = 0x49,
79 BLOBBASEFEE = 0x4A,
80 SLOTNUM = 0x4B,
81
82 POP = 0x50,
84 MLOAD = 0x51,
85 MSTORE = 0x52,
86 MSTORE8 = 0x53,
87 SLOAD = 0x54,
88 SSTORE = 0x55,
89 JUMP = 0x56,
90 JUMPI = 0x57,
91 PC = 0x58,
92 MSIZE = 0x59,
93 GAS = 0x5A,
94 JUMPDEST = 0x5B,
95 TLOAD = 0x5C,
96 TSTORE = 0x5D,
97 MCOPY = 0x5E,
98
99 PUSH0 = 0x5F,
101 PUSH1 = 0x60,
102 PUSH2 = 0x61,
103 PUSH3 = 0x62,
104 PUSH4 = 0x63,
105 PUSH5 = 0x64,
106 PUSH6 = 0x65,
107 PUSH7 = 0x66,
108 PUSH8 = 0x67,
109 PUSH9 = 0x68,
110 PUSH10 = 0x69,
111 PUSH11 = 0x6A,
112 PUSH12 = 0x6B,
113 PUSH13 = 0x6C,
114 PUSH14 = 0x6D,
115 PUSH15 = 0x6E,
116 PUSH16 = 0x6F,
117 PUSH17 = 0x70,
118 PUSH18 = 0x71,
119 PUSH19 = 0x72,
120 PUSH20 = 0x73,
121 PUSH21 = 0x74,
122 PUSH22 = 0x75,
123 PUSH23 = 0x76,
124 PUSH24 = 0x77,
125 PUSH25 = 0x78,
126 PUSH26 = 0x79,
127 PUSH27 = 0x7A,
128 PUSH28 = 0x7B,
129 PUSH29 = 0x7C,
130 PUSH30 = 0x7D,
131 PUSH31 = 0x7E,
132 PUSH32 = 0x7F,
133
134 DUP1 = 0x80,
136 DUP2 = 0x81,
137 DUP3 = 0x82,
138 DUP4 = 0x83,
139 DUP5 = 0x84,
140 DUP6 = 0x85,
141 DUP7 = 0x86,
142 DUP8 = 0x87,
143 DUP9 = 0x88,
144 DUP10 = 0x89,
145 DUP11 = 0x8A,
146 DUP12 = 0x8B,
147 DUP13 = 0x8C,
148 DUP14 = 0x8D,
149 DUP15 = 0x8E,
150 DUP16 = 0x8F,
151
152 SWAP1 = 0x90,
154 SWAP2 = 0x91,
155 SWAP3 = 0x92,
156 SWAP4 = 0x93,
157 SWAP5 = 0x94,
158 SWAP6 = 0x95,
159 SWAP7 = 0x96,
160 SWAP8 = 0x97,
161 SWAP9 = 0x98,
162 SWAP10 = 0x99,
163 SWAP11 = 0x9A,
164 SWAP12 = 0x9B,
165 SWAP13 = 0x9C,
166 SWAP14 = 0x9D,
167 SWAP15 = 0x9E,
168 SWAP16 = 0x9F,
169 LOG0 = 0xA0,
171 LOG1 = 0xA1,
172 LOG2 = 0xA2,
173 LOG3 = 0xA3,
174 LOG4 = 0xA4,
175 DUPN = 0xE6,
177 SWAPN = 0xE7,
178 EXCHANGE = 0xE8,
179 CREATE = 0xF0,
181 CALL = 0xF1,
182 CALLCODE = 0xF2,
183 RETURN = 0xF3,
184 DELEGATECALL = 0xF4,
185 CREATE2 = 0xF5,
186 STATICCALL = 0xFA,
187 REVERT = 0xFD,
188 INVALID = 0xFE,
189 SELFDESTRUCT = 0xFF,
190}
191
192impl From<u8> for Opcode {
193 #[expect(clippy::as_conversions)]
194 fn from(byte: u8) -> Self {
195 const OPCODE_TABLE: [Opcode; 256] = const {
198 let mut table = [Opcode::INVALID; 256];
199 table[0x00] = Opcode::STOP;
200 table[0x01] = Opcode::ADD;
201 table[0x16] = Opcode::AND;
202 table[0x17] = Opcode::OR;
203 table[0x18] = Opcode::XOR;
204 table[0x19] = Opcode::NOT;
205 table[0x1A] = Opcode::BYTE;
206 table[0x1B] = Opcode::SHL;
207 table[0x1C] = Opcode::SHR;
208 table[0x1D] = Opcode::SAR;
209 table[0x1E] = Opcode::CLZ;
210 table[0x02] = Opcode::MUL;
211 table[0x03] = Opcode::SUB;
212 table[0x04] = Opcode::DIV;
213 table[0x05] = Opcode::SDIV;
214 table[0x06] = Opcode::MOD;
215 table[0x07] = Opcode::SMOD;
216 table[0x08] = Opcode::ADDMOD;
217 table[0x09] = Opcode::MULMOD;
218 table[0x0A] = Opcode::EXP;
219 table[0x0B] = Opcode::SIGNEXTEND;
220 table[0x10] = Opcode::LT;
221 table[0x11] = Opcode::GT;
222 table[0x12] = Opcode::SLT;
223 table[0x13] = Opcode::SGT;
224 table[0x14] = Opcode::EQ;
225 table[0x15] = Opcode::ISZERO;
226 table[0x20] = Opcode::KECCAK256;
227 table[0x30] = Opcode::ADDRESS;
228 table[0x31] = Opcode::BALANCE;
229 table[0x32] = Opcode::ORIGIN;
230 table[0x33] = Opcode::CALLER;
231 table[0x34] = Opcode::CALLVALUE;
232 table[0x35] = Opcode::CALLDATALOAD;
233 table[0x36] = Opcode::CALLDATASIZE;
234 table[0x37] = Opcode::CALLDATACOPY;
235 table[0x38] = Opcode::CODESIZE;
236 table[0x39] = Opcode::CODECOPY;
237 table[0x3A] = Opcode::GASPRICE;
238 table[0x3B] = Opcode::EXTCODESIZE;
239 table[0x3C] = Opcode::EXTCODECOPY;
240 table[0x3D] = Opcode::RETURNDATASIZE;
241 table[0x3E] = Opcode::RETURNDATACOPY;
242 table[0x3F] = Opcode::EXTCODEHASH;
243 table[0x40] = Opcode::BLOCKHASH;
244 table[0x41] = Opcode::COINBASE;
245 table[0x42] = Opcode::TIMESTAMP;
246 table[0x43] = Opcode::NUMBER;
247 table[0x44] = Opcode::PREVRANDAO;
248 table[0x45] = Opcode::GASLIMIT;
249 table[0x46] = Opcode::CHAINID;
250 table[0x47] = Opcode::SELFBALANCE;
251 table[0x48] = Opcode::BASEFEE;
252 table[0x49] = Opcode::BLOBHASH;
253 table[0x4A] = Opcode::BLOBBASEFEE;
254 table[0x4B] = Opcode::SLOTNUM;
255 table[0x50] = Opcode::POP;
256 table[0x56] = Opcode::JUMP;
257 table[0x57] = Opcode::JUMPI;
258 table[0x58] = Opcode::PC;
259 table[0x5B] = Opcode::JUMPDEST;
260 table[0x5F] = Opcode::PUSH0;
261 table[0x60] = Opcode::PUSH1;
262 table[0x61] = Opcode::PUSH2;
263 table[0x62] = Opcode::PUSH3;
264 table[0x63] = Opcode::PUSH4;
265 table[0x64] = Opcode::PUSH5;
266 table[0x65] = Opcode::PUSH6;
267 table[0x66] = Opcode::PUSH7;
268 table[0x67] = Opcode::PUSH8;
269 table[0x68] = Opcode::PUSH9;
270 table[0x69] = Opcode::PUSH10;
271 table[0x6A] = Opcode::PUSH11;
272 table[0x6B] = Opcode::PUSH12;
273 table[0x6C] = Opcode::PUSH13;
274 table[0x6D] = Opcode::PUSH14;
275 table[0x6E] = Opcode::PUSH15;
276 table[0x6F] = Opcode::PUSH16;
277 table[0x70] = Opcode::PUSH17;
278 table[0x71] = Opcode::PUSH18;
279 table[0x72] = Opcode::PUSH19;
280 table[0x73] = Opcode::PUSH20;
281 table[0x74] = Opcode::PUSH21;
282 table[0x75] = Opcode::PUSH22;
283 table[0x76] = Opcode::PUSH23;
284 table[0x77] = Opcode::PUSH24;
285 table[0x78] = Opcode::PUSH25;
286 table[0x79] = Opcode::PUSH26;
287 table[0x7A] = Opcode::PUSH27;
288 table[0x7B] = Opcode::PUSH28;
289 table[0x7C] = Opcode::PUSH29;
290 table[0x7D] = Opcode::PUSH30;
291 table[0x7E] = Opcode::PUSH31;
292 table[0x7F] = Opcode::PUSH32;
293 table[0x80] = Opcode::DUP1;
294 table[0x81] = Opcode::DUP2;
295 table[0x82] = Opcode::DUP3;
296 table[0x83] = Opcode::DUP4;
297 table[0x84] = Opcode::DUP5;
298 table[0x85] = Opcode::DUP6;
299 table[0x86] = Opcode::DUP7;
300 table[0x87] = Opcode::DUP8;
301 table[0x88] = Opcode::DUP9;
302 table[0x89] = Opcode::DUP10;
303 table[0x8A] = Opcode::DUP11;
304 table[0x8B] = Opcode::DUP12;
305 table[0x8C] = Opcode::DUP13;
306 table[0x8D] = Opcode::DUP14;
307 table[0x8E] = Opcode::DUP15;
308 table[0x8F] = Opcode::DUP16;
309 table[0x90] = Opcode::SWAP1;
310 table[0x91] = Opcode::SWAP2;
311 table[0x92] = Opcode::SWAP3;
312 table[0x93] = Opcode::SWAP4;
313 table[0x94] = Opcode::SWAP5;
314 table[0x95] = Opcode::SWAP6;
315 table[0x96] = Opcode::SWAP7;
316 table[0x97] = Opcode::SWAP8;
317 table[0x98] = Opcode::SWAP9;
318 table[0x99] = Opcode::SWAP10;
319 table[0x9A] = Opcode::SWAP11;
320 table[0x9B] = Opcode::SWAP12;
321 table[0x9C] = Opcode::SWAP13;
322 table[0x9D] = Opcode::SWAP14;
323 table[0x9E] = Opcode::SWAP15;
324 table[0x9F] = Opcode::SWAP16;
325 table[0xA0] = Opcode::LOG0;
326 table[0xA1] = Opcode::LOG1;
327 table[0xA2] = Opcode::LOG2;
328 table[0xA3] = Opcode::LOG3;
329 table[0xA4] = Opcode::LOG4;
330 table[0x51] = Opcode::MLOAD;
331 table[0x52] = Opcode::MSTORE;
332 table[0x53] = Opcode::MSTORE8;
333 table[0x54] = Opcode::SLOAD;
334 table[0x55] = Opcode::SSTORE;
335 table[0x59] = Opcode::MSIZE;
336 table[0x5A] = Opcode::GAS;
337 table[0x5E] = Opcode::MCOPY;
338 table[0x5C] = Opcode::TLOAD;
339 table[0x5D] = Opcode::TSTORE;
340 table[0xE6] = Opcode::DUPN;
341 table[0xE7] = Opcode::SWAPN;
342 table[0xE8] = Opcode::EXCHANGE;
343 table[0xF0] = Opcode::CREATE;
344 table[0xF1] = Opcode::CALL;
345 table[0xF2] = Opcode::CALLCODE;
346 table[0xF3] = Opcode::RETURN;
347 table[0xF5] = Opcode::CREATE2;
348 table[0xF4] = Opcode::DELEGATECALL;
349 table[0xFA] = Opcode::STATICCALL;
350 table[0xFD] = Opcode::REVERT;
351 table[0xFF] = Opcode::SELFDESTRUCT;
352
353 table
354 };
355 #[expect(clippy::indexing_slicing)] OPCODE_TABLE[byte as usize]
357 }
358}
359
360impl From<Opcode> for u8 {
361 #[allow(clippy::as_conversions)]
362 fn from(opcode: Opcode) -> Self {
363 opcode as u8
364 }
365}
366
367impl From<Opcode> for usize {
368 #[allow(clippy::as_conversions)]
369 fn from(opcode: Opcode) -> Self {
370 opcode as usize
371 }
372}
373
374#[derive(Debug, Clone, Copy)]
376pub(crate) struct OpCodeFn(fn(&mut VM<'_>, &mut OnceCell<VMError>) -> OpcodeResult);
377
378impl OpCodeFn {
379 pub const fn new<T>() -> Self
380 where
381 T: OpcodeHandler,
382 {
383 Self(Self::wrap::<T>)
384 }
385
386 #[inline(always)]
388 pub fn call(self, vm: &mut VM<'_>, error: &mut OnceCell<VMError>) -> OpcodeResult {
389 (self.0)(vm, error)
390 }
391
392 fn wrap<T>(vm: &mut VM<'_>, error: &mut OnceCell<VMError>) -> OpcodeResult
393 where
394 T: OpcodeHandler,
395 {
396 T::eval(vm).unwrap_or_else(|err| {
397 _ = error.set(err);
398 OpcodeResult::Halt
399 })
400 }
401}
402
403impl<'a> VM<'a> {
404 #[allow(clippy::as_conversions, clippy::indexing_slicing)]
411 pub(crate) fn build_opcode_table(fork: Fork) -> &'static [OpCodeFn; 256] {
412 static AMSTERDAM: [OpCodeFn; 256] = VM::<'static>::build_opcode_table_amsterdam();
415 static OSAKA: [OpCodeFn; 256] = VM::<'static>::build_opcode_table_osaka();
416 static PRE_OSAKA: [OpCodeFn; 256] = VM::<'static>::build_opcode_table_pre_osaka();
417 static PRE_CANCUN: [OpCodeFn; 256] = VM::<'static>::build_opcode_table_pre_cancun();
418 static PRE_SHANGHAI: [OpCodeFn; 256] = VM::<'static>::build_opcode_table_pre_shanghai();
419
420 if fork >= Fork::Amsterdam {
421 &AMSTERDAM
422 } else if fork >= Fork::Osaka {
423 &OSAKA
424 } else if fork >= Fork::Cancun {
425 &PRE_OSAKA
426 } else if fork >= Fork::Shanghai {
427 &PRE_CANCUN
428 } else {
429 &PRE_SHANGHAI
430 }
431 }
432
433 #[allow(clippy::as_conversions, clippy::indexing_slicing)]
434 const fn build_opcode_table_pre_shanghai() -> [OpCodeFn; 256] {
435 let mut opcode_table: [OpCodeFn; 256] = [OpCodeFn::new::<OpInvalidHandler>(); 256];
436
437 opcode_table[Opcode::STOP as usize] = OpCodeFn::new::<OpStopHandler>();
438 opcode_table[Opcode::MLOAD as usize] = OpCodeFn::new::<OpMLoadHandler>();
439 opcode_table[Opcode::MSTORE as usize] = OpCodeFn::new::<OpMStoreHandler>();
440 opcode_table[Opcode::MSTORE8 as usize] = OpCodeFn::new::<OpMStore8Handler>();
441 opcode_table[Opcode::JUMP as usize] = OpCodeFn::new::<OpJumpHandler>();
442 opcode_table[Opcode::SLOAD as usize] = OpCodeFn::new::<OpSLoadHandler>();
443 opcode_table[Opcode::SSTORE as usize] = OpCodeFn::new::<OpSStoreHandler>();
444 opcode_table[Opcode::MSIZE as usize] = OpCodeFn::new::<OpMSizeHandler>();
445 opcode_table[Opcode::GAS as usize] = OpCodeFn::new::<OpGasHandler>();
446 opcode_table[Opcode::PUSH1 as usize] = OpCodeFn::new::<OpPushHandler<1>>();
447 opcode_table[Opcode::PUSH2 as usize] = OpCodeFn::new::<OpPushHandler<2>>();
448 opcode_table[Opcode::PUSH3 as usize] = OpCodeFn::new::<OpPushHandler<3>>();
449 opcode_table[Opcode::PUSH4 as usize] = OpCodeFn::new::<OpPushHandler<4>>();
450 opcode_table[Opcode::PUSH5 as usize] = OpCodeFn::new::<OpPushHandler<5>>();
451 opcode_table[Opcode::PUSH6 as usize] = OpCodeFn::new::<OpPushHandler<6>>();
452 opcode_table[Opcode::PUSH7 as usize] = OpCodeFn::new::<OpPushHandler<7>>();
453 opcode_table[Opcode::PUSH8 as usize] = OpCodeFn::new::<OpPushHandler<8>>();
454 opcode_table[Opcode::PUSH9 as usize] = OpCodeFn::new::<OpPushHandler<9>>();
455 opcode_table[Opcode::PUSH10 as usize] = OpCodeFn::new::<OpPushHandler<10>>();
456 opcode_table[Opcode::PUSH11 as usize] = OpCodeFn::new::<OpPushHandler<11>>();
457 opcode_table[Opcode::PUSH12 as usize] = OpCodeFn::new::<OpPushHandler<12>>();
458 opcode_table[Opcode::PUSH13 as usize] = OpCodeFn::new::<OpPushHandler<13>>();
459 opcode_table[Opcode::PUSH14 as usize] = OpCodeFn::new::<OpPushHandler<14>>();
460 opcode_table[Opcode::PUSH15 as usize] = OpCodeFn::new::<OpPushHandler<15>>();
461 opcode_table[Opcode::PUSH16 as usize] = OpCodeFn::new::<OpPushHandler<16>>();
462 opcode_table[Opcode::PUSH17 as usize] = OpCodeFn::new::<OpPushHandler<17>>();
463 opcode_table[Opcode::PUSH18 as usize] = OpCodeFn::new::<OpPushHandler<18>>();
464 opcode_table[Opcode::PUSH19 as usize] = OpCodeFn::new::<OpPushHandler<19>>();
465 opcode_table[Opcode::PUSH20 as usize] = OpCodeFn::new::<OpPushHandler<20>>();
466 opcode_table[Opcode::PUSH21 as usize] = OpCodeFn::new::<OpPushHandler<21>>();
467 opcode_table[Opcode::PUSH22 as usize] = OpCodeFn::new::<OpPushHandler<22>>();
468 opcode_table[Opcode::PUSH23 as usize] = OpCodeFn::new::<OpPushHandler<23>>();
469 opcode_table[Opcode::PUSH24 as usize] = OpCodeFn::new::<OpPushHandler<24>>();
470 opcode_table[Opcode::PUSH25 as usize] = OpCodeFn::new::<OpPushHandler<25>>();
471 opcode_table[Opcode::PUSH26 as usize] = OpCodeFn::new::<OpPushHandler<26>>();
472 opcode_table[Opcode::PUSH27 as usize] = OpCodeFn::new::<OpPushHandler<27>>();
473 opcode_table[Opcode::PUSH28 as usize] = OpCodeFn::new::<OpPushHandler<28>>();
474 opcode_table[Opcode::PUSH29 as usize] = OpCodeFn::new::<OpPushHandler<29>>();
475 opcode_table[Opcode::PUSH30 as usize] = OpCodeFn::new::<OpPushHandler<30>>();
476 opcode_table[Opcode::PUSH31 as usize] = OpCodeFn::new::<OpPushHandler<31>>();
477 opcode_table[Opcode::PUSH32 as usize] = OpCodeFn::new::<OpPushHandler<32>>();
478
479 opcode_table[Opcode::DUP1 as usize] = OpCodeFn::new::<OpDupHandler<0>>();
480 opcode_table[Opcode::DUP2 as usize] = OpCodeFn::new::<OpDupHandler<1>>();
481 opcode_table[Opcode::DUP3 as usize] = OpCodeFn::new::<OpDupHandler<2>>();
482 opcode_table[Opcode::DUP4 as usize] = OpCodeFn::new::<OpDupHandler<3>>();
483 opcode_table[Opcode::DUP5 as usize] = OpCodeFn::new::<OpDupHandler<4>>();
484 opcode_table[Opcode::DUP6 as usize] = OpCodeFn::new::<OpDupHandler<5>>();
485 opcode_table[Opcode::DUP7 as usize] = OpCodeFn::new::<OpDupHandler<6>>();
486 opcode_table[Opcode::DUP8 as usize] = OpCodeFn::new::<OpDupHandler<7>>();
487 opcode_table[Opcode::DUP9 as usize] = OpCodeFn::new::<OpDupHandler<8>>();
488 opcode_table[Opcode::DUP10 as usize] = OpCodeFn::new::<OpDupHandler<9>>();
489 opcode_table[Opcode::DUP11 as usize] = OpCodeFn::new::<OpDupHandler<10>>();
490 opcode_table[Opcode::DUP12 as usize] = OpCodeFn::new::<OpDupHandler<11>>();
491 opcode_table[Opcode::DUP13 as usize] = OpCodeFn::new::<OpDupHandler<12>>();
492 opcode_table[Opcode::DUP14 as usize] = OpCodeFn::new::<OpDupHandler<13>>();
493 opcode_table[Opcode::DUP15 as usize] = OpCodeFn::new::<OpDupHandler<14>>();
494 opcode_table[Opcode::DUP16 as usize] = OpCodeFn::new::<OpDupHandler<15>>();
495
496 opcode_table[Opcode::SWAP1 as usize] = OpCodeFn::new::<OpSwapHandler<1>>();
497 opcode_table[Opcode::SWAP2 as usize] = OpCodeFn::new::<OpSwapHandler<2>>();
498 opcode_table[Opcode::SWAP3 as usize] = OpCodeFn::new::<OpSwapHandler<3>>();
499 opcode_table[Opcode::SWAP4 as usize] = OpCodeFn::new::<OpSwapHandler<4>>();
500 opcode_table[Opcode::SWAP5 as usize] = OpCodeFn::new::<OpSwapHandler<5>>();
501 opcode_table[Opcode::SWAP6 as usize] = OpCodeFn::new::<OpSwapHandler<6>>();
502 opcode_table[Opcode::SWAP7 as usize] = OpCodeFn::new::<OpSwapHandler<7>>();
503 opcode_table[Opcode::SWAP8 as usize] = OpCodeFn::new::<OpSwapHandler<8>>();
504 opcode_table[Opcode::SWAP9 as usize] = OpCodeFn::new::<OpSwapHandler<9>>();
505 opcode_table[Opcode::SWAP10 as usize] = OpCodeFn::new::<OpSwapHandler<10>>();
506 opcode_table[Opcode::SWAP11 as usize] = OpCodeFn::new::<OpSwapHandler<11>>();
507 opcode_table[Opcode::SWAP12 as usize] = OpCodeFn::new::<OpSwapHandler<12>>();
508 opcode_table[Opcode::SWAP13 as usize] = OpCodeFn::new::<OpSwapHandler<13>>();
509 opcode_table[Opcode::SWAP14 as usize] = OpCodeFn::new::<OpSwapHandler<14>>();
510 opcode_table[Opcode::SWAP15 as usize] = OpCodeFn::new::<OpSwapHandler<15>>();
511 opcode_table[Opcode::SWAP16 as usize] = OpCodeFn::new::<OpSwapHandler<16>>();
512 opcode_table[Opcode::POP as usize] = OpCodeFn::new::<OpPopHandler>();
513 opcode_table[Opcode::ADD as usize] = OpCodeFn::new::<OpAddHandler>();
514 opcode_table[Opcode::MUL as usize] = OpCodeFn::new::<OpMulHandler>();
515 opcode_table[Opcode::SUB as usize] = OpCodeFn::new::<OpSubHandler>();
516 opcode_table[Opcode::DIV as usize] = OpCodeFn::new::<OpDivHandler>();
517 opcode_table[Opcode::SDIV as usize] = OpCodeFn::new::<OpSDivHandler>();
518 opcode_table[Opcode::MOD as usize] = OpCodeFn::new::<OpModHandler>();
519 opcode_table[Opcode::SMOD as usize] = OpCodeFn::new::<OpSModHandler>();
520 opcode_table[Opcode::ADDMOD as usize] = OpCodeFn::new::<OpAddModHandler>();
521 opcode_table[Opcode::MULMOD as usize] = OpCodeFn::new::<OpMulModHandler>();
522 opcode_table[Opcode::EXP as usize] = OpCodeFn::new::<OpExpHandler>();
523 opcode_table[Opcode::CALL as usize] = OpCodeFn::new::<OpCallHandler>();
524 opcode_table[Opcode::CALLCODE as usize] = OpCodeFn::new::<OpCallCodeHandler>();
525 opcode_table[Opcode::RETURN as usize] = OpCodeFn::new::<OpReturnHandler>();
526 opcode_table[Opcode::DELEGATECALL as usize] = OpCodeFn::new::<OpDelegateCallHandler>();
527 opcode_table[Opcode::STATICCALL as usize] = OpCodeFn::new::<OpStaticCallHandler>();
528 opcode_table[Opcode::CREATE as usize] = OpCodeFn::new::<OpCreateHandler>();
529 opcode_table[Opcode::CREATE2 as usize] = OpCodeFn::new::<OpCreate2Handler>();
530 opcode_table[Opcode::JUMPI as usize] = OpCodeFn::new::<OpJumpIHandler>();
531 opcode_table[Opcode::JUMPDEST as usize] = OpCodeFn::new::<OpJumpDestHandler>();
532 opcode_table[Opcode::ADDRESS as usize] = OpCodeFn::new::<OpAddressHandler>();
533 opcode_table[Opcode::ORIGIN as usize] = OpCodeFn::new::<OpOriginHandler>();
534 opcode_table[Opcode::BALANCE as usize] = OpCodeFn::new::<OpBalanceHandler>();
535 opcode_table[Opcode::CALLER as usize] = OpCodeFn::new::<OpCallerHandler>();
536 opcode_table[Opcode::CALLVALUE as usize] = OpCodeFn::new::<OpCallValueHandler>();
537 opcode_table[Opcode::CODECOPY as usize] = OpCodeFn::new::<OpCodeCopyHandler>();
538 opcode_table[Opcode::SIGNEXTEND as usize] = OpCodeFn::new::<OpSignExtendHandler>();
539 opcode_table[Opcode::LT as usize] = OpCodeFn::new::<OpLtHandler>();
540 opcode_table[Opcode::GT as usize] = OpCodeFn::new::<OpGtHandler>();
541 opcode_table[Opcode::SLT as usize] = OpCodeFn::new::<OpSLtHandler>();
542 opcode_table[Opcode::SGT as usize] = OpCodeFn::new::<OpSGtHandler>();
543 opcode_table[Opcode::EQ as usize] = OpCodeFn::new::<OpEqHandler>();
544 opcode_table[Opcode::ISZERO as usize] = OpCodeFn::new::<OpIsZeroHandler>();
545 opcode_table[Opcode::KECCAK256 as usize] = OpCodeFn::new::<OpKeccak256Handler>();
546 opcode_table[Opcode::CALLDATALOAD as usize] = OpCodeFn::new::<OpCallDataLoadHandler>();
547 opcode_table[Opcode::CALLDATASIZE as usize] = OpCodeFn::new::<OpCallDataSizeHandler>();
548 opcode_table[Opcode::CALLDATACOPY as usize] = OpCodeFn::new::<OpCallDataCopyHandler>();
549 opcode_table[Opcode::RETURNDATASIZE as usize] = OpCodeFn::new::<OpReturnDataSizeHandler>();
550 opcode_table[Opcode::RETURNDATACOPY as usize] = OpCodeFn::new::<OpReturnDataCopyHandler>();
551 opcode_table[Opcode::PC as usize] = OpCodeFn::new::<OpPcHandler>();
552 opcode_table[Opcode::BLOCKHASH as usize] = OpCodeFn::new::<OpBlockHashHandler>();
553 opcode_table[Opcode::COINBASE as usize] = OpCodeFn::new::<OpCoinbaseHandler>();
554 opcode_table[Opcode::TIMESTAMP as usize] = OpCodeFn::new::<OpTimestampHandler>();
555 opcode_table[Opcode::NUMBER as usize] = OpCodeFn::new::<OpNumberHandler>();
556 opcode_table[Opcode::PREVRANDAO as usize] = OpCodeFn::new::<OpPrevRandaoHandler>();
557 opcode_table[Opcode::GASLIMIT as usize] = OpCodeFn::new::<OpGasLimitHandler>();
558 opcode_table[Opcode::CHAINID as usize] = OpCodeFn::new::<OpChainIdHandler>();
559 opcode_table[Opcode::BASEFEE as usize] = OpCodeFn::new::<OpBaseFeeHandler>();
560 opcode_table[Opcode::AND as usize] = OpCodeFn::new::<OpAndHandler>();
561 opcode_table[Opcode::OR as usize] = OpCodeFn::new::<OpOrHandler>();
562 opcode_table[Opcode::XOR as usize] = OpCodeFn::new::<OpXorHandler>();
563 opcode_table[Opcode::NOT as usize] = OpCodeFn::new::<OpNotHandler>();
564 opcode_table[Opcode::BYTE as usize] = OpCodeFn::new::<OpByteHandler>();
565 opcode_table[Opcode::SHL as usize] = OpCodeFn::new::<OpShlHandler>();
566 opcode_table[Opcode::SHR as usize] = OpCodeFn::new::<OpShrHandler>();
567 opcode_table[Opcode::SAR as usize] = OpCodeFn::new::<OpSarHandler>();
568 opcode_table[Opcode::SELFBALANCE as usize] = OpCodeFn::new::<OpSelfBalanceHandler>();
569 opcode_table[Opcode::CODESIZE as usize] = OpCodeFn::new::<OpCodeSizeHandler>();
570 opcode_table[Opcode::GASPRICE as usize] = OpCodeFn::new::<OpGasPriceHandler>();
571 opcode_table[Opcode::EXTCODESIZE as usize] = OpCodeFn::new::<OpExtCodeSizeHandler>();
572 opcode_table[Opcode::EXTCODECOPY as usize] = OpCodeFn::new::<OpExtCodeCopyHandler>();
573 opcode_table[Opcode::EXTCODEHASH as usize] = OpCodeFn::new::<OpExtCodeHashHandler>();
574 opcode_table[Opcode::REVERT as usize] = OpCodeFn::new::<OpRevertHandler>();
575 opcode_table[Opcode::INVALID as usize] = OpCodeFn::new::<OpInvalidHandler>();
576 opcode_table[Opcode::SELFDESTRUCT as usize] = OpCodeFn::new::<OpSelfDestructHandler>();
577
578 opcode_table[Opcode::LOG0 as usize] = OpCodeFn::new::<OpLogHandler<0>>();
579 opcode_table[Opcode::LOG1 as usize] = OpCodeFn::new::<OpLogHandler<1>>();
580 opcode_table[Opcode::LOG2 as usize] = OpCodeFn::new::<OpLogHandler<2>>();
581 opcode_table[Opcode::LOG3 as usize] = OpCodeFn::new::<OpLogHandler<3>>();
582 opcode_table[Opcode::LOG4 as usize] = OpCodeFn::new::<OpLogHandler<4>>();
583
584 opcode_table
585 }
586
587 #[allow(clippy::as_conversions, clippy::indexing_slicing)]
588 const fn build_opcode_table_pre_cancun() -> [OpCodeFn; 256] {
589 let mut opcode_table: [OpCodeFn; 256] = Self::build_opcode_table_pre_shanghai();
590
591 opcode_table[Opcode::PUSH0 as usize] = OpCodeFn::new::<OpPush0Handler>();
593
594 opcode_table
595 }
596
597 #[allow(clippy::as_conversions, clippy::indexing_slicing)]
598 const fn build_opcode_table_pre_osaka() -> [OpCodeFn; 256] {
599 const {
600 let mut opcode_table: [OpCodeFn; 256] = Self::build_opcode_table_pre_cancun();
601
602 opcode_table[Opcode::MCOPY as usize] = OpCodeFn::new::<OpMCopyHandler>();
604
605 opcode_table[Opcode::TLOAD as usize] = OpCodeFn::new::<OpTLoadHandler>();
607 opcode_table[Opcode::TSTORE as usize] = OpCodeFn::new::<OpTStoreHandler>();
608
609 opcode_table[Opcode::BLOBBASEFEE as usize] = OpCodeFn::new::<OpBlobBaseFeeHandler>();
611 opcode_table[Opcode::BLOBHASH as usize] = OpCodeFn::new::<OpBlobHashHandler>();
613
614 opcode_table
615 }
616 }
617
618 #[allow(clippy::as_conversions, clippy::indexing_slicing)]
619 const fn build_opcode_table_osaka() -> [OpCodeFn; 256] {
620 let mut opcode_table: [OpCodeFn; 256] = Self::build_opcode_table_pre_osaka();
621
622 opcode_table[Opcode::CLZ as usize] = OpCodeFn::new::<OpClzHandler>();
623
624 opcode_table
625 }
626
627 #[expect(clippy::as_conversions, clippy::indexing_slicing)]
628 const fn build_opcode_table_amsterdam() -> [OpCodeFn; 256] {
629 let mut opcode_table: [OpCodeFn; 256] = Self::build_opcode_table_osaka();
630
631 opcode_table[Opcode::DUPN as usize] = OpCodeFn::new::<OpDupNHandler>();
633 opcode_table[Opcode::SWAPN as usize] = OpCodeFn::new::<OpSwapNHandler>();
634 opcode_table[Opcode::EXCHANGE as usize] = OpCodeFn::new::<OpExchangeHandler>();
635 opcode_table[Opcode::SLOTNUM as usize] = OpCodeFn::new::<OpSlotNumHandler>();
637 opcode_table
638 }
639}