1use super::opcode::Opcode;
6use super::operand::{ArrayType, LookupSwitchData, TableSwitchData};
7use crate::error::InstructionErr;
8use lvm_common::utils::cursor::ByteCursor;
9use num_enum::TryFromPrimitive;
10use std::fmt::Formatter;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum Instruction {
15 Aaload,
16 Aastore,
17 AconstNull,
18 Aload(u8),
19 Aload0,
20 Aload1,
21 Aload2,
22 Aload3,
23 Anewarray(u16),
24 Areturn,
25 ArrayLength,
26 Astore(u8),
27 Astore0,
28 Astore1,
29 Astore2,
30 Astore3,
31 Athrow,
32 Baload,
33 Bastore,
34 Bipush(i8),
35 Breakpoint,
36 Caload,
37 Castore,
38 Checkcast(u16),
39 D2f,
40 D2i,
41 D2l,
42 Dadd,
43 Daload,
44 Dastore,
45 Dcmpg,
46 Dcmpl,
47 Dconst0,
48 Dconst1,
49 Ddiv,
50 Dload(u8),
51 Dload0,
52 Dload1,
53 Dload2,
54 Dload3,
55 Dmul,
56 Dneg,
57 Drem,
58 Dreturn,
59 Dstore(u8),
60 Dstore0,
61 Dstore1,
62 Dstore2,
63 Dstore3,
64 Dsub,
65 Dup,
66 Dup2,
67 Dup2X1,
68 Dup2X2,
69 DupX1,
70 DupX2,
71 F2d,
72 F2i,
73 F2l,
74 Fadd,
75 Faload,
76 Fastore,
77 Fcmpg,
78 Fcmpl,
79 Fconst0,
80 Fconst1,
81 Fconst2,
82 Fdiv,
83 Fload(u8),
84 Fload0,
85 Fload1,
86 Fload2,
87 Fload3,
88 Fmul,
89 Fneg,
90 Frem,
91 Freturn,
92 Fstore(u8),
93 Fstore0,
94 Fstore1,
95 Fstore2,
96 Fstore3,
97 Fsub,
98 Getfield(u16),
99 Getstatic(u16),
100 Goto(i16),
101 GotoW(i32),
102 I2b,
103 I2c,
104 I2d,
105 I2f,
106 I2l,
107 I2s,
108 Iadd,
109 Iaload,
110 Iand,
111 Iastore,
112 IconstM1,
113 Iconst0,
114 Iconst1,
115 Iconst2,
116 Iconst3,
117 Iconst4,
118 Iconst5,
119 Idiv,
120 IfAcmpEq(i16),
121 IfAcmpNe(i16),
122 IfEq(i16),
123 IfGe(i16),
124 IfGt(i16),
125 IfIcmpeq(i16),
126 IfIcmpge(i16),
127 IfIcmpgt(i16),
128 IfIcmple(i16),
129 IfIcmplt(i16),
130 IfIcmpne(i16),
131 IfLe(i16),
132 IfLt(i16),
133 IfNe(i16),
134 Ifnonnull(i16),
135 Ifnull(i16),
136 Iinc(u8, i8),
137 Iload(u8),
138 Iload0,
139 Iload1,
140 Iload2,
141 Iload3,
142 Imul,
143 Ineg,
144 Lookupswitch(LookupSwitchData),
145 Instanceof(u16),
146 InvokeDynamic(u16),
147 InvokeInterface(u16, u8),
148 InvokeSpecial(u16),
149 InvokeStatic(u16),
150 InvokeVirtual(u16),
151 Ior,
152 Irem,
153 Ireturn,
154 Ishl,
155 Ishr,
156 Istore(u8),
157 Istore0,
158 Istore1,
159 Istore2,
160 Istore3,
161 Isub,
162 Iushr,
163 Ixor,
164 Jsr(i16),
165 JsrW(i32),
166 L2d,
167 L2f,
168 L2i,
169 Ladd,
170 Laload,
171 Land,
172 Lastore,
173 Lcmp,
174 Lconst0,
175 Lconst1,
176 Ldc(u16),
177 Ldc2W(u16),
178 LdcW(u16),
179 Ldiv,
180 Lload(u8),
181 Lload0,
182 Lload1,
183 Lload2,
184 Lload3,
185 Lmul,
186 Lneg,
187 Lor,
188 Lrem,
189 Lreturn,
190 Lshl,
191 Lshr,
192 Lstore(u8),
193 Lstore0,
194 Lstore1,
195 Lstore2,
196 Lstore3,
197 Lsub,
198 Lushr,
199 Lxor,
200 Monitorenter,
201 Monitorexit,
202 Multianewarray(u16, u8),
203 New(u16),
204 Newarray(ArrayType),
205 Nop,
206 Pop,
207 Pop2,
208 Putfield(u16),
209 Putstatic(u16),
210 Ret(u8),
211 Return,
212 Saload,
213 Sastore,
214 Sipush(i16),
215 Swap,
216 Impdep1,
217 Impdep2,
218 TableSwitch(TableSwitchData),
219}
220
221impl Instruction {
222 pub fn is_branch(&self) -> bool {
223 matches!(
224 self,
225 Self::Goto(_)
226 | Self::GotoW(_)
227 | Self::Jsr(_)
228 | Self::JsrW(_)
229 | Self::IfAcmpEq(_)
230 | Self::IfAcmpNe(_)
231 | Self::IfEq(_)
232 | Self::IfGe(_)
233 | Self::IfGt(_)
234 | Self::IfLe(_)
235 | Self::IfLt(_)
236 | Self::IfNe(_)
237 | Self::Ifnonnull(_)
238 | Self::Ifnull(_)
239 | Self::IfIcmpeq(_)
240 | Self::IfIcmpge(_)
241 | Self::IfIcmpgt(_)
242 | Self::IfIcmple(_)
243 | Self::IfIcmplt(_)
244 | Self::IfIcmpne(_)
245 | Self::Lookupswitch(_)
246 | Self::TableSwitch(_)
247 )
248 }
249
250 pub fn byte_size(&self) -> u16 {
251 match self {
252 Self::Lookupswitch(data) => {
254 1 + data.padding as u16 + 4 + 4 + (8 * data.pairs.len() as u16)
256 }
257 Self::TableSwitch(data) => {
258 1 + data.padding as u16 + 4 + 4 + 4 + (4 * data.offsets.len() as u16)
260 }
261 Self::GotoW(_)
263 | Self::JsrW(_)
264 | Self::InvokeDynamic(_)
265 | Self::InvokeInterface(_, _) => 5,
266
267 Self::Multianewarray(_, _) => 4,
269
270 Self::Anewarray(_)
272 | Self::Checkcast(_)
273 | Self::Getfield(_)
274 | Self::Getstatic(_)
275 | Self::Goto(_)
276 | Self::IfAcmpEq(_)
277 | Self::IfAcmpNe(_)
278 | Self::IfEq(_)
279 | Self::IfGe(_)
280 | Self::IfGt(_)
281 | Self::IfLe(_)
282 | Self::IfLt(_)
283 | Self::IfNe(_)
284 | Self::Ifnonnull(_)
285 | Self::Ifnull(_)
286 | Self::IfIcmpeq(_)
287 | Self::IfIcmpge(_)
288 | Self::IfIcmpgt(_)
289 | Self::IfIcmple(_)
290 | Self::IfIcmplt(_)
291 | Self::IfIcmpne(_)
292 | Self::Iinc(_, _)
293 | Self::Instanceof(_)
294 | Self::InvokeSpecial(_)
295 | Self::InvokeStatic(_)
296 | Self::InvokeVirtual(_)
297 | Self::Ldc2W(_)
298 | Self::LdcW(_)
299 | Self::New(_)
300 | Self::Putfield(_)
301 | Self::Putstatic(_)
302 | Self::Sipush(_)
303 | Self::Jsr(_) => 3,
304
305 Self::Aload(_)
307 | Self::Astore(_)
308 | Self::Bipush(_)
309 | Self::Dload(_)
310 | Self::Dstore(_)
311 | Self::Fload(_)
312 | Self::Fstore(_)
313 | Self::Iload(_)
314 | Self::Istore(_)
315 | Self::Ldc(_)
316 | Self::Lload(_)
317 | Self::Lstore(_)
318 | Self::Newarray(_)
319 | Self::Ret(_) => 2,
320
321 _ => 1,
323 }
324 }
325}
326
327impl Instruction {
328 fn switch_padding(pc: usize) -> u8 {
329 ((4 - ((pc + 1) & 3)) & 3) as u8
330 }
331
332 pub fn new_at(code: &[u8], pc: usize) -> Result<Instruction, InstructionErr> {
333 let mut cursor = ByteCursor::new(&code[pc..]);
334 let opcode_byte = cursor.u8()?;
335 let opcode = Opcode::try_from(opcode_byte)
336 .map_err(|_| InstructionErr::UnsupportedOpCode(opcode_byte))?;
337
338 let instruction = match opcode {
339 Opcode::Aaload => Self::Aaload,
340 Opcode::Aastore => Self::Aastore,
341 Opcode::AconstNull => Self::AconstNull,
342 Opcode::Aload => Self::Aload(cursor.u8()?),
343 Opcode::Aload0 => Self::Aload0,
344 Opcode::Aload1 => Self::Aload1,
345 Opcode::Aload2 => Self::Aload2,
346 Opcode::Aload3 => Self::Aload3,
347 Opcode::Anewarray => Self::Anewarray(cursor.u16()?),
348 Opcode::Areturn => Self::Areturn,
349 Opcode::ArrayLength => Self::ArrayLength,
350 Opcode::Astore => Self::Astore(cursor.u8()?),
351 Opcode::Astore0 => Self::Astore0,
352 Opcode::Astore1 => Self::Astore1,
353 Opcode::Astore2 => Self::Astore2,
354 Opcode::Astore3 => Self::Astore3,
355 Opcode::Athrow => Self::Athrow,
356 Opcode::Baload => Self::Baload,
357 Opcode::Bastore => Self::Bastore,
358 Opcode::Bipush => Self::Bipush(cursor.i8()?),
359 Opcode::Breakpoint => Self::Breakpoint,
360 Opcode::Caload => Self::Caload,
361 Opcode::Castore => Self::Castore,
362 Opcode::Checkcast => Self::Checkcast(cursor.u16()?),
363 Opcode::D2f => Self::D2f,
364 Opcode::D2i => Self::D2i,
365 Opcode::D2l => Self::D2l,
366 Opcode::Dadd => Self::Dadd,
367 Opcode::Daload => Self::Daload,
368 Opcode::Dastore => Self::Dastore,
369 Opcode::Dcmpg => Self::Dcmpg,
370 Opcode::Dcmpl => Self::Dcmpl,
371 Opcode::Dconst0 => Self::Dconst0,
372 Opcode::Dconst1 => Self::Dconst1,
373 Opcode::Ddiv => Self::Ddiv,
374 Opcode::Dload => Self::Dload(cursor.u8()?),
375 Opcode::Dload0 => Self::Dload0,
376 Opcode::Dload1 => Self::Dload1,
377 Opcode::Dload2 => Self::Dload2,
378 Opcode::Dload3 => Self::Dload3,
379 Opcode::Dmul => Self::Dmul,
380 Opcode::Dneg => Self::Dneg,
381 Opcode::Drem => Self::Drem,
382 Opcode::Dreturn => Self::Dreturn,
383 Opcode::Dstore => Self::Dstore(cursor.u8()?),
384 Opcode::Dstore0 => Self::Dstore0,
385 Opcode::Dstore1 => Self::Dstore1,
386 Opcode::Dstore2 => Self::Dstore2,
387 Opcode::Dstore3 => Self::Dstore3,
388 Opcode::Dsub => Self::Dsub,
389 Opcode::Dup => Self::Dup,
390 Opcode::Dup2 => Self::Dup2,
391 Opcode::Dup2X1 => Self::Dup2X1,
392 Opcode::Dup2X2 => Self::Dup2X2,
393 Opcode::DupX1 => Self::DupX1,
394 Opcode::DupX2 => Self::DupX2,
395 Opcode::F2d => Self::F2d,
396 Opcode::F2i => Self::F2i,
397 Opcode::F2l => Self::F2l,
398 Opcode::Fadd => Self::Fadd,
399 Opcode::Faload => Self::Faload,
400 Opcode::Fastore => Self::Fastore,
401 Opcode::Fcmpg => Self::Fcmpg,
402 Opcode::Fcmpl => Self::Fcmpl,
403 Opcode::Fconst0 => Self::Fconst0,
404 Opcode::Fconst1 => Self::Fconst1,
405 Opcode::Fconst2 => Self::Fconst2,
406 Opcode::Fdiv => Self::Fdiv,
407 Opcode::Fload => Self::Fload(cursor.u8()?),
408 Opcode::Fload0 => Self::Fload0,
409 Opcode::Fload1 => Self::Fload1,
410 Opcode::Fload2 => Self::Fload2,
411 Opcode::Fload3 => Self::Fload3,
412 Opcode::Fmul => Self::Fmul,
413 Opcode::Fneg => Self::Fneg,
414 Opcode::Frem => Self::Frem,
415 Opcode::Freturn => Self::Freturn,
416 Opcode::Fstore => Self::Fstore(cursor.u8()?),
417 Opcode::Fstore0 => Self::Fstore0,
418 Opcode::Fstore1 => Self::Fstore1,
419 Opcode::Fstore2 => Self::Fstore2,
420 Opcode::Fstore3 => Self::Fstore3,
421 Opcode::Fsub => Self::Fsub,
422 Opcode::Getfield => Self::Getfield(cursor.u16()?),
423 Opcode::Getstatic => Self::Getstatic(cursor.u16()?),
424 Opcode::Goto => Self::Goto(cursor.i16()?),
425 Opcode::GotoW => Self::GotoW(cursor.i32()?),
426 Opcode::I2b => Self::I2b,
427 Opcode::I2c => Self::I2c,
428 Opcode::I2d => Self::I2d,
429 Opcode::I2f => Self::I2f,
430 Opcode::I2l => Self::I2l,
431 Opcode::I2s => Self::I2s,
432 Opcode::Iadd => Self::Iadd,
433 Opcode::Iaload => Self::Iaload,
434 Opcode::Iand => Self::Iand,
435 Opcode::Iastore => Self::Iastore,
436 Opcode::IconstM1 => Self::IconstM1,
437 Opcode::Iconst0 => Self::Iconst0,
438 Opcode::Iconst1 => Self::Iconst1,
439 Opcode::Iconst2 => Self::Iconst2,
440 Opcode::Iconst3 => Self::Iconst3,
441 Opcode::Iconst4 => Self::Iconst4,
442 Opcode::Iconst5 => Self::Iconst5,
443 Opcode::Idiv => Self::Idiv,
444 Opcode::IfAcmpEq => Self::IfAcmpEq(cursor.i16()?),
445 Opcode::IfAcmpNe => Self::IfAcmpNe(cursor.i16()?),
446 Opcode::IfEq => Self::IfEq(cursor.i16()?),
447 Opcode::IfGe => Self::IfGe(cursor.i16()?),
448 Opcode::IfGt => Self::IfGt(cursor.i16()?),
449 Opcode::IfLe => Self::IfLe(cursor.i16()?),
450 Opcode::IfLt => Self::IfLt(cursor.i16()?),
451 Opcode::IfNe => Self::IfNe(cursor.i16()?),
452 Opcode::Ifnonnull => Self::Ifnonnull(cursor.i16()?),
453 Opcode::Ifnull => Self::Ifnull(cursor.i16()?),
454 Opcode::IfIcmpeq => Self::IfIcmpeq(cursor.i16()?),
455 Opcode::IfIcmpge => Self::IfIcmpge(cursor.i16()?),
456 Opcode::IfIcmpgt => Self::IfIcmpgt(cursor.i16()?),
457 Opcode::IfIcmple => Self::IfIcmple(cursor.i16()?),
458 Opcode::IfIcmplt => Self::IfIcmplt(cursor.i16()?),
459 Opcode::IfIcmpne => Self::IfIcmpne(cursor.i16()?),
460 Opcode::Iinc => Self::Iinc(cursor.u8()?, cursor.i8()?),
461 Opcode::Iload => Self::Iload(cursor.u8()?),
462 Opcode::Iload0 => Self::Iload0,
463 Opcode::Iload1 => Self::Iload1,
464 Opcode::Iload2 => Self::Iload2,
465 Opcode::Iload3 => Self::Iload3,
466 Opcode::Imul => Self::Imul,
467 Opcode::Ineg => Self::Ineg,
468 Opcode::Instanceof => Self::Instanceof(cursor.u16()?),
469 Opcode::InvokeDynamic => {
470 let index = cursor.u16()?;
471 let _zero = cursor.u16()?; Self::InvokeDynamic(index)
473 }
474 Opcode::InvokeInterface => {
475 let index = cursor.u16()?;
476 let count = cursor.u8()?;
477 let _zero = cursor.u8()?; Self::InvokeInterface(index, count)
479 }
480 Opcode::InvokeSpecial => Self::InvokeSpecial(cursor.u16()?),
481 Opcode::InvokeStatic => Self::InvokeStatic(cursor.u16()?),
482 Opcode::InvokeVirtual => Self::InvokeVirtual(cursor.u16()?),
483 Opcode::Ior => Self::Ior,
484 Opcode::Irem => Self::Irem,
485 Opcode::Ireturn => Self::Ireturn,
486 Opcode::Ishl => Self::Ishl,
487 Opcode::Ishr => Self::Ishr,
488 Opcode::Istore => Self::Istore(cursor.u8()?),
489 Opcode::Istore0 => Self::Istore0,
490 Opcode::Istore1 => Self::Istore1,
491 Opcode::Istore2 => Self::Istore2,
492 Opcode::Istore3 => Self::Istore3,
493 Opcode::Isub => Self::Isub,
494 Opcode::Iushr => Self::Iushr,
495 Opcode::Ixor => Self::Ixor,
496 Opcode::Jsr => Self::Jsr(cursor.i16()?),
497 Opcode::JsrW => Self::JsrW(cursor.i32()?),
498 Opcode::L2d => Self::L2d,
499 Opcode::L2f => Self::L2f,
500 Opcode::L2i => Self::L2i,
501 Opcode::Ladd => Self::Ladd,
502 Opcode::Laload => Self::Laload,
503 Opcode::Land => Self::Land,
504 Opcode::Lastore => Self::Lastore,
505 Opcode::Lcmp => Self::Lcmp,
506 Opcode::Lconst0 => Self::Lconst0,
507 Opcode::Lconst1 => Self::Lconst1,
508 Opcode::Ldc => Self::Ldc(cursor.u8()? as u16),
509 Opcode::Ldc2W => Self::Ldc2W(cursor.u16()?),
510 Opcode::LdcW => Self::LdcW(cursor.u16()?),
511 Opcode::Ldiv => Self::Ldiv,
512 Opcode::Lload => Self::Lload(cursor.u8()?),
513 Opcode::Lload0 => Self::Lload0,
514 Opcode::Lload1 => Self::Lload1,
515 Opcode::Lload2 => Self::Lload2,
516 Opcode::Lload3 => Self::Lload3,
517 Opcode::Lmul => Self::Lmul,
518 Opcode::Lneg => Self::Lneg,
519 Opcode::Lookupswitch => {
520 let padding = Self::switch_padding(pc);
521 for _ in 0..padding {
522 cursor.u8()?;
523 }
524
525 let default_offset = cursor.i32()?;
526 let npairs = cursor.i32()?;
527 let mut pairs = Vec::with_capacity(npairs as usize);
528 for _ in 0..npairs {
529 let match_value = cursor.i32()?;
530 let offset = cursor.i32()?;
531 pairs.push((match_value, offset));
532 }
533 Instruction::Lookupswitch(LookupSwitchData {
534 padding,
535 default_offset,
536 pairs,
537 })
538 }
539 Opcode::Lor => Self::Lor,
540 Opcode::Lrem => Self::Lrem,
541 Opcode::Lreturn => Self::Lreturn,
542 Opcode::Lshl => Self::Lshl,
543 Opcode::Lshr => Self::Lshr,
544 Opcode::Lstore => Self::Lstore(cursor.u8()?),
545 Opcode::Lstore0 => Self::Lstore0,
546 Opcode::Lstore1 => Self::Lstore1,
547 Opcode::Lstore2 => Self::Lstore2,
548 Opcode::Lstore3 => Self::Lstore3,
549 Opcode::Lsub => Self::Lsub,
550 Opcode::Lushr => Self::Lushr,
551 Opcode::Lxor => Self::Lxor,
552 Opcode::Monitorenter => Self::Monitorenter,
553 Opcode::Monitorexit => Self::Monitorexit,
554 Opcode::Multianewarray => Self::Multianewarray(cursor.u16()?, cursor.u8()?),
555 Opcode::New => Self::New(cursor.u16()?),
556 Opcode::Newarray => {
557 let array_type_raw = cursor.u8()?;
558 let array_type = ArrayType::try_from_primitive(array_type_raw)
559 .map_err(|_| InstructionErr::UnknownArrayType(array_type_raw))?;
560 Self::Newarray(array_type)
561 }
562 Opcode::Nop => Self::Nop,
563 Opcode::Pop => Self::Pop,
564 Opcode::Pop2 => Self::Pop2,
565 Opcode::Putfield => Self::Putfield(cursor.u16()?),
566 Opcode::Putstatic => Self::Putstatic(cursor.u16()?),
567 Opcode::Ret => Self::Ret(cursor.u8()?),
568 Opcode::Return => Self::Return,
569 Opcode::Saload => Self::Saload,
570 Opcode::Sastore => Self::Sastore,
571 Opcode::Sipush => Self::Sipush(cursor.i16()?),
572 Opcode::Swap => Self::Swap,
573 Opcode::TableSwitch => {
574 let padding = Self::switch_padding(pc);
575 for _ in 0..padding {
576 cursor.u8()?;
577 }
578
579 let default_offset = cursor.i32()?;
580 let low = cursor.i32()?;
581 let high = cursor.i32()?;
582 let num_offsets = (high - low + 1) as usize;
583 let mut offsets = Vec::with_capacity(num_offsets);
584 for _ in 0..num_offsets {
585 offsets.push(cursor.i32()?);
586 }
587 Instruction::TableSwitch(TableSwitchData {
588 padding,
589 default_offset,
590 low,
591 high,
592 offsets,
593 })
594 }
595 };
596
597 Ok(instruction)
598 }
599
600 pub fn opcode(&self) -> Option<Opcode> {
601 let op = match self {
602 Self::Aaload => Opcode::Aaload,
603 Self::Aastore => Opcode::Aastore,
604 Self::AconstNull => Opcode::AconstNull,
605 Self::Aload(_) => Opcode::Aload,
606 Self::Aload0 => Opcode::Aload0,
607 Self::Aload1 => Opcode::Aload1,
608 Self::Aload2 => Opcode::Aload2,
609 Self::Aload3 => Opcode::Aload3,
610 Self::Anewarray(_) => Opcode::Anewarray,
611 Self::Areturn => Opcode::Areturn,
612 Self::ArrayLength => Opcode::ArrayLength,
613 Self::Astore(_) => Opcode::Astore,
614 Self::Astore0 => Opcode::Astore0,
615 Self::Astore1 => Opcode::Astore1,
616 Self::Astore2 => Opcode::Astore2,
617 Self::Astore3 => Opcode::Astore3,
618 Self::Athrow => Opcode::Athrow,
619 Self::Baload => Opcode::Baload,
620 Self::Bastore => Opcode::Bastore,
621 Self::Bipush(_) => Opcode::Bipush,
622 Self::Breakpoint => Opcode::Breakpoint,
623 Self::Caload => Opcode::Caload,
624 Self::Castore => Opcode::Castore,
625 Self::Checkcast(_) => Opcode::Checkcast,
626 Self::D2f => Opcode::D2f,
627 Self::D2i => Opcode::D2i,
628 Self::D2l => Opcode::D2l,
629 Self::Dadd => Opcode::Dadd,
630 Self::Daload => Opcode::Daload,
631 Self::Dastore => Opcode::Dastore,
632 Self::Dcmpg => Opcode::Dcmpg,
633 Self::Dcmpl => Opcode::Dcmpl,
634 Self::Dconst0 => Opcode::Dconst0,
635 Self::Dconst1 => Opcode::Dconst1,
636 Self::Ddiv => Opcode::Ddiv,
637 Self::Dload(_) => Opcode::Dload,
638 Self::Dload0 => Opcode::Dload0,
639 Self::Dload1 => Opcode::Dload1,
640 Self::Dload2 => Opcode::Dload2,
641 Self::Dload3 => Opcode::Dload3,
642 Self::Dmul => Opcode::Dmul,
643 Self::Dneg => Opcode::Dneg,
644 Self::Drem => Opcode::Drem,
645 Self::Dreturn => Opcode::Dreturn,
646 Self::Dstore(_) => Opcode::Dstore,
647 Self::Dstore0 => Opcode::Dstore0,
648 Self::Dstore1 => Opcode::Dstore1,
649 Self::Dstore2 => Opcode::Dstore2,
650 Self::Dstore3 => Opcode::Dstore3,
651 Self::Dsub => Opcode::Dsub,
652 Self::Dup => Opcode::Dup,
653 Self::Dup2 => Opcode::Dup2,
654 Self::Dup2X1 => Opcode::Dup2X1,
655 Self::Dup2X2 => Opcode::Dup2X2,
656 Self::DupX1 => Opcode::DupX1,
657 Self::DupX2 => Opcode::DupX2,
658 Self::F2d => Opcode::F2d,
659 Self::F2i => Opcode::F2i,
660 Self::F2l => Opcode::F2l,
661 Self::Fadd => Opcode::Fadd,
662 Self::Faload => Opcode::Faload,
663 Self::Fastore => Opcode::Fastore,
664 Self::Fcmpg => Opcode::Fcmpg,
665 Self::Fcmpl => Opcode::Fcmpl,
666 Self::Fconst0 => Opcode::Fconst0,
667 Self::Fconst1 => Opcode::Fconst1,
668 Self::Fconst2 => Opcode::Fconst2,
669 Self::Fdiv => Opcode::Fdiv,
670 Self::Fload(_) => Opcode::Fload,
671 Self::Fload0 => Opcode::Fload0,
672 Self::Fload1 => Opcode::Fload1,
673 Self::Fload2 => Opcode::Fload2,
674 Self::Fload3 => Opcode::Fload3,
675 Self::Fmul => Opcode::Fmul,
676 Self::Fneg => Opcode::Fneg,
677 Self::Frem => Opcode::Frem,
678 Self::Freturn => Opcode::Freturn,
679 Self::Fstore(_) => Opcode::Fstore,
680 Self::Fstore0 => Opcode::Fstore0,
681 Self::Fstore1 => Opcode::Fstore1,
682 Self::Fstore2 => Opcode::Fstore2,
683 Self::Fstore3 => Opcode::Fstore3,
684 Self::Fsub => Opcode::Fsub,
685 Self::Getfield(_) => Opcode::Getfield,
686 Self::Getstatic(_) => Opcode::Getstatic,
687 Self::Goto(_) => Opcode::Goto,
688 Self::GotoW(_) => Opcode::GotoW,
689 Self::I2b => Opcode::I2b,
690 Self::I2c => Opcode::I2c,
691 Self::I2d => Opcode::I2d,
692 Self::I2f => Opcode::I2f,
693 Self::I2l => Opcode::I2l,
694 Self::I2s => Opcode::I2s,
695 Self::Iadd => Opcode::Iadd,
696 Self::Iaload => Opcode::Iaload,
697 Self::Iand => Opcode::Iand,
698 Self::Iastore => Opcode::Iastore,
699 Self::IconstM1 => Opcode::IconstM1,
700 Self::Iconst0 => Opcode::Iconst0,
701 Self::Iconst1 => Opcode::Iconst1,
702 Self::Iconst2 => Opcode::Iconst2,
703 Self::Iconst3 => Opcode::Iconst3,
704 Self::Iconst4 => Opcode::Iconst4,
705 Self::Iconst5 => Opcode::Iconst5,
706 Self::Idiv => Opcode::Idiv,
707 Self::IfAcmpEq(_) => Opcode::IfAcmpEq,
708 Self::IfAcmpNe(_) => Opcode::IfAcmpNe,
709 Self::IfEq(_) => Opcode::IfEq,
710 Self::IfGe(_) => Opcode::IfGe,
711 Self::IfGt(_) => Opcode::IfGt,
712 Self::IfLe(_) => Opcode::IfLe,
713 Self::IfLt(_) => Opcode::IfLt,
714 Self::IfNe(_) => Opcode::IfNe,
715 Self::Ifnonnull(_) => Opcode::Ifnonnull,
716 Self::Ifnull(_) => Opcode::Ifnull,
717 Self::IfIcmpeq(_) => Opcode::IfIcmpeq,
718 Self::IfIcmpge(_) => Opcode::IfIcmpge,
719 Self::IfIcmpgt(_) => Opcode::IfIcmpgt,
720 Self::IfIcmple(_) => Opcode::IfIcmple,
721 Self::IfIcmplt(_) => Opcode::IfIcmplt,
722 Self::IfIcmpne(_) => Opcode::IfIcmpne,
723 Self::Iinc(_, _) => Opcode::Iinc,
724 Self::Iload(_) => Opcode::Iload,
725 Self::Iload0 => Opcode::Iload0,
726 Self::Iload1 => Opcode::Iload1,
727 Self::Iload2 => Opcode::Iload2,
728 Self::Iload3 => Opcode::Iload3,
729 Self::Imul => Opcode::Imul,
730 Self::Ineg => Opcode::Ineg,
731 Self::Instanceof(_) => Opcode::Instanceof,
732 Self::InvokeDynamic(_) => Opcode::InvokeDynamic,
733 Self::InvokeInterface(_, _) => Opcode::InvokeInterface,
734 Self::InvokeSpecial(_) => Opcode::InvokeSpecial,
735 Self::InvokeStatic(_) => Opcode::InvokeStatic,
736 Self::InvokeVirtual(_) => Opcode::InvokeVirtual,
737 Self::Ior => Opcode::Ior,
738 Self::Irem => Opcode::Irem,
739 Self::Ireturn => Opcode::Ireturn,
740 Self::Ishl => Opcode::Ishl,
741 Self::Ishr => Opcode::Ishr,
742 Self::Istore(_) => Opcode::Istore,
743 Self::Istore0 => Opcode::Istore0,
744 Self::Istore1 => Opcode::Istore1,
745 Self::Istore2 => Opcode::Istore2,
746 Self::Istore3 => Opcode::Istore3,
747 Self::Isub => Opcode::Isub,
748 Self::Iushr => Opcode::Iushr,
749 Self::Ixor => Opcode::Ixor,
750 Self::Jsr(_) => Opcode::Jsr,
751 Self::JsrW(_) => Opcode::JsrW,
752 Self::L2d => Opcode::L2d,
753 Self::L2f => Opcode::L2f,
754 Self::L2i => Opcode::L2i,
755 Self::Ladd => Opcode::Ladd,
756 Self::Laload => Opcode::Laload,
757 Self::Land => Opcode::Land,
758 Self::Lastore => Opcode::Lastore,
759 Self::Lcmp => Opcode::Lcmp,
760 Self::Lconst0 => Opcode::Lconst0,
761 Self::Lconst1 => Opcode::Lconst1,
762 Self::Ldc(_) => Opcode::Ldc,
763 Self::Ldc2W(_) => Opcode::Ldc2W,
764 Self::LdcW(_) => Opcode::LdcW,
765 Self::Ldiv => Opcode::Ldiv,
766 Self::Lload(_) => Opcode::Lload,
767 Self::Lload0 => Opcode::Lload0,
768 Self::Lload1 => Opcode::Lload1,
769 Self::Lload2 => Opcode::Lload2,
770 Self::Lload3 => Opcode::Lload3,
771 Self::Lmul => Opcode::Lmul,
772 Self::Lneg => Opcode::Lneg,
773 Self::Lookupswitch(_) => Opcode::Lookupswitch,
774 Self::Lor => Opcode::Lor,
775 Self::Lrem => Opcode::Lrem,
776 Self::Lreturn => Opcode::Lreturn,
777 Self::Lshl => Opcode::Lshl,
778 Self::Lshr => Opcode::Lshr,
779 Self::Lstore(_) => Opcode::Lstore,
780 Self::Lstore0 => Opcode::Lstore0,
781 Self::Lstore1 => Opcode::Lstore1,
782 Self::Lstore2 => Opcode::Lstore2,
783 Self::Lstore3 => Opcode::Lstore3,
784 Self::Lsub => Opcode::Lsub,
785 Self::Lushr => Opcode::Lushr,
786 Self::Lxor => Opcode::Lxor,
787 Self::Monitorenter => Opcode::Monitorenter,
788 Self::Monitorexit => Opcode::Monitorexit,
789 Self::Multianewarray(_, _) => Opcode::Multianewarray,
790 Self::New(_) => Opcode::New,
791 Self::Newarray(_) => Opcode::Newarray,
792 Self::Nop => Opcode::Nop,
793 Self::Pop => Opcode::Pop,
794 Self::Pop2 => Opcode::Pop2,
795 Self::Putfield(_) => Opcode::Putfield,
796 Self::Putstatic(_) => Opcode::Putstatic,
797 Self::Ret(_) => Opcode::Ret,
798 Self::Return => Opcode::Return,
799 Self::Saload => Opcode::Saload,
800 Self::Sastore => Opcode::Sastore,
801 Self::Sipush(_) => Opcode::Sipush,
802 Self::Swap => Opcode::Swap,
803 Self::TableSwitch(_) => Opcode::TableSwitch,
804 Self::Impdep1 | Self::Impdep2 => return None,
805 };
806 Some(op)
807 }
808
809 pub fn get_name(&self) -> &'static str {
815 match self {
816 Self::Impdep1 => "impdep1",
817 Self::Impdep2 => "impdep2",
818 _ => self.opcode().unwrap().as_str(),
820 }
821 }
822}
823
824impl std::fmt::Display for Instruction {
825 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
826 f.write_str(self.get_name())
827 }
828}