rusty_dex/dex/
instructions.rs

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