foundry_debugger/
op.rs

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