1use num_enum::TryFromPrimitive;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
7#[repr(u8)]
8pub enum Opcode {
9 Aaload = 0x32,
10 Aastore = 0x53,
11 AconstNull = 0x01,
12 Aload = 0x19,
13 Aload0 = 0x2A,
14 Aload1 = 0x2B,
15 Aload2 = 0x2C,
16 Aload3 = 0x2D,
17 Anewarray = 0xBD,
18 Areturn = 0xB0,
19 ArrayLength = 0xBE,
20 Astore = 0x3A,
21 Astore0 = 0x4B,
22 Astore1 = 0x4C,
23 Astore2 = 0x4D,
24 Astore3 = 0x4E,
25 Athrow = 0xBF,
26 Baload = 0x33,
27 Bastore = 0x54,
28 Bipush = 0x10,
29 Breakpoint = 0xCA,
30 Caload = 0x34,
31 Castore = 0x55,
32 Checkcast = 0xC0,
33 D2f = 0x90,
34 D2i = 0x8E,
35 D2l = 0x8F,
36 Dadd = 0x63,
37 Daload = 0x31,
38 Dastore = 0x52,
39 Dcmpg = 0x98,
40 Dcmpl = 0x97,
41 Dconst0 = 0x0E,
42 Dconst1 = 0x0F,
43 Ddiv = 0x6F,
44 Dload = 0x18,
45 Dload0 = 0x26,
46 Dload1 = 0x27,
47 Dload2 = 0x28,
48 Dload3 = 0x29,
49 Dmul = 0x6B,
50 Dneg = 0x77,
51 Drem = 0x73,
52 Dreturn = 0xAF,
53 Dstore = 0x39,
54 Dstore0 = 0x47,
55 Dstore1 = 0x48,
56 Dstore2 = 0x49,
57 Dstore3 = 0x4A,
58 Dsub = 0x67,
59 Dup = 0x59,
60 DupX1 = 0x5A,
61 DupX2 = 0x5B,
62 Dup2 = 0x5C,
63 Dup2X1 = 0x5D,
64 Dup2X2 = 0x5E,
65 F2d = 0x8D,
66 F2i = 0x8B,
67 F2l = 0x8C,
68 Fadd = 0x62,
69 Faload = 0x30,
70 Fastore = 0x51,
71 Fcmpg = 0x96,
72 Fcmpl = 0x95,
73 Fconst0 = 0x0B,
74 Fconst1 = 0x0C,
75 Fconst2 = 0x0D,
76 Fdiv = 0x6E,
77 Fload = 0x17,
78 Fload0 = 0x22,
79 Fload1 = 0x23,
80 Fload2 = 0x24,
81 Fload3 = 0x25,
82 Fmul = 0x6A,
83 Fneg = 0x76,
84 Frem = 0x72,
85 Freturn = 0xAE,
86 Fstore = 0x38,
87 Fstore0 = 0x43,
88 Fstore1 = 0x44,
89 Fstore2 = 0x45,
90 Fstore3 = 0x46,
91 Fsub = 0x66,
92 Getfield = 0xB4,
93 Getstatic = 0xB2,
94 Goto = 0xA7,
95 GotoW = 0xC8,
96 I2b = 0x91,
97 I2c = 0x92,
98 I2d = 0x87,
99 I2f = 0x86,
100 I2l = 0x85,
101 I2s = 0x93,
102 Iadd = 0x60,
103 Iaload = 0x2E,
104 Iand = 0x7E,
105 Iastore = 0x4F,
106 IconstM1 = 0x02,
107 Iconst0 = 0x03,
108 Iconst1 = 0x04,
109 Iconst2 = 0x05,
110 Iconst3 = 0x06,
111 Iconst4 = 0x07,
112 Iconst5 = 0x08,
113 Idiv = 0x6C,
114 IfAcmpEq = 0xA5,
115 IfAcmpNe = 0xA6,
116 IfIcmpeq = 0x9F,
117 IfIcmpge = 0xA2,
118 IfIcmpgt = 0xA3,
119 IfIcmple = 0xA4,
120 IfIcmplt = 0xA1,
121 IfIcmpne = 0xA0,
122 IfEq = 0x99,
123 IfGe = 0x9C,
124 IfGt = 0x9D,
125 IfLe = 0x9E,
126 IfLt = 0x9B,
127 IfNe = 0x9A,
128 Ifnonnull = 0xC7,
129 Ifnull = 0xC6,
130 Iinc = 0x84,
131 Iload = 0x15,
132 Iload0 = 0x1A,
133 Iload1 = 0x1B,
134 Iload2 = 0x1C,
135 Iload3 = 0x1D,
136 Imul = 0x68,
137 Ineg = 0x74,
138 Instanceof = 0xC1,
139 InvokeDynamic = 0xBA,
140 InvokeInterface = 0xB9,
141 InvokeSpecial = 0xB7,
142 InvokeStatic = 0xB8,
143 InvokeVirtual = 0xB6,
144 Ior = 0x80,
145 Irem = 0x70,
146 Ireturn = 0xAC,
147 Ishl = 0x78,
148 Ishr = 0x7A,
149 Istore = 0x36,
150 Istore0 = 0x3B,
151 Istore1 = 0x3C,
152 Istore2 = 0x3D,
153 Istore3 = 0x3E,
154 Isub = 0x64,
155 Iushr = 0x7C,
156 Ixor = 0x82,
157 Jsr = 0xA8,
158 JsrW = 0xC9,
159 L2d = 0x8A,
160 L2f = 0x89,
161 L2i = 0x88,
162 Ladd = 0x61,
163 Laload = 0x2F,
164 Land = 0x7F,
165 Lastore = 0x50,
166 Lcmp = 0x94,
167 Lconst0 = 0x09,
168 Lconst1 = 0x0A,
169 Ldc = 0x12,
170 LdcW = 0x13,
171 Ldc2W = 0x14,
172 Ldiv = 0x6D,
173 Lload = 0x16,
174 Lload0 = 0x1E,
175 Lload1 = 0x1F,
176 Lload2 = 0x20,
177 Lload3 = 0x21,
178 Lmul = 0x69,
179 Lneg = 0x75,
180 Lookupswitch = 0xAB,
181 Lor = 0x81,
182 Lrem = 0x71,
183 Lreturn = 0xAD,
184 Lshl = 0x79,
185 Lshr = 0x7B,
186 Lstore = 0x37,
187 Lstore0 = 0x3F,
188 Lstore1 = 0x40,
189 Lstore2 = 0x41,
190 Lstore3 = 0x42,
191 Lsub = 0x65,
192 Lushr = 0x7D,
193 Lxor = 0x83,
194 Monitorenter = 0xC2,
195 Monitorexit = 0xC3,
196 Multianewarray = 0xC5,
197 New = 0xBB,
198 Newarray = 0xBC,
199 Nop = 0x00,
200 Pop = 0x57,
201 Pop2 = 0x58,
202 Putfield = 0xB5,
203 Putstatic = 0xB3,
204 Ret = 0xA9,
205 Return = 0xB1,
206 Saload = 0x35,
207 Sastore = 0x56,
208 Sipush = 0x11,
209 Swap = 0x5F,
210 TableSwitch = 0xAA,
211}
212
213impl Opcode {
214 pub const fn as_str(self) -> &'static str {
215 match self {
216 Self::Aaload => "aaload",
217 Self::Aastore => "aastore",
218 Self::AconstNull => "aconst_null",
219 Self::Aload => "aload",
220 Self::Aload0 => "aload_0",
221 Self::Aload1 => "aload_1",
222 Self::Aload2 => "aload_2",
223 Self::Aload3 => "aload_3",
224 Self::Anewarray => "anewarray",
225 Self::Areturn => "areturn",
226 Self::ArrayLength => "arraylength",
227 Self::Astore => "astore",
228 Self::Astore0 => "astore_0",
229 Self::Astore1 => "astore_1",
230 Self::Astore2 => "astore_2",
231 Self::Astore3 => "astore_3",
232 Self::Athrow => "athrow",
233 Self::Baload => "baload",
234 Self::Bastore => "bastore",
235 Self::Bipush => "bipush",
236 Self::Breakpoint => "breakpoint",
237 Self::Caload => "caload",
238 Self::Castore => "castore",
239 Self::Checkcast => "checkcast",
240 Self::D2f => "d2f",
241 Self::D2i => "d2i",
242 Self::D2l => "d2l",
243 Self::Dadd => "dadd",
244 Self::Daload => "daload",
245 Self::Dastore => "dastore",
246 Self::Dcmpg => "dcmpg",
247 Self::Dcmpl => "dcmpl",
248 Self::Dconst0 => "dconst_0",
249 Self::Dconst1 => "dconst_1",
250 Self::Ddiv => "ddiv",
251 Self::Dload => "dload",
252 Self::Dload0 => "dload_0",
253 Self::Dload1 => "dload_1",
254 Self::Dload2 => "dload_2",
255 Self::Dload3 => "dload_3",
256 Self::Dmul => "dmul",
257 Self::Dneg => "dneg",
258 Self::Drem => "drem",
259 Self::Dreturn => "dreturn",
260 Self::Dstore => "dstore",
261 Self::Dstore0 => "dstore_0",
262 Self::Dstore1 => "dstore_1",
263 Self::Dstore2 => "dstore_2",
264 Self::Dstore3 => "dstore_3",
265 Self::Dsub => "dsub",
266 Self::Dup => "dup",
267 Self::DupX1 => "dup_x1",
268 Self::DupX2 => "dup_x2",
269 Self::Dup2 => "dup2",
270 Self::Dup2X1 => "dup2_x1",
271 Self::Dup2X2 => "dup2_x2",
272 Self::F2d => "f2d",
273 Self::F2i => "f2i",
274 Self::F2l => "f2l",
275 Self::Fadd => "fadd",
276 Self::Faload => "faload",
277 Self::Fastore => "fastore",
278 Self::Fcmpg => "fcmpg",
279 Self::Fcmpl => "fcmpl",
280 Self::Fconst0 => "fconst_0",
281 Self::Fconst1 => "fconst_1",
282 Self::Fconst2 => "fconst_2",
283 Self::Fdiv => "fdiv",
284 Self::Fload => "fload",
285 Self::Fload0 => "fload_0",
286 Self::Fload1 => "fload_1",
287 Self::Fload2 => "fload_2",
288 Self::Fload3 => "fload_3",
289 Self::Fmul => "fmul",
290 Self::Fneg => "fneg",
291 Self::Frem => "frem",
292 Self::Freturn => "freturn",
293 Self::Fstore => "fstore",
294 Self::Fstore0 => "fstore_0",
295 Self::Fstore1 => "fstore_1",
296 Self::Fstore2 => "fstore_2",
297 Self::Fstore3 => "fstore_3",
298 Self::Fsub => "fsub",
299 Self::Getfield => "getfield",
300 Self::Getstatic => "getstatic",
301 Self::Goto => "goto",
302 Self::GotoW => "goto_w",
303 Self::I2b => "i2b",
304 Self::I2c => "i2c",
305 Self::I2d => "i2d",
306 Self::I2f => "i2f",
307 Self::I2l => "i2l",
308 Self::I2s => "i2s",
309 Self::Iadd => "iadd",
310 Self::Iaload => "iaload",
311 Self::Iand => "iand",
312 Self::Iastore => "iastore",
313 Self::IconstM1 => "iconst_m1",
314 Self::Iconst0 => "iconst_0",
315 Self::Iconst1 => "iconst_1",
316 Self::Iconst2 => "iconst_2",
317 Self::Iconst3 => "iconst_3",
318 Self::Iconst4 => "iconst_4",
319 Self::Iconst5 => "iconst_5",
320 Self::Idiv => "idiv",
321 Self::IfAcmpEq => "if_acmpeq",
322 Self::IfAcmpNe => "if_acmpne",
323 Self::IfIcmpeq => "if_icmpeq",
324 Self::IfIcmpge => "if_icmpge",
325 Self::IfIcmpgt => "if_icmpgt",
326 Self::IfIcmple => "if_icmple",
327 Self::IfIcmplt => "if_icmplt",
328 Self::IfIcmpne => "if_icmpne",
329 Self::IfEq => "ifeq",
330 Self::IfGe => "ifge",
331 Self::IfGt => "ifgt",
332 Self::IfLe => "ifle",
333 Self::IfLt => "iflt",
334 Self::IfNe => "ifne",
335 Self::Ifnonnull => "ifnonnull",
336 Self::Ifnull => "ifnull",
337 Self::Iinc => "iinc",
338 Self::Iload => "iload",
339 Self::Iload0 => "iload_0",
340 Self::Iload1 => "iload_1",
341 Self::Iload2 => "iload_2",
342 Self::Iload3 => "iload_3",
343 Self::Imul => "imul",
344 Self::Ineg => "ineg",
345 Self::Instanceof => "instanceof",
346 Self::InvokeDynamic => "invokedynamic",
347 Self::InvokeInterface => "invokeinterface",
348 Self::InvokeSpecial => "invokespecial",
349 Self::InvokeStatic => "invokestatic",
350 Self::InvokeVirtual => "invokevirtual",
351 Self::Ior => "ior",
352 Self::Irem => "irem",
353 Self::Ireturn => "ireturn",
354 Self::Ishl => "ishl",
355 Self::Ishr => "ishr",
356 Self::Istore => "istore",
357 Self::Istore0 => "istore_0",
358 Self::Istore1 => "istore_1",
359 Self::Istore2 => "istore_2",
360 Self::Istore3 => "istore_3",
361 Self::Isub => "isub",
362 Self::Iushr => "iushr",
363 Self::Ixor => "ixor",
364 Self::Jsr => "jsr",
365 Self::JsrW => "jsr_w",
366 Self::L2d => "l2d",
367 Self::L2f => "l2f",
368 Self::L2i => "l2i",
369 Self::Ladd => "ladd",
370 Self::Laload => "laload",
371 Self::Land => "land",
372 Self::Lastore => "lastore",
373 Self::Lcmp => "lcmp",
374 Self::Lconst0 => "lconst_0",
375 Self::Lconst1 => "lconst_1",
376 Self::Ldc => "ldc",
377 Self::LdcW => "ldc_w",
378 Self::Ldc2W => "ldc2_w",
379 Self::Ldiv => "ldiv",
380 Self::Lload => "lload",
381 Self::Lload0 => "lload_0",
382 Self::Lload1 => "lload_1",
383 Self::Lload2 => "lload_2",
384 Self::Lload3 => "lload_3",
385 Self::Lmul => "lmul",
386 Self::Lneg => "lneg",
387 Self::Lookupswitch => "lookupswitch",
388 Self::Lor => "lor",
389 Self::Lrem => "lrem",
390 Self::Lreturn => "lreturn",
391 Self::Lshl => "lshl",
392 Self::Lshr => "lshr",
393 Self::Lstore => "lstore",
394 Self::Lstore0 => "lstore_0",
395 Self::Lstore1 => "lstore_1",
396 Self::Lstore2 => "lstore_2",
397 Self::Lstore3 => "lstore_3",
398 Self::Lsub => "lsub",
399 Self::Lushr => "lushr",
400 Self::Lxor => "lxor",
401 Self::Monitorenter => "monitorenter",
402 Self::Monitorexit => "monitorexit",
403 Self::Multianewarray => "multianewarray",
404 Self::New => "new",
405 Self::Newarray => "newarray",
406 Self::Nop => "nop",
407 Self::Pop => "pop",
408 Self::Pop2 => "pop2",
409 Self::Putfield => "putfield",
410 Self::Putstatic => "putstatic",
411 Self::Ret => "ret",
412 Self::Return => "return",
413 Self::Saload => "saload",
414 Self::Sastore => "sastore",
415 Self::Sipush => "sipush",
416 Self::Swap => "swap",
417 Self::TableSwitch => "tableswitch",
418 }
419 }
420}
421
422impl Opcode {
423 pub const fn operand_size(self) -> u8 {
424 match self {
425 Self::GotoW | Self::JsrW | Self::InvokeDynamic | Self::InvokeInterface => 4,
427
428 Self::Multianewarray => 3,
430
431 Self::Anewarray
433 | Self::Checkcast
434 | Self::Getfield
435 | Self::Getstatic
436 | Self::Goto
437 | Self::IfAcmpEq
438 | Self::IfAcmpNe
439 | Self::IfEq
440 | Self::IfGe
441 | Self::IfGt
442 | Self::IfLe
443 | Self::IfLt
444 | Self::IfNe
445 | Self::Ifnonnull
446 | Self::Ifnull
447 | Self::IfIcmpeq
448 | Self::IfIcmpge
449 | Self::IfIcmpgt
450 | Self::IfIcmple
451 | Self::IfIcmplt
452 | Self::IfIcmpne
453 | Self::Iinc
454 | Self::Instanceof
455 | Self::InvokeSpecial
456 | Self::InvokeStatic
457 | Self::InvokeVirtual
458 | Self::Ldc2W
459 | Self::LdcW
460 | Self::New
461 | Self::Putfield
462 | Self::Putstatic
463 | Self::Sipush
464 | Self::Jsr => 2,
465
466 Self::Aload
468 | Self::Astore
469 | Self::Bipush
470 | Self::Dload
471 | Self::Dstore
472 | Self::Fload
473 | Self::Fstore
474 | Self::Iload
475 | Self::Istore
476 | Self::Ldc
477 | Self::Lload
478 | Self::Lstore
479 | Self::Newarray
480 | Self::Ret => 1,
481
482 _ => 0,
484 }
485 }
486
487 pub const fn pc_size(self) -> Option<u8> {
488 match self {
489 Self::Lookupswitch | Self::TableSwitch => None,
490 _ => Some(1 + self.operand_size()),
491 }
492 }
493}
494
495impl std::fmt::Display for Opcode {
496 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
497 f.write_str(self.as_str())
498 }
499}