foundry_debugger/
op.rs

1/// Named parameter of an EVM opcode.
2#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3pub(crate) struct OpcodeParam {
4    /// The name of the parameter.
5    pub(crate) name: &'static str,
6    /// The index of the parameter on the stack. This is relative to the top of the stack.
7    pub(crate) index: usize,
8}
9
10impl OpcodeParam {
11    /// Returns the list of named parameters for the given opcode, accounts for special opcodes
12    /// requiring immediate bytes to determine stack items.
13    #[inline]
14    pub(crate) fn of(op: u8) -> &'static [Self] {
15        MAP[op as usize]
16    }
17}
18
19static MAP: [&[OpcodeParam]; 256] = {
20    let mut table = [[].as_slice(); 256];
21    let mut i = 0;
22    while i < 256 {
23        table[i] = map_opcode(i as u8);
24        i += 1;
25    }
26    table
27};
28
29const fn map_opcode(op: u8) -> &'static [OpcodeParam] {
30    macro_rules! map {
31        ($($op:literal($($idx:literal : $name:literal),* $(,)?)),* $(,)?) => {
32            match op {
33                $($op => &[
34                    $(OpcodeParam {
35                        name: $name,
36                        index: $idx,
37                    }),*
38                ]),*
39            }
40        };
41    }
42
43    // https://www.evm.codes
44    // https://raw.githubusercontent.com/duneanalytics/evm.codes/refs/heads/main/opcodes.json
45    //
46    // jq -r '
47    //   def mkargs(input):
48    //     input
49    //     | split(" | ")
50    //     | to_entries
51    //     | map("\(.key): \"\(.value)\"")
52    //     | join(", ");
53    //   to_entries[]
54    //   | "0x\(.key)(\(mkargs(.value.input))),"
55    // ' opcodes.json
56    //
57    // NOTE: the labels generated for `DUPN` and `SWAPN` have incorrect indices and have been
58    // manually adjusted in the `map!` macro below.
59    map! {
60        0x00(),
61        0x01(0: "a", 1: "b"),
62        0x02(0: "a", 1: "b"),
63        0x03(0: "a", 1: "b"),
64        0x04(0: "a", 1: "b"),
65        0x05(0: "a", 1: "b"),
66        0x06(0: "a", 1: "b"),
67        0x07(0: "a", 1: "b"),
68        0x08(0: "a", 1: "b", 2: "N"),
69        0x09(0: "a", 1: "b", 2: "N"),
70        0x0a(0: "a", 1: "exponent"),
71        0x0b(0: "b", 1: "x"),
72        0x0c(),
73        0x0d(),
74        0x0e(),
75        0x0f(),
76        0x10(0: "a", 1: "b"),
77        0x11(0: "a", 1: "b"),
78        0x12(0: "a", 1: "b"),
79        0x13(0: "a", 1: "b"),
80        0x14(0: "a", 1: "b"),
81        0x15(0: "a"),
82        0x16(0: "a", 1: "b"),
83        0x17(0: "a", 1: "b"),
84        0x18(0: "a", 1: "b"),
85        0x19(0: "a"),
86        0x1a(0: "i", 1: "x"),
87        0x1b(0: "shift", 1: "value"),
88        0x1c(0: "shift", 1: "value"),
89        0x1d(0: "shift", 1: "value"),
90        0x1e(),
91        0x1f(),
92        0x20(0: "offset", 1: "size"),
93        0x21(),
94        0x22(),
95        0x23(),
96        0x24(),
97        0x25(),
98        0x26(),
99        0x27(),
100        0x28(),
101        0x29(),
102        0x2a(),
103        0x2b(),
104        0x2c(),
105        0x2d(),
106        0x2e(),
107        0x2f(),
108        0x30(),
109        0x31(0: "address"),
110        0x32(),
111        0x33(),
112        0x34(),
113        0x35(0: "i"),
114        0x36(),
115        0x37(0: "destOffset", 1: "offset", 2: "size"),
116        0x38(),
117        0x39(0: "destOffset", 1: "offset", 2: "size"),
118        0x3a(),
119        0x3b(0: "address"),
120        0x3c(0: "address", 1: "destOffset", 2: "offset", 3: "size"),
121        0x3d(),
122        0x3e(0: "destOffset", 1: "offset", 2: "size"),
123        0x3f(0: "address"),
124        0x40(0: "blockNumber"),
125        0x41(),
126        0x42(),
127        0x43(),
128        0x44(),
129        0x45(),
130        0x46(),
131        0x47(),
132        0x48(),
133        0x49(0: "index"),
134        0x4a(),
135        0x4b(),
136        0x4c(),
137        0x4d(),
138        0x4e(),
139        0x4f(),
140        0x50(0: "y"),
141        0x51(0: "offset"),
142        0x52(0: "offset", 1: "value"),
143        0x53(0: "offset", 1: "value"),
144        0x54(0: "key"),
145        0x55(0: "key", 1: "value"),
146        0x56(0: "counter"),
147        0x57(0: "counter", 1: "b"),
148        0x58(),
149        0x59(),
150        0x5a(),
151        0x5b(),
152        0x5c(0: "key"),
153        0x5d(0: "key", 1: "value"),
154        0x5e(0: "destOffset", 1: "offset", 2: "size"),
155        0x5f(),
156        0x60(),
157        0x61(),
158        0x62(),
159        0x63(),
160        0x64(),
161        0x65(),
162        0x66(),
163        0x67(),
164        0x68(),
165        0x69(),
166        0x6a(),
167        0x6b(),
168        0x6c(),
169        0x6d(),
170        0x6e(),
171        0x6f(),
172        0x70(),
173        0x71(),
174        0x72(),
175        0x73(),
176        0x74(),
177        0x75(),
178        0x76(),
179        0x77(),
180        0x78(),
181        0x79(),
182        0x7a(),
183        0x7b(),
184        0x7c(),
185        0x7d(),
186        0x7e(),
187        0x7f(),
188
189        // DUPN
190        0x80(0x00: "dup_value"),
191        0x81(0x01: "dup_value"),
192        0x82(0x02: "dup_value"),
193        0x83(0x03: "dup_value"),
194        0x84(0x04: "dup_value"),
195        0x85(0x05: "dup_value"),
196        0x86(0x06: "dup_value"),
197        0x87(0x07: "dup_value"),
198        0x88(0x08: "dup_value"),
199        0x89(0x09: "dup_value"),
200        0x8a(0x0a: "dup_value"),
201        0x8b(0x0b: "dup_value"),
202        0x8c(0x0c: "dup_value"),
203        0x8d(0x0d: "dup_value"),
204        0x8e(0x0e: "dup_value"),
205        0x8f(0x0f: "dup_value"),
206
207        // SWAPN
208        0x90(0: "a", 0x01: "swap_value"),
209        0x91(0: "a", 0x02: "swap_value"),
210        0x92(0: "a", 0x03: "swap_value"),
211        0x93(0: "a", 0x04: "swap_value"),
212        0x94(0: "a", 0x05: "swap_value"),
213        0x95(0: "a", 0x06: "swap_value"),
214        0x96(0: "a", 0x07: "swap_value"),
215        0x97(0: "a", 0x08: "swap_value"),
216        0x98(0: "a", 0x09: "swap_value"),
217        0x99(0: "a", 0x0a: "swap_value"),
218        0x9a(0: "a", 0x0b: "swap_value"),
219        0x9b(0: "a", 0x0c: "swap_value"),
220        0x9c(0: "a", 0x0d: "swap_value"),
221        0x9d(0: "a", 0x0e: "swap_value"),
222        0x9e(0: "a", 0x0f: "swap_value"),
223        0x9f(0: "a", 0x10: "swap_value"),
224
225        0xa0(0: "offset", 1: "size"),
226        0xa1(0: "offset", 1: "size", 2: "topic"),
227        0xa2(0: "offset", 1: "size", 2: "topic1", 3: "topic2"),
228        0xa3(0: "offset", 1: "size", 2: "topic1", 3: "topic2", 4: "topic3"),
229        0xa4(0: "offset", 1: "size", 2: "topic1", 3: "topic2", 4: "topic3", 5: "topic4"),
230        0xa5(),
231        0xa6(),
232        0xa7(),
233        0xa8(),
234        0xa9(),
235        0xaa(),
236        0xab(),
237        0xac(),
238        0xad(),
239        0xae(),
240        0xaf(),
241        0xb0(),
242        0xb1(),
243        0xb2(),
244        0xb3(),
245        0xb4(),
246        0xb5(),
247        0xb6(),
248        0xb7(),
249        0xb8(),
250        0xb9(),
251        0xba(),
252        0xbb(),
253        0xbc(),
254        0xbd(),
255        0xbe(),
256        0xbf(),
257        0xc0(),
258        0xc1(),
259        0xc2(),
260        0xc3(),
261        0xc4(),
262        0xc5(),
263        0xc6(),
264        0xc7(),
265        0xc8(),
266        0xc9(),
267        0xca(),
268        0xcb(),
269        0xcc(),
270        0xcd(),
271        0xce(),
272        0xcf(),
273        0xd0(0: "offset"),
274        0xd1(),
275        0xd2(),
276        0xd3(0: "mem_offset", 1: "offset", 2: "size"),
277        0xd4(),
278        0xd5(),
279        0xd6(),
280        0xd7(),
281        0xd8(),
282        0xd9(),
283        0xda(),
284        0xdb(),
285        0xdc(),
286        0xdd(),
287        0xde(),
288        0xdf(),
289        0xe0(),
290        0xe1(0: "condition"),
291        0xe2(0: "case"),
292        0xe3(),
293        0xe4(),
294        0xe5(),
295        0xe6(),
296        0xe7(),
297        0xe8(),
298        0xe9(),
299        0xea(),
300        0xeb(),
301        0xec(0: "value", 1: "salt", 2: "input_offset", 3: "input_size"),
302        0xed(),
303        0xee(0: "aux_data_offset", 1: "aux_data_size"),
304        0xef(),
305        0xf0(0: "value", 1: "offset", 2: "size"),
306        0xf1(0: "gas", 1: "address", 2: "value", 3: "argsOffset", 4: "argsSize", 5: "retOffset", 6: "retSize"),
307        0xf2(0: "gas", 1: "address", 2: "value", 3: "argsOffset", 4: "argsSize", 5: "retOffset", 6: "retSize"),
308        0xf3(0: "offset", 1: "size"),
309        0xf4(0: "gas", 1: "address", 2: "argsOffset", 3: "argsSize", 4: "retOffset", 5: "retSize"),
310        0xf5(0: "value", 1: "offset", 2: "size", 3: "salt"),
311        0xf6(),
312        0xf7(0: "offset"),
313        0xf8(0: "target_address", 1: "input_offset", 2: "input_size", 3: "value"),
314        0xf9(0: "target_address", 1: "input_offset", 2: "input_size"),
315        0xfa(0: "gas", 1: "address", 2: "argsOffset", 3: "argsSize", 4: "retOffset", 5: "retSize"),
316        0xfb(0: "target_address", 1: "input_offset", 2: "input_size"),
317        0xfc(),
318        0xfd(0: "offset", 1: "size"),
319        0xfe(),
320        0xff(0: "address"),
321    }
322}