evm_interpreter/
opcode.rs

1/// Opcode enum. One-to-one corresponding to an `u8` value.
2#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3#[cfg_attr(
4	feature = "scale",
5	derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
6)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct Opcode(pub u8);
9
10// Core opcodes.
11impl Opcode {
12	/// `STOP`
13	pub const STOP: Opcode = Opcode(0x00);
14	/// `ADD`
15	pub const ADD: Opcode = Opcode(0x01);
16	/// `MUL`
17	pub const MUL: Opcode = Opcode(0x02);
18	/// `SUB`
19	pub const SUB: Opcode = Opcode(0x03);
20	/// `DIV`
21	pub const DIV: Opcode = Opcode(0x04);
22	/// `SDIV`
23	pub const SDIV: Opcode = Opcode(0x05);
24	/// `MOD`
25	pub const MOD: Opcode = Opcode(0x06);
26	/// `SMOD`
27	pub const SMOD: Opcode = Opcode(0x07);
28	/// `ADDMOD`
29	pub const ADDMOD: Opcode = Opcode(0x08);
30	/// `MULMOD`
31	pub const MULMOD: Opcode = Opcode(0x09);
32	/// `EXP`
33	pub const EXP: Opcode = Opcode(0x0a);
34	/// `SIGNEXTEND`
35	pub const SIGNEXTEND: Opcode = Opcode(0x0b);
36
37	/// `LT`
38	pub const LT: Opcode = Opcode(0x10);
39	/// `GT`
40	pub const GT: Opcode = Opcode(0x11);
41	/// `SLT`
42	pub const SLT: Opcode = Opcode(0x12);
43	/// `SGT`
44	pub const SGT: Opcode = Opcode(0x13);
45	/// `EQ`
46	pub const EQ: Opcode = Opcode(0x14);
47	/// `ISZERO`
48	pub const ISZERO: Opcode = Opcode(0x15);
49	/// `AND`
50	pub const AND: Opcode = Opcode(0x16);
51	/// `OR`
52	pub const OR: Opcode = Opcode(0x17);
53	/// `XOR`
54	pub const XOR: Opcode = Opcode(0x18);
55	/// `NOT`
56	pub const NOT: Opcode = Opcode(0x19);
57	/// `BYTE`
58	pub const BYTE: Opcode = Opcode(0x1a);
59
60	/// `SHL`
61	pub const SHL: Opcode = Opcode(0x1b);
62	/// `SHR`
63	pub const SHR: Opcode = Opcode(0x1c);
64	/// `SAR`
65	pub const SAR: Opcode = Opcode(0x1d);
66
67	/// `CALLDATALOAD`
68	pub const CALLDATALOAD: Opcode = Opcode(0x35);
69	/// `CALLDATASIZE`
70	pub const CALLDATASIZE: Opcode = Opcode(0x36);
71	/// `CALLDATACOPY`
72	pub const CALLDATACOPY: Opcode = Opcode(0x37);
73	/// `CODESIZE`
74	pub const CODESIZE: Opcode = Opcode(0x38);
75	/// `CODECOPY`
76	pub const CODECOPY: Opcode = Opcode(0x39);
77
78	/// `POP`
79	pub const POP: Opcode = Opcode(0x50);
80	/// `MLOAD`
81	pub const MLOAD: Opcode = Opcode(0x51);
82	/// `MSTORE`
83	pub const MSTORE: Opcode = Opcode(0x52);
84	/// `MSTORE8`
85	pub const MSTORE8: Opcode = Opcode(0x53);
86
87	/// `JUMP`
88	pub const JUMP: Opcode = Opcode(0x56);
89	/// `JUMPI`
90	pub const JUMPI: Opcode = Opcode(0x57);
91	/// `PC`
92	pub const PC: Opcode = Opcode(0x58);
93	/// `MSIZE`
94	pub const MSIZE: Opcode = Opcode(0x59);
95
96	/// `JUMPDEST`
97	pub const JUMPDEST: Opcode = Opcode(0x5b);
98	/// `MCOPY`
99	pub const MCOPY: Opcode = Opcode(0x5e);
100
101	/// `PUSH0`
102	pub const PUSH0: Opcode = Opcode(0x5f);
103	/// `PUSH1`
104	pub const PUSH1: Opcode = Opcode(0x60);
105	/// `PUSH2`
106	pub const PUSH2: Opcode = Opcode(0x61);
107	/// `PUSH3`
108	pub const PUSH3: Opcode = Opcode(0x62);
109	/// `PUSH4`
110	pub const PUSH4: Opcode = Opcode(0x63);
111	/// `PUSH5`
112	pub const PUSH5: Opcode = Opcode(0x64);
113	/// `PUSH6`
114	pub const PUSH6: Opcode = Opcode(0x65);
115	/// `PUSH7`
116	pub const PUSH7: Opcode = Opcode(0x66);
117	/// `PUSH8`
118	pub const PUSH8: Opcode = Opcode(0x67);
119	/// `PUSH9`
120	pub const PUSH9: Opcode = Opcode(0x68);
121	/// `PUSH10`
122	pub const PUSH10: Opcode = Opcode(0x69);
123	/// `PUSH11`
124	pub const PUSH11: Opcode = Opcode(0x6a);
125	/// `PUSH12`
126	pub const PUSH12: Opcode = Opcode(0x6b);
127	/// `PUSH13`
128	pub const PUSH13: Opcode = Opcode(0x6c);
129	/// `PUSH14`
130	pub const PUSH14: Opcode = Opcode(0x6d);
131	/// `PUSH15`
132	pub const PUSH15: Opcode = Opcode(0x6e);
133	/// `PUSH16`
134	pub const PUSH16: Opcode = Opcode(0x6f);
135	/// `PUSH17`
136	pub const PUSH17: Opcode = Opcode(0x70);
137	/// `PUSH18`
138	pub const PUSH18: Opcode = Opcode(0x71);
139	/// `PUSH19`
140	pub const PUSH19: Opcode = Opcode(0x72);
141	/// `PUSH20`
142	pub const PUSH20: Opcode = Opcode(0x73);
143	/// `PUSH21`
144	pub const PUSH21: Opcode = Opcode(0x74);
145	/// `PUSH22`
146	pub const PUSH22: Opcode = Opcode(0x75);
147	/// `PUSH23`
148	pub const PUSH23: Opcode = Opcode(0x76);
149	/// `PUSH24`
150	pub const PUSH24: Opcode = Opcode(0x77);
151	/// `PUSH25`
152	pub const PUSH25: Opcode = Opcode(0x78);
153	/// `PUSH26`
154	pub const PUSH26: Opcode = Opcode(0x79);
155	/// `PUSH27`
156	pub const PUSH27: Opcode = Opcode(0x7a);
157	/// `PUSH28`
158	pub const PUSH28: Opcode = Opcode(0x7b);
159	/// `PUSH29`
160	pub const PUSH29: Opcode = Opcode(0x7c);
161	/// `PUSH30`
162	pub const PUSH30: Opcode = Opcode(0x7d);
163	/// `PUSH31`
164	pub const PUSH31: Opcode = Opcode(0x7e);
165	/// `PUSH32`
166	pub const PUSH32: Opcode = Opcode(0x7f);
167
168	/// `DUP1`
169	pub const DUP1: Opcode = Opcode(0x80);
170	/// `DUP2`
171	pub const DUP2: Opcode = Opcode(0x81);
172	/// `DUP3`
173	pub const DUP3: Opcode = Opcode(0x82);
174	/// `DUP4`
175	pub const DUP4: Opcode = Opcode(0x83);
176	/// `DUP5`
177	pub const DUP5: Opcode = Opcode(0x84);
178	/// `DUP6`
179	pub const DUP6: Opcode = Opcode(0x85);
180	/// `DUP7`
181	pub const DUP7: Opcode = Opcode(0x86);
182	/// `DUP8`
183	pub const DUP8: Opcode = Opcode(0x87);
184	/// `DUP9`
185	pub const DUP9: Opcode = Opcode(0x88);
186	/// `DUP10`
187	pub const DUP10: Opcode = Opcode(0x89);
188	/// `DUP11`
189	pub const DUP11: Opcode = Opcode(0x8a);
190	/// `DUP12`
191	pub const DUP12: Opcode = Opcode(0x8b);
192	/// `DUP13`
193	pub const DUP13: Opcode = Opcode(0x8c);
194	/// `DUP14`
195	pub const DUP14: Opcode = Opcode(0x8d);
196	/// `DUP15`
197	pub const DUP15: Opcode = Opcode(0x8e);
198	/// `DUP16`
199	pub const DUP16: Opcode = Opcode(0x8f);
200
201	/// `SWAP1`
202	pub const SWAP1: Opcode = Opcode(0x90);
203	/// `SWAP2`
204	pub const SWAP2: Opcode = Opcode(0x91);
205	/// `SWAP3`
206	pub const SWAP3: Opcode = Opcode(0x92);
207	/// `SWAP4`
208	pub const SWAP4: Opcode = Opcode(0x93);
209	/// `SWAP5`
210	pub const SWAP5: Opcode = Opcode(0x94);
211	/// `SWAP6`
212	pub const SWAP6: Opcode = Opcode(0x95);
213	/// `SWAP7`
214	pub const SWAP7: Opcode = Opcode(0x96);
215	/// `SWAP8`
216	pub const SWAP8: Opcode = Opcode(0x97);
217	/// `SWAP9`
218	pub const SWAP9: Opcode = Opcode(0x98);
219	/// `SWAP10`
220	pub const SWAP10: Opcode = Opcode(0x99);
221	/// `SWAP11`
222	pub const SWAP11: Opcode = Opcode(0x9a);
223	/// `SWAP12`
224	pub const SWAP12: Opcode = Opcode(0x9b);
225	/// `SWAP13`
226	pub const SWAP13: Opcode = Opcode(0x9c);
227	/// `SWAP14`
228	pub const SWAP14: Opcode = Opcode(0x9d);
229	/// `SWAP15`
230	pub const SWAP15: Opcode = Opcode(0x9e);
231	/// `SWAP16`
232	pub const SWAP16: Opcode = Opcode(0x9f);
233
234	/// See [EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md)
235	pub const EOFMAGIC: Opcode = Opcode(0xef);
236
237	/// `RETURN`
238	pub const RETURN: Opcode = Opcode(0xf3);
239
240	/// `REVERT`
241	pub const REVERT: Opcode = Opcode(0xfd);
242
243	/// `INVALID`
244	pub const INVALID: Opcode = Opcode(0xfe);
245}
246
247// External opcodes
248impl Opcode {
249	/// `SHA3`
250	pub const SHA3: Opcode = Opcode(0x20);
251
252	/// `ADDRESS`
253	pub const ADDRESS: Opcode = Opcode(0x30);
254	/// `BALANCE`
255	pub const BALANCE: Opcode = Opcode(0x31);
256	/// `ORIGIN`
257	pub const ORIGIN: Opcode = Opcode(0x32);
258	/// `CALLER`
259	pub const CALLER: Opcode = Opcode(0x33);
260	/// `CALLVALUE`
261	pub const CALLVALUE: Opcode = Opcode(0x34);
262
263	/// `GASPRICE`
264	pub const GASPRICE: Opcode = Opcode(0x3a);
265	/// `EXTCODESIZE`
266	pub const EXTCODESIZE: Opcode = Opcode(0x3b);
267	/// `EXTCODECOPY`
268	pub const EXTCODECOPY: Opcode = Opcode(0x3c);
269	/// `RETURNDATASIZE`
270	pub const RETURNDATASIZE: Opcode = Opcode(0x3d);
271	/// `RETURNDATACOPY`
272	pub const RETURNDATACOPY: Opcode = Opcode(0x3e);
273	/// `EXTCODEHASH`
274	pub const EXTCODEHASH: Opcode = Opcode(0x3f);
275
276	/// `BLOCKHASH`
277	pub const BLOCKHASH: Opcode = Opcode(0x40);
278	/// `COINBASE`
279	pub const COINBASE: Opcode = Opcode(0x41);
280	/// `TIMESTAMP`
281	pub const TIMESTAMP: Opcode = Opcode(0x42);
282	/// `NUMBER`
283	pub const NUMBER: Opcode = Opcode(0x43);
284	/// `DIFFICULTY`
285	pub const DIFFICULTY: Opcode = Opcode(0x44);
286	/// `GASLIMIT`
287	pub const GASLIMIT: Opcode = Opcode(0x45);
288	/// `CHAINID`
289	pub const CHAINID: Opcode = Opcode(0x46);
290	/// `SELFBALANCE`
291	pub const SELFBALANCE: Opcode = Opcode(0x47);
292	/// `BASEFEE`
293	pub const BASEFEE: Opcode = Opcode(0x48);
294	/// `BLOBHASH`
295	pub const BLOBHASH: Opcode = Opcode(0x49);
296	/// `BLOBBASEFEE`
297	pub const BLOBBASEFEE: Opcode = Opcode(0x4a);
298
299	/// `SLOAD`
300	pub const SLOAD: Opcode = Opcode(0x54);
301	/// `SSTORE`
302	pub const SSTORE: Opcode = Opcode(0x55);
303
304	/// `GAS`
305	pub const GAS: Opcode = Opcode(0x5a);
306
307	/// `TLOAD`
308	pub const TLOAD: Opcode = Opcode(0x5c);
309	/// `TSTORE`
310	pub const TSTORE: Opcode = Opcode(0x5d);
311
312	/// `LOG0`
313	pub const LOG0: Opcode = Opcode(0xa0);
314	/// `LOG1`
315	pub const LOG1: Opcode = Opcode(0xa1);
316	/// `LOG2`
317	pub const LOG2: Opcode = Opcode(0xa2);
318	/// `LOG3`
319	pub const LOG3: Opcode = Opcode(0xa3);
320	/// `LOG4`
321	pub const LOG4: Opcode = Opcode(0xa4);
322
323	/// `CREATE`
324	pub const CREATE: Opcode = Opcode(0xf0);
325	/// `CALL`
326	pub const CALL: Opcode = Opcode(0xf1);
327	/// `CALLCODE`
328	pub const CALLCODE: Opcode = Opcode(0xf2);
329
330	/// `DELEGATECALL`
331	pub const DELEGATECALL: Opcode = Opcode(0xf4);
332	/// `CREATE2`
333	pub const CREATE2: Opcode = Opcode(0xf5);
334
335	/// `STATICCALL`
336	pub const STATICCALL: Opcode = Opcode(0xfa);
337
338	/// `SUICIDE`
339	pub const SUICIDE: Opcode = Opcode(0xff);
340}
341
342impl Opcode {
343	/// Whether the opcode is a push opcode.
344	#[must_use]
345	pub fn is_push(&self) -> Option<u8> {
346		let value = self.0;
347		if (0x60..=0x7f).contains(&value) {
348			Some(value - 0x60 + 1)
349		} else {
350			None
351		}
352	}
353
354	/// Convert opcode to u8.
355	#[inline]
356	#[must_use]
357	pub const fn as_u8(&self) -> u8 {
358		self.0
359	}
360
361	/// Convert opcode to usize.
362	#[inline]
363	#[must_use]
364	pub const fn as_usize(&self) -> usize {
365		self.0 as usize
366	}
367}