1use crate::dex::opcodes::OpCode;
8use crate::dex::reader::DexReader;
9use crate::error::DexError;
10
11#[derive(Debug, Clone)]
13pub struct Instruction10t { opcode: OpCode, length: usize, bytes: [u16; 1] }
14#[derive(Debug, Clone)]
16pub struct Instruction10x { opcode: OpCode, length: usize, bytes: [u16; 1] }
17#[derive(Debug, Clone)]
19pub struct Instruction11n { opcode: OpCode, length: usize, bytes: [u16; 1] }
20#[derive(Debug, Clone)]
22pub struct Instruction11x { opcode: OpCode, length: usize, bytes: [u16; 1] }
23#[derive(Debug, Clone)]
25pub struct Instruction12x { opcode: OpCode, length: usize, bytes: [u16; 1] }
26#[derive(Debug, Clone)]
28pub struct Instruction20t { opcode: OpCode, length: usize, bytes: [u16; 2] }
29#[derive(Debug, Clone)]
31pub struct Instruction21c { opcode: OpCode, length: usize, bytes: [u16; 2] }
32#[derive(Debug, Clone)]
34pub struct Instruction21h { opcode: OpCode, length: usize, bytes: [u16; 2] }
35#[derive(Debug, Clone)]
37pub struct Instruction21s { opcode: OpCode, length: usize, bytes: [u16; 2] }
38#[derive(Debug, Clone)]
40pub struct Instruction21t { opcode: OpCode, length: usize, bytes: [u16; 2] }
41#[derive(Debug, Clone)]
43pub struct Instruction22b { opcode: OpCode, length: usize, bytes: [u16; 2] }
44#[derive(Debug, Clone)]
46pub struct Instruction22c { opcode: OpCode, length: usize, bytes: [u16; 2] }
47#[derive(Debug, Clone)]
49pub struct Instruction22s { opcode: OpCode, length: usize, bytes: [u16; 2] }
50#[derive(Debug, Clone)]
52pub struct Instruction22t { opcode: OpCode, length: usize, bytes: [u16; 2] }
53#[derive(Debug, Clone)]
55pub struct Instruction22x { opcode: OpCode, length: usize, bytes: [u16; 2] }
56#[derive(Debug, Clone)]
58pub struct Instruction23x { opcode: OpCode, length: usize, bytes: [u16; 2] }
59#[derive(Debug, Clone)]
61pub struct Instruction30t { opcode: OpCode, length: usize, bytes: [u16; 3] }
62#[derive(Debug, Clone)]
64pub struct Instruction31c { opcode: OpCode, length: usize, bytes: [u16; 3] }
65#[derive(Debug, Clone)]
67pub struct Instruction31i { opcode: OpCode, length: usize, bytes: [u16; 3] }
68#[derive(Debug, Clone)]
70pub struct Instruction31t { opcode: OpCode, length: usize, bytes: [u16; 3] }
71#[derive(Debug, Clone)]
73pub struct Instruction32x { opcode: OpCode, length: usize, bytes: [u16; 3] }
74#[derive(Debug, Clone)]
76pub struct Instruction35c { opcode: OpCode, length: usize, bytes: [u16; 3] }
77#[derive(Debug, Clone)]
79pub struct Instruction3rc { opcode: OpCode, length: usize, bytes: [u16; 3] }
80#[derive(Debug, Clone)]
82pub struct Instruction45cc { opcode: OpCode, length: usize, bytes: [u16; 4] }
83#[derive(Debug, Clone)]
85pub struct Instruction4rcc { opcode: OpCode, length: usize, bytes: [u16; 4] }
86#[derive(Debug, Clone)]
88pub struct Instruction51l { opcode: OpCode, length: usize, bytes: [u16; 5] }
89#[derive(Debug, Clone)]
91pub struct PackedSwitchPayload {
92 opcode: OpCode,
93 size: u16,
94 first_key: i32,
95 targets: Vec<i32>
96}
97#[derive(Debug, Clone)]
99pub struct SparseSwitchPayload {
100 opcode: OpCode,
101 size: u16,
102 keys: Vec<i32>,
103 targets: Vec<i32>
104}
105#[derive(Debug, Clone)]
107pub struct FillArrayDataPayload {
108 opcode: OpCode,
109 element_width: u16,
110 size: u32,
111 data: Vec<u8>
112}
113
114impl PackedSwitchPayload {
115 fn build(reader: &mut DexReader) -> Result<Self, DexError> {
117 let size = reader.read_u16()?;
118 let first_key = reader.read_i32()?;
119
120 let mut targets = Vec::with_capacity(size.into());
121 for _ in 0..size {
122 targets.push(reader.read_i32()?);
123 }
124
125 Ok(PackedSwitchPayload {
126 opcode: OpCode::PACKED_SWITCH_PAYLOAD,
127 size,
128 first_key,
129 targets
130 })
131 }
132
133 fn get_size(&self) -> usize {
134 self.size as usize
135 }
136
137 fn get_first_key(&self) -> i32 {
138 self.first_key
139 }
140
141 fn get_targets(&self) -> &[i32] {
142 &self.targets
143 }
144
145 fn length(&self) -> usize {
146 ((self.size * 2) + 4).into()
148 }
149
150 fn opcode(&self) -> OpCode {
151 OpCode::PACKED_SWITCH_PAYLOAD
152 }
153
154 fn bytes(&self) -> &[u16] {
159 &[]
160 }
161
162 fn inst_format(&self) -> &str {
163 "PackedSwitchPayload"
164 }
165}
166
167impl SparseSwitchPayload {
168 fn build(reader: &mut DexReader) -> Result<Self, DexError> {
170 let size = reader.read_u16()?;
171
172 let mut keys = Vec::with_capacity(size.into());
173 for _ in 0..size {
174 keys.push(reader.read_i32()?);
175 }
176
177 let mut targets = Vec::with_capacity(size.into());
178 for _ in 0..size {
179 targets.push(reader.read_i32()?);
180 }
181
182 Ok(SparseSwitchPayload {
183 opcode: OpCode::SPARSE_SWITCH_PAYLOAD,
184 size,
185 keys,
186 targets
187 })
188 }
189
190 fn get_size(&self) -> usize {
191 self.size as usize
192 }
193
194 fn get_keys(&self) -> &[i32] {
195 &self.keys
196 }
197
198 fn get_targets(&self) -> &[i32] {
199 &self.targets
200 }
201
202 fn length(&self) -> usize {
203 ((self.size * 4) + 2).into()
204 }
205
206 fn opcode(&self) -> OpCode {
207 OpCode::SPARSE_SWITCH_PAYLOAD
208 }
209
210 fn bytes(&self) -> &[u16] {
215 &[]
216 }
217
218 fn inst_format(&self) -> &str {
219 "SparseSwitchPayload"
220 }
221}
222
223impl FillArrayDataPayload {
224 fn build(reader: &mut DexReader) -> Result<Self, DexError> {
226 let element_width = reader.read_u16()?;
228 let size = reader.read_u32()?;
229
230 let mut data = Vec::with_capacity((size * element_width as u32) as usize);
231 for _ in 0..size {
232 for _ in 0..element_width {
233 data.push(reader.read_u8()?);
234 }
235 }
236
237 Ok(FillArrayDataPayload {
238 opcode: OpCode::FILL_ARRAY_DATA_PAYLOAD,
239 element_width,
240 size,
241 data
242 })
243 }
244
245 fn get_element_width(&self) -> u16 {
246 self.element_width
247 }
248
249 fn get_size(&self) -> u32 {
250 self.size
251 }
252
253 fn get_data(&self) -> &[u8] {
254 &self.data
255 }
256
257 fn length(&self) -> usize {
258 ((self.size * self.element_width as u32) / 2 + 4) as usize
259 }
260
261 fn opcode(&self) -> OpCode {
262 OpCode::FILL_ARRAY_DATA_PAYLOAD
263 }
264
265 fn bytes(&self) -> &[u16] {
270 &[]
271 }
272
273 fn inst_format(&self) -> &str {
274 "FillArrayDataPayload"
275 }
276}
277
278
279#[derive(Debug, Clone)]
281pub enum Instructions {
282 Instruction10t(Instruction10t),
283 Instruction10x(Instruction10x),
284 Instruction11n(Instruction11n),
285 Instruction11x(Instruction11x),
286 Instruction12x(Instruction12x),
287 Instruction20t(Instruction20t),
288 Instruction21c(Instruction21c),
289 Instruction21h(Instruction21h),
290 Instruction21s(Instruction21s),
291 Instruction21t(Instruction21t),
292 Instruction22b(Instruction22b),
293 Instruction22c(Instruction22c),
294 Instruction22s(Instruction22s),
295 Instruction22t(Instruction22t),
296 Instruction22x(Instruction22x),
297 Instruction23x(Instruction23x),
298 Instruction30t(Instruction30t),
299 Instruction31c(Instruction31c),
300 Instruction31i(Instruction31i),
301 Instruction31t(Instruction31t),
302 Instruction32x(Instruction32x),
303 Instruction35c(Instruction35c),
304 Instruction3rc(Instruction3rc),
305 Instruction45cc(Instruction45cc),
306 Instruction4rcc(Instruction4rcc),
307 Instruction51l(Instruction51l),
308 PackedSwitchPayload(PackedSwitchPayload),
309 SparseSwitchPayload(SparseSwitchPayload),
310 FillArrayDataPayload(FillArrayDataPayload),
311}
312
313
314impl Instructions {
315 pub fn length(&self) -> usize {
317 match self {
318 Instructions::Instruction10t(inst) => inst.length,
319 Instructions::Instruction10x(inst) => inst.length,
320 Instructions::Instruction11n(inst) => inst.length,
321 Instructions::Instruction11x(inst) => inst.length,
322 Instructions::Instruction12x(inst) => inst.length,
323 Instructions::Instruction20t(inst) => inst.length,
324 Instructions::Instruction21c(inst) => inst.length,
325 Instructions::Instruction21h(inst) => inst.length,
326 Instructions::Instruction21s(inst) => inst.length,
327 Instructions::Instruction21t(inst) => inst.length,
328 Instructions::Instruction22b(inst) => inst.length,
329 Instructions::Instruction22c(inst) => inst.length,
330 Instructions::Instruction22s(inst) => inst.length,
331 Instructions::Instruction22t(inst) => inst.length,
332 Instructions::Instruction22x(inst) => inst.length,
333 Instructions::Instruction23x(inst) => inst.length,
334 Instructions::Instruction30t(inst) => inst.length,
335 Instructions::Instruction31c(inst) => inst.length,
336 Instructions::Instruction31i(inst) => inst.length,
337 Instructions::Instruction31t(inst) => inst.length,
338 Instructions::Instruction32x(inst) => inst.length,
339 Instructions::Instruction35c(inst) => inst.length,
340 Instructions::Instruction3rc(inst) => inst.length,
341 Instructions::Instruction45cc(inst) => inst.length,
342 Instructions::Instruction4rcc(inst) => inst.length,
343 Instructions::Instruction51l(inst) => inst.length,
344 Instructions::PackedSwitchPayload(inst) => inst.length(),
345 Instructions::SparseSwitchPayload(inst) => inst.length(),
346 Instructions::FillArrayDataPayload(inst) => inst.length(),
347 }
348 }
349
350 pub fn opcode(&self) -> OpCode {
352 match self {
353 Instructions::Instruction10t(inst) => inst.opcode,
354 Instructions::Instruction10x(inst) => inst.opcode,
355 Instructions::Instruction11n(inst) => inst.opcode,
356 Instructions::Instruction11x(inst) => inst.opcode,
357 Instructions::Instruction12x(inst) => inst.opcode,
358 Instructions::Instruction20t(inst) => inst.opcode,
359 Instructions::Instruction21c(inst) => inst.opcode,
360 Instructions::Instruction21h(inst) => inst.opcode,
361 Instructions::Instruction21s(inst) => inst.opcode,
362 Instructions::Instruction21t(inst) => inst.opcode,
363 Instructions::Instruction22b(inst) => inst.opcode,
364 Instructions::Instruction22c(inst) => inst.opcode,
365 Instructions::Instruction22s(inst) => inst.opcode,
366 Instructions::Instruction22t(inst) => inst.opcode,
367 Instructions::Instruction22x(inst) => inst.opcode,
368 Instructions::Instruction23x(inst) => inst.opcode,
369 Instructions::Instruction30t(inst) => inst.opcode,
370 Instructions::Instruction31c(inst) => inst.opcode,
371 Instructions::Instruction31i(inst) => inst.opcode,
372 Instructions::Instruction31t(inst) => inst.opcode,
373 Instructions::Instruction32x(inst) => inst.opcode,
374 Instructions::Instruction35c(inst) => inst.opcode,
375 Instructions::Instruction3rc(inst) => inst.opcode,
376 Instructions::Instruction45cc(inst) => inst.opcode,
377 Instructions::Instruction4rcc(inst) => inst.opcode,
378 Instructions::Instruction51l(inst) => inst.opcode,
379 Instructions::PackedSwitchPayload(inst) => inst.opcode,
380 Instructions::SparseSwitchPayload(inst) => inst.opcode,
381 Instructions::FillArrayDataPayload(inst) => inst.opcode,
382 }
383 }
384
385 pub fn bytes(&self) -> &[u16] {
387 match self {
388 Instructions::Instruction10t(inst) => &inst.bytes,
389 Instructions::Instruction10x(inst) => &inst.bytes,
390 Instructions::Instruction11n(inst) => &inst.bytes,
391 Instructions::Instruction11x(inst) => &inst.bytes,
392 Instructions::Instruction12x(inst) => &inst.bytes,
393 Instructions::Instruction20t(inst) => &inst.bytes,
394 Instructions::Instruction21c(inst) => &inst.bytes,
395 Instructions::Instruction21h(inst) => &inst.bytes,
396 Instructions::Instruction21s(inst) => &inst.bytes,
397 Instructions::Instruction21t(inst) => &inst.bytes,
398 Instructions::Instruction22b(inst) => &inst.bytes,
399 Instructions::Instruction22c(inst) => &inst.bytes,
400 Instructions::Instruction22s(inst) => &inst.bytes,
401 Instructions::Instruction22t(inst) => &inst.bytes,
402 Instructions::Instruction22x(inst) => &inst.bytes,
403 Instructions::Instruction23x(inst) => &inst.bytes,
404 Instructions::Instruction30t(inst) => &inst.bytes,
405 Instructions::Instruction31c(inst) => &inst.bytes,
406 Instructions::Instruction31i(inst) => &inst.bytes,
407 Instructions::Instruction31t(inst) => &inst.bytes,
408 Instructions::Instruction32x(inst) => &inst.bytes,
409 Instructions::Instruction35c(inst) => &inst.bytes,
410 Instructions::Instruction3rc(inst) => &inst.bytes,
411 Instructions::Instruction45cc(inst) => &inst.bytes,
412 Instructions::Instruction4rcc(inst) => &inst.bytes,
413 Instructions::Instruction51l(inst) => &inst.bytes,
414 Instructions::PackedSwitchPayload(_) => &[], Instructions::SparseSwitchPayload(_) => &[], Instructions::FillArrayDataPayload(_) => &[], }
418 }
419}
420
421pub fn parse_instruction(reader: &mut DexReader, container: &mut Vec<Instructions>) -> Result<usize, DexError> {
425 let raw_opcode = reader.read_u16()?;
426
427 let opcode = match OpCode::parse((raw_opcode & 0xff).try_into().unwrap()) {
428 Some(OpCode::NOP) => match raw_opcode >> 8 {
431 0x01 => OpCode::PACKED_SWITCH_PAYLOAD,
432 0x02 => OpCode::SPARSE_SWITCH_PAYLOAD,
433 0x03 => OpCode::FILL_ARRAY_DATA_PAYLOAD,
434 _ => OpCode::NOP
435 },
436 Some(code) => code,
437 None => return Err(DexError::InvalidOpCode)
438 };
439
440 match opcode {
441 OpCode::GOTO => {
442 let mut bytes = [0u16; 1];
443 bytes[0] = raw_opcode;
444 container.push(Instructions::Instruction10t(Instruction10t {
445 opcode,
446 bytes,
447 length: 1
448 }));
449 Ok(1)
450 },
451
452 OpCode::NOP | OpCode::RETURN_VOID => {
453 let mut bytes = [0u16; 1];
454 bytes[0] = raw_opcode;
455 container.push(Instructions::Instruction10x(Instruction10x{
456 opcode,
457 bytes,
458 length: 1
459 }));
460 Ok(1)
461 },
462
463 OpCode::CONST_4 => {
464 let mut bytes = [0u16; 1];
465 bytes[0] = raw_opcode;
466 container.push(Instructions::Instruction11n(Instruction11n{
467 opcode,
468 bytes,
469 length: 1
470 }));
471 Ok(1)
472 },
473
474 OpCode::MONITOR_ENTER | OpCode::MONITOR_EXIT
475 | OpCode::MOVE_EXCEPTION | OpCode::MOVE_RESULT
476 | OpCode::MOVE_RESULT_OBJECT | OpCode::MOVE_RESULT_WIDE
477 | OpCode::RETURN | OpCode::RETURN_OBJECT
478 | OpCode::RETURN_WIDE | OpCode::THROW
479 => {
480 let mut bytes = [0u16; 1];
481 bytes[0] = raw_opcode;
482 container.push(Instructions::Instruction11x(Instruction11x{
483 opcode,
484 bytes,
485 length: 1
486 }));
487 Ok(1)
488 },
489
490 OpCode::ADD_DOUBLE_2ADDR | OpCode::ADD_FLOAT_2ADDR
491 | OpCode::ADD_INT_2ADDR | OpCode::ADD_LONG_2ADDR
492 | OpCode::AND_INT_2ADDR | OpCode::AND_LONG_2ADDR
493 | OpCode::ARRAY_LENGTH | OpCode::DIV_DOUBLE_2ADDR
494 | OpCode::DIV_FLOAT_2ADDR | OpCode::DIV_INT_2ADDR
495 | OpCode::DIV_LONG_2ADDR | OpCode::DOUBLE_TO_FLOAT
496 | OpCode::DOUBLE_TO_INT | OpCode::DOUBLE_TO_LONG
497 | OpCode::FLOAT_TO_DOUBLE | OpCode::FLOAT_TO_INT
498 | OpCode::FLOAT_TO_LONG | OpCode::INT_TO_BYTE
499 | OpCode::INT_TO_CHAR | OpCode::INT_TO_DOUBLE
500 | OpCode::INT_TO_FLOAT | OpCode::INT_TO_LONG
501 | OpCode::INT_TO_SHORT | OpCode::LONG_TO_DOUBLE
502 | OpCode::LONG_TO_FLOAT | OpCode::LONG_TO_INT
503 | OpCode::MOVE | OpCode::MOVE_OBJECT
504 | OpCode::MOVE_WIDE | OpCode::MUL_DOUBLE_2ADDR
505 | OpCode::MUL_FLOAT_2ADDR | OpCode::MUL_INT_2ADDR
506 | OpCode::MUL_LONG_2ADDR | OpCode::NEG_DOUBLE
507 | OpCode::NEG_FLOAT | OpCode::NEG_INT
508 | OpCode::NEG_LONG | OpCode::NOT_INT
509 | OpCode::NOT_LONG | OpCode::OR_INT_2ADDR
510 | OpCode::OR_LONG_2ADDR | OpCode::REM_DOUBLE_2ADDR
511 | OpCode::REM_FLOAT_2ADDR | OpCode::REM_INT_2ADDR
512 | OpCode::REM_LONG_2ADDR | OpCode::SHL_INT_2ADDR
513 | OpCode::SHL_LONG_2ADDR | OpCode::SHR_INT_2ADDR
514 | OpCode::SHR_LONG_2ADDR | OpCode::SUB_DOUBLE_2ADDR
515 | OpCode::SUB_FLOAT_2ADDR | OpCode::SUB_INT_2ADDR
516 | OpCode::SUB_LONG_2ADDR | OpCode::USHR_INT_2ADDR
517 | OpCode::USHR_LONG_2ADDR | OpCode::XOR_INT_2ADDR
518 | OpCode::XOR_LONG_2ADDR
519 => {
520 let mut bytes = [0u16; 1];
521 bytes[0] = raw_opcode;
522 container.push(Instructions::Instruction12x(Instruction12x{
523 opcode,
524 bytes,
525 length: 1
526 }));
527 Ok(1)
528 },
529
530 OpCode::GOTO_16 => {
531 let mut bytes = [0u16; 2];
532 bytes[0] = raw_opcode;
533 bytes[1] = reader.read_u16()?;
534 container.push(Instructions::Instruction20t(Instruction20t{
535 opcode,
536 bytes,
537 length: 2
538 }));
539 Ok(2)
540 },
541
542 OpCode::CHECK_CAST | OpCode::CONST_CLASS
543 | OpCode::CONST_METHOD_HANDLE | OpCode::CONST_METHOD_TYPE
544 | OpCode::CONST_STRING | OpCode::NEW_INSTANCE
545 | OpCode::SGET_BOOLEAN | OpCode::SGET_BYTE
546 | OpCode::SGET_CHAR | OpCode::SGET
547 | OpCode::SGET_OBJECT | OpCode::SGET_SHORT
548 | OpCode::SGET_WIDE | OpCode::SPUT_BOOLEAN
549 | OpCode::SPUT_BYTE | OpCode::SPUT_CHAR
550 | OpCode::SPUT | OpCode::SPUT_OBJECT
551 | OpCode::SPUT_SHORT | OpCode::SPUT_WIDE
552 => {
553 let mut bytes = [0u16; 2];
554 bytes[0] = raw_opcode;
555 bytes[1] = reader.read_u16()?;
556 container.push(Instructions::Instruction21c(Instruction21c {
557 opcode,
558 bytes,
559 length: 2
560 }));
561 Ok(2)
562 },
563
564 OpCode::CONST_HIGH16 | OpCode::CONST_WIDE_HIGH16
565 => {
566 let mut bytes = [0u16; 2];
567 bytes[0] = raw_opcode;
568 bytes[1] = reader.read_u16()?;
569 container.push(Instructions::Instruction21h(Instruction21h {
570 opcode,
571 bytes,
572 length: 2
573 }));
574 Ok(2)
575 },
576
577 OpCode::CONST_16 | OpCode::CONST_WIDE_16
578 => {
579 let mut bytes = [0u16; 2];
580 bytes[0] = raw_opcode;
581 bytes[1] = reader.read_u16()?;
582 container.push(Instructions::Instruction21s(Instruction21s {
583 opcode,
584 bytes,
585 length: 2
586 }));
587 Ok(2)
588 },
589
590 OpCode::IF_EQZ | OpCode::IF_GEZ
591 | OpCode::IF_GTZ | OpCode::IF_LEZ
592 | OpCode::IF_LTZ | OpCode::IF_NEZ
593 => {
594 let mut bytes = [0u16; 2];
595 bytes[0] = raw_opcode;
596 bytes[1] = reader.read_u16()?;
597 container.push(Instructions::Instruction21t(Instruction21t {
598 opcode,
599 bytes,
600 length: 2
601 }));
602 Ok(2)
603 },
604
605 OpCode::ADD_INT_LIT8 | OpCode::AND_INT_LIT8
606 | OpCode::DIV_INT_LIT8 | OpCode::MUL_INT_LIT8
607 | OpCode::OR_INT_LIT8 | OpCode::REM_INT_LIT8
608 | OpCode::RSUB_INT_LIT8 | OpCode::SHL_INT_LIT8
609 | OpCode::SHR_INT_LIT8 | OpCode::USHR_INT_LIT8
610 | OpCode::XOR_INT_LIT8
611 => {
612 let mut bytes = [0u16; 2];
613 bytes[0] = raw_opcode;
614 bytes[1] = reader.read_u16()?;
615 container.push(Instructions::Instruction22b(Instruction22b {
616 opcode,
617 bytes,
618 length: 2
619 }));
620 Ok(2)
621 },
622
623 OpCode::IGET_BOOLEAN | OpCode::IGET_BYTE
624 | OpCode::IGET_CHAR | OpCode::IGET
625 | OpCode::IGET_OBJECT | OpCode::IGET_SHORT
626 | OpCode::IGET_WIDE | OpCode::INSTANCE_OF
627 | OpCode::IPUT_BOOLEAN | OpCode::IPUT_BYTE
628 | OpCode::IPUT_CHAR | OpCode::IPUT
629 | OpCode::IPUT_OBJECT | OpCode::IPUT_SHORT
630 | OpCode::IPUT_WIDE | OpCode::NEW_ARRAY
631 => {
632 let mut bytes = [0u16; 2];
633 bytes[0] = raw_opcode;
634 bytes[1] = reader.read_u16()?;
635 container.push(Instructions::Instruction22c(Instruction22c {
636 opcode,
637 bytes,
638 length: 2
639 }));
640 Ok(2)
641 },
642
643 OpCode::ADD_INT_LIT16 | OpCode::AND_INT_LIT16
644 | OpCode::DIV_INT_LIT16 | OpCode::MUL_INT_LIT16
645 | OpCode::OR_INT_LIT16 | OpCode::REM_INT_LIT16
646 | OpCode::RSUB_INT | OpCode::XOR_INT_LIT16
647 => {
648 let mut bytes = [0u16; 2];
649 bytes[0] = raw_opcode;
650 bytes[1] = reader.read_u16()?;
651 container.push(Instructions::Instruction22s(Instruction22s {
652 opcode,
653 bytes,
654 length: 2
655 }));
656 Ok(2)
657 },
658
659 OpCode::IF_EQ | OpCode::IF_GE
660 | OpCode::IF_GT | OpCode::IF_LE
661 | OpCode::IF_LT | OpCode::IF_NE
662 => {
663 let mut bytes = [0u16; 2];
664 bytes[0] = raw_opcode;
665 bytes[1] = reader.read_u16()?;
666 container.push(Instructions::Instruction22t(Instruction22t {
667 opcode,
668 bytes,
669 length: 2
670 }));
671 Ok(2)
672 },
673
674 OpCode::MOVE_FROM16 | OpCode::MOVE_OBJECT_FROM16
675 | OpCode::MOVE_WIDE_FROM16
676 => {
677 let mut bytes = [0u16; 2];
678 bytes[0] = raw_opcode;
679 bytes[1] = reader.read_u16()?;
680 container.push(Instructions::Instruction22x(Instruction22x {
681 opcode,
682 bytes,
683 length: 2
684 }));
685 Ok(2)
686 },
687
688 OpCode::ADD_DOUBLE | OpCode::ADD_FLOAT
689 | OpCode::ADD_INT | OpCode::ADD_LONG
690 | OpCode::AGET_BOOLEAN | OpCode::AGET_BYTE
691 | OpCode::AGET_CHAR | OpCode::AGET
692 | OpCode::AGET_OBJECT | OpCode::AGET_SHORT
693 | OpCode::AGET_WIDE | OpCode::AND_INT
694 | OpCode::AND_LONG | OpCode::APUT_BOOLEAN
695 | OpCode::APUT_BYTE | OpCode::APUT_CHAR
696 | OpCode::APUT | OpCode::APUT_OBJECT
697 | OpCode::APUT_SHORT | OpCode::APUT_WIDE
698 | OpCode::CMPG_DOUBLE | OpCode::CMPG_FLOAT
699 | OpCode::CMPL_DOUBLE | OpCode::CMPL_FLOAT
700 | OpCode::CMP_LONG | OpCode::DIV_DOUBLE
701 | OpCode::DIV_FLOAT | OpCode::DIV_INT
702 | OpCode::DIV_LONG | OpCode::MUL_DOUBLE
703 | OpCode::MUL_FLOAT | OpCode::MUL_INT
704 | OpCode::MUL_LONG | OpCode::OR_INT
705 | OpCode::OR_LONG | OpCode::REM_DOUBLE
706 | OpCode::REM_FLOAT | OpCode::REM_INT
707 | OpCode::REM_LONG | OpCode::SHL_INT
708 | OpCode::SHL_LONG | OpCode::SHR_INT
709 | OpCode::SHR_LONG | OpCode::SUB_DOUBLE
710 | OpCode::SUB_FLOAT | OpCode::SUB_INT
711 | OpCode::SUB_LONG | OpCode::USHR_INT
712 | OpCode::USHR_LONG | OpCode::XOR_INT
713 | OpCode::XOR_LONG
714 => {
715 let mut bytes = [0u16; 2];
716 bytes[0] = raw_opcode;
717 bytes[1] = reader.read_u16()?;
718 container.push(Instructions::Instruction23x(Instruction23x {
719 opcode,
720 bytes,
721 length: 2
722 }));
723 Ok(2)
724 },
725
726 OpCode::GOTO_32 => {
727 let mut bytes = [0u16; 3];
728 bytes[0] = raw_opcode;
729 bytes[1] = reader.read_u16()?;
730 bytes[2] = reader.read_u16()?;
731 container.push(Instructions::Instruction30t(Instruction30t {
732 opcode,
733 bytes,
734 length: 3
735 }));
736 Ok(3)
737 },
738
739 OpCode::CONST_STRING_JUMBO => {
740 let mut bytes = [0u16; 3];
741 bytes[0] = raw_opcode;
742 bytes[1] = reader.read_u16()?;
743 bytes[2] = reader.read_u16()?;
744 container.push(Instructions::Instruction31c(Instruction31c {
745 opcode,
746 bytes,
747 length: 3
748 }));
749 Ok(3)
750 },
751
752 OpCode::CONST | OpCode::CONST_WIDE_32
753 => {
754 let mut bytes = [0u16; 3];
755 bytes[0] = raw_opcode;
756 bytes[1] = reader.read_u16()?;
757 bytes[2] = reader.read_u16()?;
758 container.push(Instructions::Instruction31i(Instruction31i {
759 opcode,
760 bytes,
761 length: 3
762 }));
763 Ok(3)
764 },
765
766 OpCode::FILL_ARRAY_DATA | OpCode::PACKED_SWITCH
767 | OpCode::SPARSE_SWITCH => {
768 let mut bytes = [0u16; 3];
769 bytes[0] = raw_opcode;
770 bytes[1] = reader.read_u16()?;
771 bytes[2] = reader.read_u16()?;
772 container.push(Instructions::Instruction31t(Instruction31t {
773 opcode,
774 bytes,
775 length: 3
776 }));
777 Ok(3)
778 },
779
780 OpCode::MOVE_16 | OpCode::MOVE_OBJECT_16
781 | OpCode::MOVE_WIDE_16 => {
782 let mut bytes = [0u16; 3];
783 bytes[0] = raw_opcode;
784 bytes[1] = reader.read_u16()?;
785 bytes[2] = reader.read_u16()?;
786 container.push(Instructions::Instruction32x(Instruction32x {
787 opcode,
788 bytes,
789 length: 3
790 }));
791 Ok(3)
792 },
793
794 OpCode::FILLED_NEW_ARRAY | OpCode::INVOKE_CUSTOM
795 | OpCode::INVOKE_DIRECT | OpCode::INVOKE_INTERFACE
796 | OpCode::INVOKE_STATIC | OpCode::INVOKE_SUPER
797 | OpCode::INVOKE_VIRTUAL
798 => {
799 let mut bytes = [0u16; 3];
800 bytes[0] = raw_opcode;
801 bytes[1] = reader.read_u16()?;
802 bytes[2] = reader.read_u16()?;
803 container.push(Instructions::Instruction35c(Instruction35c {
804 opcode,
805 bytes,
806 length: 3
807 }));
808 Ok(3)
809 },
810
811 OpCode::FILLED_NEW_ARRAY_RANGE | OpCode::INVOKE_CUSTOM_RANGE
812 | OpCode::INVOKE_DIRECT_RANGE | OpCode::INVOKE_INTERFACE_RANGE
813 | OpCode::INVOKE_STATIC_RANGE | OpCode::INVOKE_SUPER_RANGE
814 | OpCode::INVOKE_VIRTUAL_RANGE
815 => {
816 let mut bytes = [0u16; 3];
817 bytes[0] = raw_opcode;
818 bytes[1] = reader.read_u16()?;
819 bytes[2] = reader.read_u16()?;
820 container.push(Instructions::Instruction3rc(Instruction3rc {
821 opcode,
822 bytes,
823 length: 3
824 }));
825 Ok(3)
826 },
827
828 OpCode::INVOKE_POLYMORPHIC => {
829 let mut bytes = [0u16; 4];
830 bytes[0] = raw_opcode;
831 bytes[1] = reader.read_u16()?;
832 bytes[2] = reader.read_u16()?;
833 bytes[3] = reader.read_u16()?;
834 container.push(Instructions::Instruction45cc(Instruction45cc {
835 opcode,
836 bytes,
837 length: 4
838 }));
839 Ok(4)
840 },
841
842 OpCode::INVOKE_POLYMORPHIC_RANGE => {
843 let mut bytes = [0u16; 4];
844 bytes[0] = raw_opcode;
845 bytes[1] = reader.read_u16()?;
846 bytes[2] = reader.read_u16()?;
847 bytes[3] = reader.read_u16()?;
848 container.push(Instructions::Instruction4rcc(Instruction4rcc {
849 opcode,
850 bytes,
851 length: 4
852 }));
853 Ok(4)
854 },
855
856 OpCode::CONST_WIDE => {
857 let mut bytes = [0u16; 5];
858 bytes[0] = raw_opcode;
859 bytes[1] = reader.read_u16()?;
860 bytes[2] = reader.read_u16()?;
861 bytes[3] = reader.read_u16()?;
862 bytes[4] = reader.read_u16()?;
863 container.push(Instructions::Instruction51l(Instruction51l {
864 opcode,
865 bytes,
866 length: 5
867 }));
868 Ok(5)
869 },
870
871 OpCode::PACKED_SWITCH_PAYLOAD => {
872 let inst = PackedSwitchPayload::build(reader)?;
873 let len = inst.length();
874 container.push(Instructions::PackedSwitchPayload(inst));
875 reader.align_cursor()?;
876 Ok(len)
877 },
878
879 OpCode::SPARSE_SWITCH_PAYLOAD => {
880 let inst = SparseSwitchPayload::build(reader)?;
881 let len = inst.length();
882 container.push(Instructions::SparseSwitchPayload(inst));
883 reader.align_cursor()?;
884 Ok(len)
885 },
886
887 OpCode::FILL_ARRAY_DATA_PAYLOAD => {
888 let inst = FillArrayDataPayload::build(reader)?;
889 let len = inst.length();
890 container.push(Instructions::FillArrayDataPayload(inst));
891 reader.align_cursor()?;
892 Ok(len)
893 }
894 }
895}