1use core::fmt::{Display, Formatter};
2
3#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5#[cfg_attr(
6 feature = "with-codec",
7 derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
8)]
9#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct Opcode(pub u8);
11
12#[allow(clippy::use_self)]
14impl Opcode {
15 pub const STOP: Opcode = Opcode(0x00);
17 pub const ADD: Opcode = Opcode(0x01);
19 pub const MUL: Opcode = Opcode(0x02);
21 pub const SUB: Opcode = Opcode(0x03);
23 pub const DIV: Opcode = Opcode(0x04);
25 pub const SDIV: Opcode = Opcode(0x05);
27 pub const MOD: Opcode = Opcode(0x06);
29 pub const SMOD: Opcode = Opcode(0x07);
31 pub const ADDMOD: Opcode = Opcode(0x08);
33 pub const MULMOD: Opcode = Opcode(0x09);
35 pub const EXP: Opcode = Opcode(0x0a);
37 pub const SIGNEXTEND: Opcode = Opcode(0x0b);
39
40 pub const LT: Opcode = Opcode(0x10);
42 pub const GT: Opcode = Opcode(0x11);
44 pub const SLT: Opcode = Opcode(0x12);
46 pub const SGT: Opcode = Opcode(0x13);
48 pub const EQ: Opcode = Opcode(0x14);
50 pub const ISZERO: Opcode = Opcode(0x15);
52 pub const AND: Opcode = Opcode(0x16);
54 pub const OR: Opcode = Opcode(0x17);
56 pub const XOR: Opcode = Opcode(0x18);
58 pub const NOT: Opcode = Opcode(0x19);
60 pub const BYTE: Opcode = Opcode(0x1a);
62 pub const SHL: Opcode = Opcode(0x1b);
64 pub const SHR: Opcode = Opcode(0x1c);
66 pub const SAR: Opcode = Opcode(0x1d);
68
69 pub const SHA3: Opcode = Opcode(0x20);
71
72 pub const ADDRESS: Opcode = Opcode(0x30);
74 pub const BALANCE: Opcode = Opcode(0x31);
76 pub const ORIGIN: Opcode = Opcode(0x32);
78 pub const CALLER: Opcode = Opcode(0x33);
80 pub const CALLVALUE: Opcode = Opcode(0x34);
82 pub const CALLDATALOAD: Opcode = Opcode(0x35);
84 pub const CALLDATASIZE: Opcode = Opcode(0x36);
86 pub const CALLDATACOPY: Opcode = Opcode(0x37);
88 pub const CODESIZE: Opcode = Opcode(0x38);
90 pub const CODECOPY: Opcode = Opcode(0x39);
92
93 pub const GASPRICE: Opcode = Opcode(0x3a);
95 pub const EXTCODESIZE: Opcode = Opcode(0x3b);
97 pub const EXTCODECOPY: Opcode = Opcode(0x3c);
99 pub const RETURNDATASIZE: Opcode = Opcode(0x3d);
101 pub const RETURNDATACOPY: Opcode = Opcode(0x3e);
103 pub const EXTCODEHASH: Opcode = Opcode(0x3f);
105 pub const BLOCKHASH: Opcode = Opcode(0x40);
107 pub const COINBASE: Opcode = Opcode(0x41);
109 pub const TIMESTAMP: Opcode = Opcode(0x42);
111 pub const NUMBER: Opcode = Opcode(0x43);
113 pub const PREVRANDAO: Opcode = Opcode(0x44);
116 pub const GASLIMIT: Opcode = Opcode(0x45);
118 pub const CHAINID: Opcode = Opcode(0x46);
120 pub const SELFBALANCE: Opcode = Opcode(0x47);
122 pub const BASEFEE: Opcode = Opcode(0x48);
124 pub const BLOBHASH: Opcode = Opcode(0x49);
126 pub const BLOBBASEFEE: Opcode = Opcode(0x4a);
128
129 pub const POP: Opcode = Opcode(0x50);
131 pub const MLOAD: Opcode = Opcode(0x51);
133 pub const MSTORE: Opcode = Opcode(0x52);
135 pub const MSTORE8: Opcode = Opcode(0x53);
137 pub const SLOAD: Opcode = Opcode(0x54);
139 pub const SSTORE: Opcode = Opcode(0x55);
141 pub const JUMP: Opcode = Opcode(0x56);
143 pub const JUMPI: Opcode = Opcode(0x57);
145 pub const PC: Opcode = Opcode(0x58);
147 pub const MSIZE: Opcode = Opcode(0x59);
149 pub const GAS: Opcode = Opcode(0x5a);
151 pub const JUMPDEST: Opcode = Opcode(0x5b);
153 pub const TLOAD: Opcode = Opcode(0x5c);
155 pub const TSTORE: Opcode = Opcode(0x5d);
157 pub const MCOPY: Opcode = Opcode(0x5e);
159
160 pub const PUSH0: Opcode = Opcode(0x5f);
162 pub const PUSH1: Opcode = Opcode(0x60);
163 pub const PUSH2: Opcode = Opcode(0x61);
164 pub const PUSH3: Opcode = Opcode(0x62);
165 pub const PUSH4: Opcode = Opcode(0x63);
166 pub const PUSH5: Opcode = Opcode(0x64);
167 pub const PUSH6: Opcode = Opcode(0x65);
168 pub const PUSH7: Opcode = Opcode(0x66);
169 pub const PUSH8: Opcode = Opcode(0x67);
170 pub const PUSH9: Opcode = Opcode(0x68);
171 pub const PUSH10: Opcode = Opcode(0x69);
172 pub const PUSH11: Opcode = Opcode(0x6a);
173 pub const PUSH12: Opcode = Opcode(0x6b);
174 pub const PUSH13: Opcode = Opcode(0x6c);
175 pub const PUSH14: Opcode = Opcode(0x6d);
176 pub const PUSH15: Opcode = Opcode(0x6e);
177 pub const PUSH16: Opcode = Opcode(0x6f);
178 pub const PUSH17: Opcode = Opcode(0x70);
179 pub const PUSH18: Opcode = Opcode(0x71);
180 pub const PUSH19: Opcode = Opcode(0x72);
181 pub const PUSH20: Opcode = Opcode(0x73);
182 pub const PUSH21: Opcode = Opcode(0x74);
183 pub const PUSH22: Opcode = Opcode(0x75);
184 pub const PUSH23: Opcode = Opcode(0x76);
185 pub const PUSH24: Opcode = Opcode(0x77);
186 pub const PUSH25: Opcode = Opcode(0x78);
187 pub const PUSH26: Opcode = Opcode(0x79);
188 pub const PUSH27: Opcode = Opcode(0x7a);
189 pub const PUSH28: Opcode = Opcode(0x7b);
190 pub const PUSH29: Opcode = Opcode(0x7c);
191 pub const PUSH30: Opcode = Opcode(0x7d);
192 pub const PUSH31: Opcode = Opcode(0x7e);
193 pub const PUSH32: Opcode = Opcode(0x7f);
194
195 pub const DUP1: Opcode = Opcode(0x80);
197 pub const DUP2: Opcode = Opcode(0x81);
198 pub const DUP3: Opcode = Opcode(0x82);
199 pub const DUP4: Opcode = Opcode(0x83);
200 pub const DUP5: Opcode = Opcode(0x84);
201 pub const DUP6: Opcode = Opcode(0x85);
202 pub const DUP7: Opcode = Opcode(0x86);
203 pub const DUP8: Opcode = Opcode(0x87);
204 pub const DUP9: Opcode = Opcode(0x88);
205 pub const DUP10: Opcode = Opcode(0x89);
206 pub const DUP11: Opcode = Opcode(0x8a);
207 pub const DUP12: Opcode = Opcode(0x8b);
208 pub const DUP13: Opcode = Opcode(0x8c);
209 pub const DUP14: Opcode = Opcode(0x8d);
210 pub const DUP15: Opcode = Opcode(0x8e);
211 pub const DUP16: Opcode = Opcode(0x8f);
212
213 pub const SWAP1: Opcode = Opcode(0x90);
215 pub const SWAP2: Opcode = Opcode(0x91);
216 pub const SWAP3: Opcode = Opcode(0x92);
217 pub const SWAP4: Opcode = Opcode(0x93);
218 pub const SWAP5: Opcode = Opcode(0x94);
219 pub const SWAP6: Opcode = Opcode(0x95);
220 pub const SWAP7: Opcode = Opcode(0x96);
221 pub const SWAP8: Opcode = Opcode(0x97);
222 pub const SWAP9: Opcode = Opcode(0x98);
223 pub const SWAP10: Opcode = Opcode(0x99);
224 pub const SWAP11: Opcode = Opcode(0x9a);
225 pub const SWAP12: Opcode = Opcode(0x9b);
226 pub const SWAP13: Opcode = Opcode(0x9c);
227 pub const SWAP14: Opcode = Opcode(0x9d);
228 pub const SWAP15: Opcode = Opcode(0x9e);
229 pub const SWAP16: Opcode = Opcode(0x9f);
230
231 pub const LOG0: Opcode = Opcode(0xa0);
233 pub const LOG1: Opcode = Opcode(0xa1);
234 pub const LOG2: Opcode = Opcode(0xa2);
235 pub const LOG3: Opcode = Opcode(0xa3);
236 pub const LOG4: Opcode = Opcode(0xa4);
237
238 pub const DATALOAD: Opcode = Opcode(0xd0);
239 pub const DATALOADN: Opcode = Opcode(0xd1);
240 pub const DATASIZE: Opcode = Opcode(0xd2);
241 pub const DATACOPY: Opcode = Opcode(0xd3);
242
243 pub const RJUMP: Opcode = Opcode(0xe0);
245 pub const RJUMPI: Opcode = Opcode(0xe1);
247 pub const RJUMPV: Opcode = Opcode(0xe2);
249
250 pub const CALLF: Opcode = Opcode(0xe3);
252 pub const RETF: Opcode = Opcode(0xe4);
254
255 pub const JUMPF: Opcode = Opcode(0xe5);
257
258 pub const DUPN: Opcode = Opcode(0xe6);
260 pub const SWAPN: Opcode = Opcode(0xe7);
262 pub const EXCHANGE: Opcode = Opcode(0xe8);
264
265 pub const EOFCREATE: Opcode = Opcode(0xec);
267 pub const RETURNCONTRACT: Opcode = Opcode(0xee);
269
270 pub const CREATE: Opcode = Opcode(0xf0);
272 pub const CALL: Opcode = Opcode(0xf1);
274 pub const CALLCODE: Opcode = Opcode(0xf2);
276 pub const RETURN: Opcode = Opcode(0xf3);
278 pub const DELEGATECALL: Opcode = Opcode(0xf4);
280 pub const CREATE2: Opcode = Opcode(0xf5);
282
283 pub const RETURNDATALOAD: Opcode = Opcode(0xf7);
285 pub const EXTCALL: Opcode = Opcode(0xf8);
287 pub const EXTDELEGATECALL: Opcode = Opcode(0xf9);
289 pub const STATICCALL: Opcode = Opcode(0xfa);
291 pub const EXTSTATICCALL: Opcode = Opcode(0xfb);
293
294 pub const REVERT: Opcode = Opcode(0xfd);
296 pub const INVALID: Opcode = Opcode(0xfe);
298 pub const SELFDESTRUCT: Opcode = Opcode(0xff);
300}
301
302impl Opcode {
303 #[must_use]
305 pub fn is_push(&self) -> Option<u8> {
306 let value = self.0;
307 if (0x60..=0x7f).contains(&value) {
308 Some(value - 0x60 + 1)
309 } else {
310 None
311 }
312 }
313
314 #[inline]
315 #[must_use]
316 pub const fn as_u8(&self) -> u8 {
317 self.0
318 }
319
320 #[inline]
321 #[must_use]
322 #[allow(clippy::as_conversions)]
323 pub const fn as_usize(&self) -> usize {
324 self.0 as usize
325 }
326}
327
328impl Display for Opcode {
329 #[allow(clippy::too_many_lines)]
330 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
331 let name = match *self {
332 Self::STOP => "STOP",
333 Self::ADD => "ADD",
334 Self::MUL => "MUL",
335 Self::SUB => "SUB",
336 Self::DIV => "DIV",
337 Self::SDIV => "SDIV",
338 Self::MOD => "MOD",
339 Self::SMOD => "SMOD",
340 Self::ADDMOD => "ADDMOD",
341 Self::MULMOD => "MULMOD",
342 Self::EXP => "EXP",
343 Self::SIGNEXTEND => "SIGNEXTEND",
344 Self::LT => "LT",
345 Self::GT => "GT",
346 Self::SLT => "SLT",
347 Self::SGT => "SGT",
348 Self::EQ => "EQ",
349 Self::ISZERO => "ISZERO",
350 Self::AND => "AND",
351 Self::OR => "OR",
352 Self::XOR => "XOR",
353 Self::NOT => "NOT",
354 Self::BYTE => "BYTE",
355 Self::CALLDATALOAD => "CALLDATALOAD",
356 Self::CALLDATASIZE => "CALLDATASIZE",
357 Self::CALLDATACOPY => "CALLDATACOPY",
358 Self::CODESIZE => "CODESIZE",
359 Self::CODECOPY => "CODECOPY",
360 Self::SHL => "SHL",
361 Self::SHR => "SHR",
362 Self::SAR => "SAR",
363 Self::POP => "POP",
364 Self::MLOAD => "MLOAD",
365 Self::MSTORE => "MSTORE",
366 Self::MSTORE8 => "MSTORE8",
367 Self::JUMP => "JUMP",
368 Self::JUMPI => "JUMPI",
369 Self::PC => "PC",
370 Self::MSIZE => "MSIZE",
371 Self::JUMPDEST => "JUMPDEST",
372 Self::TLOAD => "TLOAD",
373 Self::TSTORE => "TSTORE",
374 Self::MCOPY => "MCOPY",
375 Self::PUSH0 => "PUSH0",
376 Self::PUSH1 => "PUSH1",
377 Self::PUSH2 => "PUSH2",
378 Self::PUSH3 => "PUSH3",
379 Self::PUSH4 => "PUSH4",
380 Self::PUSH5 => "PUSH5",
381 Self::PUSH6 => "PUSH6",
382 Self::PUSH7 => "PUSH7",
383 Self::PUSH8 => "PUSH8",
384 Self::PUSH9 => "PUSH9",
385 Self::PUSH10 => "PUSH10",
386 Self::PUSH11 => "PUSH11",
387 Self::PUSH12 => "PUSH12",
388 Self::PUSH13 => "PUSH13",
389 Self::PUSH14 => "PUSH14",
390 Self::PUSH15 => "PUSH15",
391 Self::PUSH16 => "PUSH16",
392 Self::PUSH17 => "PUSH17",
393 Self::PUSH18 => "PUSH18",
394 Self::PUSH19 => "PUSH19",
395 Self::PUSH20 => "PUSH20",
396 Self::PUSH21 => "PUSH21",
397 Self::PUSH22 => "PUSH22",
398 Self::PUSH23 => "PUSH23",
399 Self::PUSH24 => "PUSH24",
400 Self::PUSH25 => "PUSH25",
401 Self::PUSH26 => "PUSH26",
402 Self::PUSH27 => "PUSH27",
403 Self::PUSH28 => "PUSH28",
404 Self::PUSH29 => "PUSH29",
405 Self::PUSH30 => "PUSH30",
406 Self::PUSH31 => "PUSH31",
407 Self::PUSH32 => "PUSH32",
408 Self::DUP1 => "DUP1",
409 Self::DUP2 => "DUP2",
410 Self::DUP3 => "DUP3",
411 Self::DUP4 => "DUP4",
412 Self::DUP5 => "DUP5",
413 Self::DUP6 => "DUP6",
414 Self::DUP7 => "DUP7",
415 Self::DUP8 => "DUP8",
416 Self::DUP9 => "DUP9",
417 Self::DUP10 => "DUP10",
418 Self::DUP11 => "DUP11",
419 Self::DUP12 => "DUP12",
420 Self::DUP13 => "DUP13",
421 Self::DUP14 => "DUP14",
422 Self::DUP15 => "DUP15",
423 Self::DUP16 => "DUP16",
424 Self::SWAP1 => "SWAP1",
425 Self::SWAP2 => "SWAP2",
426 Self::SWAP3 => "SWAP3",
427 Self::SWAP4 => "SWAP4",
428 Self::SWAP5 => "SWAP5",
429 Self::SWAP6 => "SWAP6",
430 Self::SWAP7 => "SWAP7",
431 Self::SWAP8 => "SWAP8",
432 Self::SWAP9 => "SWAP9",
433 Self::SWAP10 => "SWAP10",
434 Self::SWAP11 => "SWAP11",
435 Self::SWAP12 => "SWAP12",
436 Self::SWAP13 => "SWAP13",
437 Self::SWAP14 => "SWAP14",
438 Self::SWAP15 => "SWAP15",
439 Self::SWAP16 => "SWAP16",
440 Self::RETURN => "RETURN",
441 Self::REVERT => "REVERT",
442 Self::INVALID => "INVALID",
443 Self::SHA3 => "SHA3",
444 Self::ADDRESS => "ADDRESS",
445 Self::BALANCE => "BALANCE",
446 Self::SELFBALANCE => "SELFBALANCE",
447 Self::BASEFEE => "BASEFEE",
448 Self::BLOBHASH => "BLOBHASH",
449 Self::BLOBBASEFEE => "BLOBBASEFEE",
450 Self::ORIGIN => "ORIGIN",
451 Self::CALLER => "CALLER",
452 Self::CALLVALUE => "CALLVALUE",
453 Self::GASPRICE => "GASPRICE",
454 Self::EXTCODESIZE => "EXTCODESIZE",
455 Self::EXTCODECOPY => "EXTCODECOPY",
456 Self::EXTCODEHASH => "EXTCODEHASH",
457 Self::RETURNDATASIZE => "RETURNDATASIZE",
458 Self::RETURNDATACOPY => "RETURNDATACOPY",
459 Self::BLOCKHASH => "BLOCKHASH",
460 Self::COINBASE => "COINBASE",
461 Self::TIMESTAMP => "TIMESTAMP",
462 Self::NUMBER => "NUMBER",
463 Self::PREVRANDAO => "PREVRANDAO",
464 Self::GASLIMIT => "GASLIMIT",
465 Self::SLOAD => "SLOAD",
466 Self::SSTORE => "SSTORE",
467 Self::GAS => "GAS",
468 Self::LOG0 => "LOG0",
469 Self::LOG1 => "LOG1",
470 Self::LOG2 => "LOG2",
471 Self::LOG3 => "LOG3",
472 Self::LOG4 => "LOG4",
473 Self::CREATE => "CREATE",
474 Self::CREATE2 => "CREATE2",
475 Self::CALL => "CALL",
476 Self::CALLCODE => "CALLCODE",
477 Self::DELEGATECALL => "DELEGATECALL",
478 Self::STATICCALL => "STATICCALL",
479 Self::SELFDESTRUCT => "SELFDESTRUCT",
480 Self::CHAINID => "CHAINID",
481 Self::EXTSTATICCALL => "EXTSTATICCALL",
482 Self::EXTCALL => "EXTCALL",
483 Self::EXTDELEGATECALL => "EXTDELEGATECALL",
484 Self::RETURNDATALOAD => "RETURNDATALOAD",
485 _ => "UNKNOWN",
486 };
487 write!(f, "{name} [{}]", self.0)
488 }
489}