001    package edu.rice.cs.cunit.classFile.code;
002    
003    import edu.rice.cs.cunit.util.Types;
004    import edu.rice.cs.cunit.classFile.code.instructions.AInstruction;
005    import edu.rice.cs.cunit.classFile.code.instructions.GenericInstruction;
006    import edu.rice.cs.cunit.classFile.code.instructions.WideInstruction;
007    
008    /**
009     * Java opcode class.
010     *
011     * @author Mathias Ricken
012     */
013    public abstract class Opcode {
014        public final static byte NOP = (byte)0x00;
015        public final static byte ACONST_NULL = (byte)0x01;
016        public final static byte ICONST_M1 = (byte)0x02;
017        public final static byte ICONST_0 = (byte)0x03;
018        public final static byte ICONST_1 = (byte)0x04;
019        public final static byte ICONST_2 = (byte)0x05;
020        public final static byte ICONST_3 = (byte)0x06;
021        public final static byte ICONST_4 = (byte)0x07;
022        public final static byte ICONST_5 = (byte)0x08;
023        public final static byte LCONST_0 = (byte)0x09;
024        public final static byte LCONST_1 = (byte)0x0A;
025        public final static byte FCONST_0 = (byte)0x0B;
026        public final static byte FCONST_1 = (byte)0x0C;
027        public final static byte FCONST_2 = (byte)0x0D;
028        public final static byte DCONST_0 = (byte)0x0E;
029        public final static byte DCONST_1 = (byte)0x0F;
030        public final static byte BIPUSH = (byte)0x10;
031        public final static byte SIPUSH = (byte)0x11;
032        public final static byte LDC = (byte)0x12;
033        public final static byte LDC_W = (byte)0x13;
034        public final static byte LDC2_W = (byte)0x14;
035        public final static byte ILOAD = (byte)0x15;
036        public final static byte LLOAD = (byte)0x16;
037        public final static byte FLOAD = (byte)0x17;
038        public final static byte DLOAD = (byte)0x18;
039        public final static byte ALOAD = (byte)0x19;
040        public final static byte ILOAD_0 = (byte)0x1A;
041        public final static byte ILOAD_1 = (byte)0x1B;
042        public final static byte ILOAD_2 = (byte)0x1C;
043        public final static byte ILOAD_3 = (byte)0x1D;
044        public final static byte LLOAD_0 = (byte)0x1E;
045        public final static byte LLOAD_1 = (byte)0x1F;
046        public final static byte LLOAD_2 = (byte)0x20;
047        public final static byte LLOAD_3 = (byte)0x21;
048        public final static byte FLOAD_0 = (byte)0x22;
049        public final static byte FLOAD_1 = (byte)0x23;
050        public final static byte FLOAD_2 = (byte)0x24;
051        public final static byte FLOAD_3 = (byte)0x25;
052        public final static byte DLOAD_0 = (byte)0x26;
053        public final static byte DLOAD_1 = (byte)0x27;
054        public final static byte DLOAD_2 = (byte)0x28;
055        public final static byte DLOAD_3 = (byte)0x29;
056        public final static byte ALOAD_0 = (byte)0x2A;
057        public final static byte ALOAD_1 = (byte)0x2B;
058        public final static byte ALOAD_2 = (byte)0x2C;
059        public final static byte ALOAD_3 = (byte)0x2D;
060        public final static byte IALOAD = (byte)0x2E;
061        public final static byte LALOAD = (byte)0x2F;
062        public final static byte FALOAD = (byte)0x30;
063        public final static byte DALOAD = (byte)0x31;
064        public final static byte AALOAD = (byte)0x32;
065        public final static byte BALOAD = (byte)0x33;
066        public final static byte CALOAD = (byte)0x34;
067        public final static byte SALOAD = (byte)0x35;
068        public final static byte ISTORE = (byte)0x36;
069        public final static byte LSTORE = (byte)0x37;
070        public final static byte FSTORE = (byte)0x38;
071        public final static byte DSTORE = (byte)0x39;
072        public final static byte ASTORE = (byte)0x3A;
073        public final static byte ISTORE_0 = (byte)0x3B;
074        public final static byte ISTORE_1 = (byte)0x3C;
075        public final static byte ISTORE_2 = (byte)0x3D;
076        public final static byte ISTORE_3 = (byte)0x3E;
077        public final static byte LSTORE_0 = (byte)0x3F;
078        public final static byte LSTORE_1 = (byte)0x40;
079        public final static byte LSTORE_2 = (byte)0x41;
080        public final static byte LSTORE_3 = (byte)0x42;
081        public final static byte FSTORE_0 = (byte)0x43;
082        public final static byte FSTORE_1 = (byte)0x44;
083        public final static byte FSTORE_2 = (byte)0x45;
084        public final static byte FSTORE_3 = (byte)0x46;
085        public final static byte DSTORE_0 = (byte)0x47;
086        public final static byte DSTORE_1 = (byte)0x48;
087        public final static byte DSTORE_2 = (byte)0x49;
088        public final static byte DSTORE_3 = (byte)0x4A;
089        public final static byte ASTORE_0 = (byte)0x4B;
090        public final static byte ASTORE_1 = (byte)0x4C;
091        public final static byte ASTORE_2 = (byte)0x4D;
092        public final static byte ASTORE_3 = (byte)0x4E;
093        public final static byte IASTORE = (byte)0x4F;
094        public final static byte LASTORE = (byte)0x50;
095        public final static byte FASTORE = (byte)0x51;
096        public final static byte DASTORE = (byte)0x52;
097        public final static byte AASTORE = (byte)0x53;
098        public final static byte BASTORE = (byte)0x54;
099        public final static byte CASTORE = (byte)0x55;
100        public final static byte SASTORE = (byte)0x56;
101        public final static byte POP = (byte)0x57;
102        public final static byte POP2 = (byte)0x58;
103        public final static byte DUP = (byte)0x59;
104        public final static byte DUP_X1 = (byte)0x5A;
105        public final static byte DUP_X2 = (byte)0x5B;
106        public final static byte DUP2 = (byte)0x5C;
107        public final static byte DUP2_X1 = (byte)0x5D;
108        public final static byte DUP2_X2 = (byte)0x5E;
109        public final static byte SWAP = (byte)0x5F;
110        public final static byte IADD = (byte)0x60;
111        public final static byte LADD = (byte)0x61;
112        public final static byte FADD = (byte)0x62;
113        public final static byte DADD = (byte)0x63;
114        public final static byte ISUB = (byte)0x64;
115        public final static byte LSUB = (byte)0x65;
116        public final static byte FSUB = (byte)0x66;
117        public final static byte DSUB = (byte)0x67;
118        public final static byte IMUL = (byte)0x68;
119        public final static byte LMUL = (byte)0x69;
120        public final static byte FMUL = (byte)0x6A;
121        public final static byte DMUL = (byte)0x6B;
122        public final static byte IDIV = (byte)0x6C;
123        public final static byte LDIV = (byte)0x6D;
124        public final static byte FDIV = (byte)0x6E;
125        public final static byte DDIV = (byte)0x6F;
126        public final static byte IREM = (byte)0x70;
127        public final static byte LREM = (byte)0x71;
128        public final static byte FREM = (byte)0x72;
129        public final static byte DREM = (byte)0x73;
130        public final static byte INEG = (byte)0x74;
131        public final static byte LNEG = (byte)0x75;
132        public final static byte FNEG = (byte)0x76;
133        public final static byte DNEG = (byte)0x77;
134        public final static byte ISHL = (byte)0x78;
135        public final static byte LSHL = (byte)0x79;
136        public final static byte ISHR = (byte)0x7A;
137        public final static byte LSHR = (byte)0x7B;
138        public final static byte IUSHR = (byte)0x7C;
139        public final static byte LUSHR = (byte)0x7D;
140        public final static byte IAND = (byte)0x7E;
141        public final static byte LAND = (byte)0x7F;
142        public final static byte IOR = (byte)0x80;
143        public final static byte LOR = (byte)0x81;
144        public final static byte IXOR = (byte)0x82;
145        public final static byte LXOR = (byte)0x83;
146        public final static byte IINC = (byte)0x84;
147        public final static byte I2L = (byte)0x85;
148        public final static byte I2F = (byte)0x86;
149        public final static byte I2D = (byte)0x87;
150        public final static byte L2I = (byte)0x88;
151        public final static byte L2F = (byte)0x89;
152        public final static byte L2D = (byte)0x8A;
153        public final static byte F2I = (byte)0x8B;
154        public final static byte F2L = (byte)0x8C;
155        public final static byte F2D = (byte)0x8D;
156        public final static byte D2I = (byte)0x8E;
157        public final static byte D2L = (byte)0x8F;
158        public final static byte D2F = (byte)0x90;
159        public final static byte I2B = (byte)0x91;
160        public final static byte I2C = (byte)0x92;
161        public final static byte I2S = (byte)0x93;
162        public final static byte LCMP = (byte)0x94;
163        public final static byte FCMPL = (byte)0x95;
164        public final static byte FCMPG = (byte)0x96;
165        public final static byte DCMPL = (byte)0x97;
166        public final static byte DCMPG = (byte)0x98;
167        public final static byte IFEQ = (byte)0x99;
168        public final static byte IFNE = (byte)0x9A;
169        public final static byte IFLT = (byte)0x9B;
170        public final static byte IFGE = (byte)0x9C;
171        public final static byte IFGT = (byte)0x9D;
172        public final static byte IFLE = (byte)0x9E;
173        public final static byte IF_ICMPEQ = (byte)0x9F;
174        public final static byte IF_ICMPNE = (byte)0xA0;
175        public final static byte IF_ICMPLT = (byte)0xA1;
176        public final static byte IF_ICMPGE = (byte)0xA2;
177        public final static byte IF_ICMPGT = (byte)0xA3;
178        public final static byte IF_ICMPLE = (byte)0xA4;
179        public final static byte IF_ACMPEQ = (byte)0xA5;
180        public final static byte IF_ACMPNE = (byte)0xA6;
181        public final static byte GOTO = (byte)0xA7;
182        public final static byte JSR = (byte)0xA8;
183        public final static byte RET = (byte)0xA9;
184        public final static byte TABLESWITCH = (byte)0xAA;
185        public final static byte LOOKUPSWITCH = (byte)0xAB;
186        public final static byte IRETURN = (byte)0xAC;
187        public final static byte LRETURN = (byte)0xAD;
188        public final static byte FRETURN = (byte)0xAE;
189        public final static byte DRETURN = (byte)0xAF;
190        public final static byte ARETURN = (byte)0xB0;
191        public final static byte RETURN = (byte)0xB1;
192        public final static byte GETSTATIC = (byte)0xB2;
193        public final static byte PUTSTATIC = (byte)0xB3;
194        public final static byte GETFIELD = (byte)0xB4;
195        public final static byte PUTFIELD = (byte)0xB5;
196        public final static byte INVOKEVIRTUAL = (byte)0xB6;
197        public final static byte INVOKESPECIAL = (byte)0xB7;
198        public final static byte INVOKESTATIC = (byte)0xB8;
199        public final static byte INVOKEINTERFACE = (byte)0xB9;
200        public final static byte XXXUNUSEDXXX = (byte)0xBA;
201        public final static byte NEW = (byte)0xBB;
202        public final static byte NEWARRAY = (byte)0xBC;
203        public final static byte ANEWARRAY = (byte)0xBD;
204        public final static byte ARRAYLENGTH = (byte)0xBE;
205        public final static byte ATHROW = (byte)0xBF;
206        public final static byte CHECKCAST = (byte)0xC0;
207        public final static byte INSTANCEOF = (byte)0xC1;
208        public final static byte MONITORENTER = (byte)0xC2;
209        public final static byte MONITOREXIT = (byte)0xC3;
210        public final static byte WIDE = (byte)0xC4;
211        public final static byte MULTIANEWARRAY = (byte)0xC5;
212        public final static byte IFNULL = (byte)0xC6;
213        public final static byte IFNONNULL = (byte)0xC7;
214        public final static byte GOTO_W = (byte)0xC8;
215        public final static byte JSR_W = (byte)0xC9;
216        public final static byte BREAKPOINT = (byte)0xCA;
217        public final static byte LDC_QUICK = (byte)0xCB;
218        public final static byte LDC_W_QUICK = (byte)0xCC;
219        public final static byte LDC2_W_QUICK = (byte)0xCD;
220        public final static byte GETFIELD_QUICK = (byte)0xCE;
221        public final static byte PUTFIELD_QUICK = (byte)0xCF;
222        public final static byte GETFIELD2_QUICK = (byte)0xD0;
223        public final static byte PUTFIELD2_QUICK = (byte)0xD1;
224        public final static byte GETSTATIC_QUICK = (byte)0xD2;
225        public final static byte PUTSTATIC_QUICK = (byte)0xD3;
226        public final static byte GETSTATIC2_QUICK = (byte)0xD4;
227        public final static byte PUTSTATIC2_QUICK = (byte)0xD5;
228        public final static byte INVOKEVIRTUAL_QUICK = (byte)0xD6;
229        public final static byte INVOKENONVIRTUAL_QUICK = (byte)0xD7;
230        public final static byte INVOKESUPER_QUICK = (byte)0xD8;
231        public final static byte INVOKESTATIC_QUICK = (byte)0xD9;
232        public final static byte INVOKEINTERFACE_QUICK = (byte)0xDA;
233        public final static byte INVOKEVIRTUALOBJECT_QUICK = (byte)0xDB;
234        public final static byte UNKNOWN_DC = (byte)0xDC;
235        public final static byte NEW_QUICK = (byte)0xDD;
236        public final static byte ANEWARRAY_QUICK = (byte)0xDE;
237        public final static byte MULTIANEWARRAY_QUICK = (byte)0xDF;
238        public final static byte CHECKCAST_QUICK = (byte)0xE0;
239        public final static byte INSTANCEOF_QUICK = (byte)0xE1;
240        public final static byte INVOKEVIRTUAL_QUICK_W = (byte)0xE2;
241        public final static byte GETFIELD_QUICK_W = (byte)0xE3;
242        public final static byte PUTFIELD_QUICK_W = (byte)0xE4;
243        public final static byte UNKNOWN_E5 = (byte)0xE5;
244        public final static byte UNKNOWN_E6 = (byte)0xE6;
245        public final static byte UNKNOWN_E7 = (byte)0xE7;
246        public final static byte UNKNOWN_E8 = (byte)0xE8;
247        public final static byte UNKNOWN_E9 = (byte)0xE9;
248        public final static byte UNKNOWN_EA = (byte)0xEA;
249        public final static byte UNKNOWN_EB = (byte)0xEB;
250        public final static byte UNKNOWN_EC = (byte)0xEC;
251        public final static byte UNKNOWN_ED = (byte)0xED;
252        public final static byte UNKNOWN_EE = (byte)0xEE;
253        public final static byte UNKNOWN_EF = (byte)0xEF;
254        public final static byte UNKNOWN_F0 = (byte)0xF0;
255        public final static byte UNKNOWN_F1 = (byte)0xF1;
256        public final static byte UNKNOWN_F2 = (byte)0xF2;
257        public final static byte UNKNOWN_F3 = (byte)0xF3;
258        public final static byte UNKNOWN_F4 = (byte)0xF4;
259        public final static byte UNKNOWN_F5 = (byte)0xF5;
260        public final static byte UNKNOWN_F6 = (byte)0xF6;
261        public final static byte UNKNOWN_F7 = (byte)0xF7;
262        public final static byte UNKNOWN_F8 = (byte)0xF8;
263        public final static byte UNKNOWN_F9 = (byte)0xF9;
264        public final static byte UNKNOWN_FA = (byte)0xFA;
265        public final static byte UNKNOWN_FB = (byte)0xFB;
266        public final static byte UNKNOWN_FC = (byte)0xFC;
267        public final static byte UNKNOWN_FD = (byte)0xFD;
268        public final static byte IMPDEP1 = (byte)0xFE;
269        public final static byte IMPDEP2 = (byte)0xFF;
270    
271        /**
272         * Return a human-readable version of the code.
273         *
274         * @param opcode code
275         *
276         * @return mnemonic
277         */
278        public static final String getOpcodeName(byte opcode) {
279            return NAMES[((int)opcode) & 0xFF];
280        }
281    
282        /**
283         * Table of mnemonics.
284         */
285        private final static String[] NAMES = new String[]{
286            /* 0x00 */ "nop",
287            /* 0x01 */ "aconst_null",
288            /* 0x02 */ "iconst_m1",
289            /* 0x03 */ "iconst_0",
290            /* 0x04 */ "iconst_1",
291            /* 0x05 */ "iconst_2",
292            /* 0x06 */ "iconst_3",
293            /* 0x07 */ "iconst_4",
294            /* 0x08 */ "iconst_5",
295            /* 0x09 */ "lconst_0",
296            /* 0x0A */ "lconst_1",
297            /* 0x0B */ "fconst_0",
298            /* 0x0C */ "fconst_1",
299            /* 0x0D */ "fconst_2",
300            /* 0x0E */ "dconst_0",
301            /* 0x0F */ "dconst_1",
302            /* 0x10 */ "bipush",
303            /* 0x11 */ "sipush",
304            /* 0x12 */ "ldc",
305            /* 0x13 */ "ldc_w",
306            /* 0x14 */ "ldc2_w",
307            /* 0x15 */ "iload",
308            /* 0x16 */ "lload",
309            /* 0x17 */ "fload",
310            /* 0x18 */ "dload",
311            /* 0x19 */ "aload",
312            /* 0x1A */ "iload_0",
313            /* 0x1B */ "iload_1",
314            /* 0x1C */ "iload_2",
315            /* 0x1D */ "iload_3",
316            /* 0x1E */ "lload_0",
317            /* 0x1F */ "lload_1",
318            /* 0x20 */ "lload_2",
319            /* 0x21 */ "lload_3",
320            /* 0x22 */ "fload_0",
321            /* 0x23 */ "fload_1",
322            /* 0x24 */ "fload_2",
323            /* 0x25 */ "fload_3",
324            /* 0x26 */ "dload_0",
325            /* 0x27 */ "dload_1",
326            /* 0x28 */ "dload_2",
327            /* 0x29 */ "dload_3",
328            /* 0x2A */ "aload_0",
329            /* 0x2B */ "aload_1",
330            /* 0x2C */ "aload_2",
331            /* 0x2D */ "aload_3",
332            /* 0x2E */ "iaload",
333            /* 0x2F */ "laload",
334            /* 0x30 */ "faload",
335            /* 0x31 */ "daload",
336            /* 0x32 */ "aaload",
337            /* 0x33 */ "baload",
338            /* 0x34 */ "caload",
339            /* 0x35 */ "saload",
340            /* 0x36 */ "istore",
341            /* 0x37 */ "lstore",
342            /* 0x38 */ "fstore",
343            /* 0x39 */ "dstore",
344            /* 0x3A */ "astore",
345            /* 0x3B */ "istore_0",
346            /* 0x3C */ "istore_1",
347            /* 0x3D */ "istore_2",
348            /* 0x3E */ "istore_3",
349            /* 0x3F */ "lstore_0",
350            /* 0x40 */ "lstore_1",
351            /* 0x41 */ "lstore_2",
352            /* 0x42 */ "lstore_3",
353            /* 0x43 */ "fstore_0",
354            /* 0x44 */ "fstore_1",
355            /* 0x45 */ "fstore_2",
356            /* 0x46 */ "fstore_3",
357            /* 0x47 */ "dstore_0",
358            /* 0x48 */ "dstore_1",
359            /* 0x49 */ "dstore_2",
360            /* 0x4A */ "dstore_3",
361            /* 0x4B */ "astore_0",
362            /* 0x4C */ "astore_1",
363            /* 0x4D */ "astore_2",
364            /* 0x4E */ "astore_3",
365            /* 0x4F */ "iastore",
366            /* 0x50 */ "lastore",
367            /* 0x51 */ "fastore",
368            /* 0x52 */ "dastore",
369            /* 0x53 */ "aastore",
370            /* 0x54 */ "bastore",
371            /* 0x55 */ "castore",
372            /* 0x56 */ "sastore",
373            /* 0x57 */ "pop",
374            /* 0x58 */ "pop2",
375            /* 0x59 */ "dup",
376            /* 0x5A */ "dup_x1",
377            /* 0x5B */ "dup_x2",
378            /* 0x5C */ "dup2",
379            /* 0x5D */ "dup2_x1",
380            /* 0x5E */ "dup2_x2",
381            /* 0x5F */ "swap",
382            /* 0x60 */ "iadd",
383            /* 0x61 */ "ladd",
384            /* 0x62 */ "fadd",
385            /* 0x63 */ "dadd",
386            /* 0x64 */ "isub",
387            /* 0x65 */ "lsub",
388            /* 0x66 */ "fsub",
389            /* 0x67 */ "dsub",
390            /* 0x68 */ "imul",
391            /* 0x69 */ "lmul",
392            /* 0x6A */ "fmul",
393            /* 0x6B */ "dmul",
394            /* 0x6C */ "idiv",
395            /* 0x6D */ "ldiv",
396            /* 0x6E */ "fdiv",
397            /* 0x6F */ "ddiv",
398            /* 0x70 */ "irem",
399            /* 0x71 */ "lrem",
400            /* 0x72 */ "frem",
401            /* 0x73 */ "drem",
402            /* 0x74 */ "ineg",
403            /* 0x75 */ "lneg",
404            /* 0x76 */ "fneg",
405            /* 0x77 */ "dneg",
406            /* 0x78 */ "ishl",
407            /* 0x79 */ "lshl",
408            /* 0x7A */ "ishr",
409            /* 0x7B */ "lshr",
410            /* 0x7C */ "iushr",
411            /* 0x7D */ "lushr",
412            /* 0x7E */ "iand",
413            /* 0x7F */ "land",
414            /* 0x80 */ "ior",
415            /* 0x81 */ "lor",
416            /* 0x82 */ "ixor",
417            /* 0x83 */ "lxor",
418            /* 0x84 */ "iinc",
419            /* 0x85 */ "i2l",
420            /* 0x86 */ "i2f",
421            /* 0x87 */ "i2d",
422            /* 0x88 */ "l2i",
423            /* 0x89 */ "l2f",
424            /* 0x8A */ "l2d",
425            /* 0x8B */ "f2i",
426            /* 0x8C */ "f2l",
427            /* 0x8D */ "f2d",
428            /* 0x8E */ "d2i",
429            /* 0x8F */ "d2l",
430            /* 0x90 */ "d2f",
431            /* 0x91 */ "i2b",
432            /* 0x92 */ "i2c",
433            /* 0x93 */ "i2s",
434            /* 0x94 */ "lcmp",
435            /* 0x95 */ "fcmpl",
436            /* 0x96 */ "fcmpg",
437            /* 0x97 */ "dcmpl",
438            /* 0x98 */ "dcmpg",
439            /* 0x99 */ "ifeq",
440            /* 0x9A */ "ifne",
441            /* 0x9B */ "iflt",
442            /* 0x9C */ "ifge",
443            /* 0x9D */ "ifgt",
444            /* 0x9E */ "ifle",
445            /* 0x9F */ "if_icmpeq",
446            /* 0xA0 */ "if_icmpne",
447            /* 0xA1 */ "if_icmplt",
448            /* 0xA2 */ "if_icmpge",
449            /* 0xA3 */ "if_icmpgt",
450            /* 0xA4 */ "if_icmple",
451            /* 0xA5 */ "if_acmpeq",
452            /* 0xA6 */ "if_acmpne",
453            /* 0xA7 */ "goto",
454            /* 0xA8 */ "jsr",
455            /* 0xA9 */ "ret",
456            /* 0xAA */ "tableswitch",
457            /* 0xAB */ "lookupswitch",
458            /* 0xAC */ "ireturn",
459            /* 0xAD */ "lreturn",
460            /* 0xAE */ "freturn",
461            /* 0xAF */ "dreturn",
462            /* 0xB0 */ "areturn",
463            /* 0xB1 */ "return",
464            /* 0xB2 */ "getstatic",
465            /* 0xB3 */ "putstatic",
466            /* 0xB4 */ "getfield",
467            /* 0xB5 */ "putfield",
468            /* 0xB6 */ "invokevirtual",
469            /* 0xB7 */ "invokespecial",
470            /* 0xB8 */ "invokestatic",
471            /* 0xB9 */ "invokeinterface",
472            /* 0xBA */ "xxxunusedxxx",
473            /* 0xBB */ "new",
474            /* 0xBC */ "newarray",
475            /* 0xBD */ "anewarray",
476            /* 0xBE */ "arraylength",
477            /* 0xBF */ "athrow",
478            /* 0xC0 */ "checkcast",
479            /* 0xC1 */ "instanceof",
480            /* 0xC2 */ "monitorenter",
481            /* 0xC3 */ "monitorexit",
482            /* 0xC4 */ "wide",
483            /* 0xC5 */ "multianewarray",
484            /* 0xC6 */ "ifnull",
485            /* 0xC7 */ "ifnonnull",
486            /* 0xC8 */ "goto_w",
487            /* 0xC9 */ "jsr_w",
488            /* 0xCA */ "breakpoint",
489            /* 0xCB */ "ldc_quick",
490            /* 0xCC */ "ldc_w_quick",
491            /* 0xCD */ "ldc2_w_quick",
492            /* 0xCE */ "getfield_quick",
493            /* 0xCF */ "putfield_quick",
494            /* 0xD0 */ "getfield2_quick",
495            /* 0xD1 */ "putfield2_quick",
496            /* 0xD2 */ "getstatic_quick",
497            /* 0xD3 */ "putstatic_quick",
498            /* 0xD4 */ "getstatic2_quick",
499            /* 0xD5 */ "putstatic2_quick",
500            /* 0xD6 */ "invokevirtual_quick",
501            /* 0xD7 */ "invokenonvirtual_quick",
502            /* 0xD8 */ "invokesuper_quick",
503            /* 0xD9 */ "invokestatic_quick",
504            /* 0xDA */ "invokeinterface_quick",
505            /* 0xDB */ "invokevirtualobject_quick",
506            /* 0xDC */ "unknown_dc",
507            /* 0xDD */ "new_quick",
508            /* 0xDE */ "anewarray_quick",
509            /* 0xDF */ "multianewarray_quick",
510            /* 0xE0 */ "checkcast_quick",
511            /* 0xE1 */ "instanceof_quick",
512            /* 0xE2 */ "invokevirtual_quick_w",
513            /* 0xE3 */ "getfield_quick_w",
514            /* 0xE4 */ "putfield_quick_w",
515            /* 0xE5 */ "unknown_e5",
516            /* 0xE6 */ "unknown_e6",
517            /* 0xE7 */ "unknown_e7",
518            /* 0xE8 */ "unknown_e8",
519            /* 0xE9 */ "unknown_e9",
520            /* 0xEA */ "unknown_ea",
521            /* 0xEB */ "unknown_eb",
522            /* 0xEC */ "unknown_ec",
523            /* 0xED */ "unknown_ed",
524            /* 0xEE */ "unknown_ee",
525            /* 0xEF */ "unknown_ef",
526            /* 0xF0 */ "unknown_f0",
527            /* 0xF1 */ "unknown_f1",
528            /* 0xF2 */ "unknown_f2",
529            /* 0xF3 */ "unknown_f3",
530            /* 0xF4 */ "unknown_f4",
531            /* 0xF5 */ "unknown_f5",
532            /* 0xF6 */ "unknown_f6",
533            /* 0xF7 */ "unknown_f7",
534            /* 0xF8 */ "unknown_f8",
535            /* 0xF9 */ "unknown_f9",
536            /* 0xFA */ "unknown_fa",
537            /* 0xFB */ "unknown_fb",
538            /* 0xFC */ "unknown_fc",
539            /* 0xFD */ "unknown_fd",
540            /* 0xFE */ "impdep1",
541            /* 0xFF */ "impdep2"
542        };
543    
544        /**
545         * Table with code offsets.
546         */
547        private static final byte[] OFFSET = new byte[256];
548    
549        static {
550            for(int i = 0; i < OFFSET.length; ++i) {
551                OFFSET[i] = 0;
552            }
553            OFFSET[Types.unsigned(BIPUSH)] = 1;
554            OFFSET[Types.unsigned(SIPUSH)] = 2;
555            OFFSET[Types.unsigned(LDC)] = 1;
556            OFFSET[Types.unsigned(LDC_W)] = 2;
557            OFFSET[Types.unsigned(LDC2_W)] = 2;
558            for(int i = Types.unsigned(ILOAD); i <= Types.unsigned(ALOAD); ++i) {
559                OFFSET[i] = 1;
560            }
561            for(int i = Types.unsigned(ISTORE); i <= Types.unsigned(ASTORE); ++i) {
562                OFFSET[i] = 1;
563            }
564            OFFSET[Types.unsigned(IINC)] = 2;
565            for(int i = Types.unsigned(IFEQ); i <= Types.unsigned(JSR); i++) {
566                OFFSET[i] = 2;
567            }
568            OFFSET[Types.unsigned(RET)] = 1;
569            // TABLESWITCH and LOOKUPSWITCH are highly irregular.
570            for(int i = Types.unsigned(GETSTATIC); i <= Types.unsigned(INVOKESTATIC); ++i) {
571                OFFSET[i] = 2;
572            }
573            OFFSET[Types.unsigned(INVOKEINTERFACE)] = 4;
574            OFFSET[Types.unsigned(NEW)] = 2;
575            OFFSET[Types.unsigned(NEWARRAY)] = 1;
576            OFFSET[Types.unsigned(ANEWARRAY)] = 2;
577            OFFSET[Types.unsigned(CHECKCAST)] = 2;
578            OFFSET[Types.unsigned(INSTANCEOF)] = 2;
579            // WIDE is irregular.
580            OFFSET[Types.unsigned(MULTIANEWARRAY)] = 3;
581            OFFSET[Types.unsigned(IFNULL)] = 2;
582            OFFSET[Types.unsigned(IFNONNULL)] = 2;
583            OFFSET[Types.unsigned(GOTO_W)] = 4;
584            OFFSET[Types.unsigned(JSR_W)] = 4;
585        }
586    
587        /**
588         * Return the length of the instruction at the specified offset in the bytecode array. This includes the code itself
589         * and its operands.
590         *
591         * @param code the bytecode array.
592         * @param pc   offset
593         *
594         * @return the length of the code and operands
595         */
596        public static final int getInstrSize(byte[] code, int pc) {
597            return getInstrSize(code, pc, pc);
598        }
599    
600        /**
601         * Return the length of the instruction at the specified offset in the bytecode array. This includes the code itself
602         * and its operands.
603         *
604         * @param code      the bytecode array.
605         * @param pc        offset
606         * @param paddingPC offset for calculating padding
607         *
608         * @return the length of the code and operands
609         */
610        public static final int getInstrSize(byte[] code, int pc, int paddingPC) {
611            byte opcode = code[pc];
612            switch(opcode) {
613                case LOOKUPSWITCH:
614                    {
615                        int pad = 3 - (paddingPC % 4);
616                        long npairs = Types.intFromBytes(code, pc + pad + 5);
617                        assert npairs >= 0;
618                        return (int)(npairs * 8) + pad + 9;
619                    }
620                case TABLESWITCH:
621                    {
622                        int pad = 3 - (paddingPC % 4);
623                        long low = Types.intFromBytes(code, pc + pad + 5);
624                        long high = Types.intFromBytes(code, pc + pad + 9);
625                        long npairs = high - low + 1;
626                        assert low <= high;
627                        return (int)(npairs * 4) + pad + 13;
628                    }
629                case WIDE:
630                    if (code[pc + 1] == IINC) {
631                        return 6;
632                    }
633                    return 4;
634                default:
635                    return 1 + OFFSET[Types.unsigned(opcode)];
636            }
637        }
638    
639        /**
640         * Change the padding on the inside of the instruction found at pc, so that it is padded for a PC=newPC, not for a
641         * PC=paddingPC.
642         *
643         * @param code      bytecode
644         * @param pc        start of instruction in bytecode array
645         * @param paddingPC old PC used for padding
646         * @param newPC     new PC used for padding
647         *
648         * @return repadded bytecode array
649         */
650        public static final byte[] repadInstr(byte[] code, int pc, int paddingPC, int newPC) {
651            byte opcode = code[pc];
652            switch(opcode) {
653                case LOOKUPSWITCH:
654                    {
655                        int pad = 3 - (paddingPC % 4);
656                        int newPad = 3 - (newPC % 4);
657                        byte[] newCode = new byte[code.length - pad + newPad];
658                        System.arraycopy(code, 0, newCode, 0, pc + 1);
659                        System.arraycopy(code, pc + pad + 1, newCode, pc + newPad + 1, code.length - pc - pad - 1);
660    
661                        return newCode;
662                    }
663                case TABLESWITCH:
664                    {
665                        int pad = 3 - (paddingPC % 4);
666                        int newPad = 3 - (newPC % 4);
667                        byte[] newCode = new byte[code.length - pad + newPad];
668                        System.arraycopy(code, 0, newCode, 0, pc + 1);
669                        System.arraycopy(code, pc + pad + 1, newCode, pc + newPad + 1, code.length - pc - pad - 1);
670    
671                        return newCode;
672                    }
673                default:
674                    byte[] newCode = new byte[code.length];
675                    System.arraycopy(code, 0, newCode, 0, code.length);
676    
677                    return newCode;
678            }
679        }
680    
681        /**
682         * Return true if the specified code is a return instruction.
683         *
684         * NOTE: ATHROW is not a return instruction. It does not leave immediately if there are matching exception handlers.
685         *
686         * @param opcode code to check
687         *
688         * @return true if the code is a return instruction
689         */
690        public final static boolean isReturn(byte opcode) {
691            switch(opcode) {
692                case IRETURN:
693                case LRETURN:
694                case FRETURN:
695                case DRETURN:
696                case ARETURN:
697                case RETURN:
698                    return true;
699                default:
700                    return false;
701            }
702        }
703    
704        /**
705         * Table determining if an code is a branch instruction.
706         */
707        private static final boolean[] isBranch = new boolean[256];
708    
709        static {
710            for(int i = 0; i < isBranch.length; ++i) {
711                isBranch[i] = false;
712            }
713            for(int i = Types.unsigned(IFEQ); i <= Types.unsigned(RETURN); i++) {
714                isBranch[i] = true;
715            }
716            for(int i = Types.unsigned(IFNULL); i <= Types.unsigned(JSR_W); i++) {
717                isBranch[i] = true;
718            }
719            isBranch[Types.unsigned(ATHROW)] = true;
720        }
721    
722        /**
723         * Return true if the specified code is a branch instruction.
724         *
725         * @param opcode code to check
726         *
727         * @return true if the code is a branch instruction
728         */
729        public final static boolean isBranch(byte opcode) {
730            return isBranch[Types.unsigned(opcode)];
731        }
732    
733        /**
734         * Return true if the specified code is an unconditional branch instruction.
735         *
736         * @param opcode code to check
737         *
738         * @return true if the code is an unconditional branch instruction
739         */
740        public final static boolean isUnconditionalBranch(byte opcode) {
741            switch(opcode) {
742                case GOTO:
743                case GOTO_W:
744                case JSR:
745                case JSR_W:
746                case RET:
747                case IRETURN:
748                case LRETURN:
749                case FRETURN:
750                case DRETURN:
751                case ARETURN:
752                case RETURN:
753                case ATHROW:
754                case LOOKUPSWITCH:
755                case TABLESWITCH:
756                    return true;
757                default:
758                    return false;
759            }
760        }
761    
762        /**
763         * Return true if the specified code is a subroutine call.
764         *
765         * @param opcode code to check
766         *
767         * @return true if the code is a JSR or JSR_W instruction
768         */
769        public final static boolean isJSR(byte opcode) {
770            return ((opcode == JSR) || (opcode == JSR_W));
771        }
772    
773        /**
774         * Returns an array of branch targets for the instruction.
775         *
776         * @param code      byte code
777         * @param pc        program counter
778         * @param paddingPC
779         *
780         * @return array of branch targets
781         */
782        public final static int[] getBranchTargets(byte[] code, int pc, int paddingPC) {
783            if (!isBranch(code[pc])) {
784                return new int[0];
785            }
786    
787            switch(code[pc]) {
788                case LOOKUPSWITCH:
789                    {
790                        int pad = 3 - (paddingPC % 4);
791                        long deflt = Types.intFromBytes(code, pc + pad + 1);
792                        long npairs = Types.intFromBytes(code, pc + pad + 5);
793                        assert npairs >= 0;
794    
795                        int[] result = new int[(int)npairs + 1];
796                        result[0] = pc + ((int)deflt);
797                        for(int i = 0; i < npairs; i++) {
798                            long offset = Types.intFromBytes(code, pc + pad + 9 + 4 + (8 * i));
799                            result[i + 1] = pc + ((int)offset);
800                        }
801                        return result;
802                    }
803    
804                case TABLESWITCH:
805                    {
806                        int pad = 3 - (paddingPC % 4);
807                        long deflt = Types.intFromBytes(code, pc + pad + 1);
808                        long low = Types.intFromBytes(code, pc + pad + 5);
809                        long high = Types.intFromBytes(code, pc + pad + 9);
810                        long npairs = high - low + 1;
811                        assert low <= high;
812    
813                        int[] result = new int[(int)npairs + 1];
814                        result[0] = pc + ((int)deflt);
815                        for(int i = 0; i < npairs; i++) {
816                            long offset = Types.intFromBytes(code, pc + pad + 13 + (4 * i));
817                            result[i + 1] = pc + ((int)offset);
818                        }
819                        return result;
820                    }
821    
822                case GOTO_W:
823                case JSR_W:
824                    {
825                        long offset = Types.intFromBytes(code, pc + 1);
826                        int[] result = new int[1];
827                        result[0] = pc + (int)offset;
828                        return result;
829    
830                    }
831    
832                case RET:
833                case RETURN:
834                case IRETURN:
835                case LRETURN:
836                case FRETURN:
837                case DRETURN:
838                case ARETURN:
839                case ATHROW:
840                    {
841                        return new int[0];
842                    }
843    
844                default:
845                    {
846                        int offset = Types.ushortFromBytes(code, pc + 1);
847                        int[] result = new int[1];
848                        result[0] = pc + offset;
849                        return result;
850    
851                    }
852            }
853        }
854    
855    
856        /**
857         * Sets the branch targets for an instruction.
858         *
859         * NOTE: The number of branch targets has to remain unchanged.
860         *
861         * @param code          byte code
862         * @param pc            program counter
863         * @param branchTargets array of branch targets
864         */
865        public final static void setBranchTargets(byte[] code, int pc, int[] branchTargets) {
866            if (!isBranch(code[pc])) {
867                throw new IllegalArgumentException("Cannot set branch targets for non-branch instruction");
868            }
869    
870            switch(code[pc]) {
871                case LOOKUPSWITCH:
872                    {
873                        int pad = 3 - (pc % 4);
874                        long npairs = Types.intFromBytes(code, pc + pad + 5);
875                        assert npairs >= 0;
876    
877                        if (branchTargets.length != npairs + 1) {
878                            throw new IllegalArgumentException("Not allowed to change number of branch targets");
879                        }
880    
881                        int delta = branchTargets[0] - pc;
882                        Types.bytesFromInt(delta, code, pc + pad + 1);
883                        for(int i = 0; i < npairs; i++) {
884                            delta = branchTargets[1 + i] - pc;
885                            Types.bytesFromInt(delta, code, pc + pad + 9 + 4 + (8 * i));
886                        }
887                        return;
888                    }
889    
890                case TABLESWITCH:
891                    {
892                        int pad = 3 - (pc % 4);
893                        long low = Types.intFromBytes(code, pc + pad + 5);
894                        long high = Types.intFromBytes(code, pc + pad + 9);
895                        long npairs = high - low + 1;
896                        assert low <= high;
897    
898                        if (branchTargets.length != npairs + 1) {
899                            throw new IllegalArgumentException("Not allowed to change number of branch targets");
900                        }
901    
902                        int delta = branchTargets[0] - pc;
903                        Types.bytesFromInt(delta, code, pc + pad + 1);
904                        for(int i = 0; i < npairs; i++) {
905                            delta = branchTargets[1 + i] - pc;
906                            Types.bytesFromInt(delta, code, pc + pad + 13 + (4 * i));
907                        }
908                        return;
909                    }
910    
911                case GOTO_W:
912                case JSR_W:
913                    {
914                        if (branchTargets.length != 1) {
915                            throw new IllegalArgumentException("Not allowed to change number of branch targets");
916                        }
917                        int delta = branchTargets[0] - pc;
918                        Types.bytesFromInt(delta, code, pc + 1);
919                        return;
920    
921                    }
922    
923                case RET:
924                case RETURN:
925                case IRETURN:
926                case LRETURN:
927                case FRETURN:
928                case DRETURN:
929                case ARETURN:
930                case ATHROW:
931                    {
932                        if (branchTargets.length != 0) {
933                            throw new IllegalArgumentException("Not allowed to change number of branch targets");
934                        }
935                        return;
936                    }
937    
938                default:
939                    {
940                        if (branchTargets.length != 1) {
941                            throw new IllegalArgumentException("Not allowed to change number of branch targets");
942                        }
943                        int delta = (branchTargets[0] - pc);
944                        Types.bytesFromShort((short)(0xffff & delta), code, pc + 1);
945                        return;
946    
947                    }
948            }
949        }
950    
951        /**
952         * Return the shortest instruction possible that loads/stores local variable index onto the stack.
953         * @param baseOpcode the kind of load/store (ALOAD, ILOAD, ...)
954         * @param index local variable index
955         * @return shortest instruction to load/store
956         */
957        public static AInstruction getShortestLoadStoreInstruction(byte baseOpcode, short index) {
958            switch(baseOpcode) {
959                case ILOAD:
960                case ILOAD_0:
961                case ILOAD_1:
962                case ILOAD_2:
963                case ILOAD_3:
964                    switch(index) {
965                        case 0: return new GenericInstruction(ILOAD_0);
966                        case 1: return new GenericInstruction(ILOAD_1);
967                        case 2: return new GenericInstruction(ILOAD_2);
968                        case 3: return new GenericInstruction(ILOAD_3);
969                        default:
970                            if (index<=256) {
971                                return new GenericInstruction(ILOAD, (byte)index);
972                            }
973                            else {
974                                byte[] b = Types.bytesFromInt(index);
975                                return new WideInstruction(new byte[] {ILOAD, b[0], b[1]});
976                            }
977                    }
978                case LLOAD:
979                case LLOAD_0:
980                case LLOAD_1:
981                case LLOAD_2:
982                case LLOAD_3:
983                    switch(index) {
984                        case 0: return new GenericInstruction(LLOAD_0);
985                        case 1: return new GenericInstruction(LLOAD_1);
986                        case 2: return new GenericInstruction(LLOAD_2);
987                        case 3: return new GenericInstruction(LLOAD_3);
988                        default:
989                            if (index<=256) {
990                                return new GenericInstruction(LLOAD, (byte)index);
991                            }
992                            else {
993                                byte[] b = Types.bytesFromInt(index);
994                                return new WideInstruction(new byte[] {LLOAD, b[0], b[1]});
995                            }
996                    }
997                case FLOAD:
998                case FLOAD_0:
999                case FLOAD_1:
1000                case FLOAD_2:
1001                case FLOAD_3:
1002                    switch(index) {
1003                        case 0: return new GenericInstruction(FLOAD_0);
1004                        case 1: return new GenericInstruction(FLOAD_1);
1005                        case 2: return new GenericInstruction(FLOAD_2);
1006                        case 3: return new GenericInstruction(FLOAD_3);
1007                        default:
1008                            if (index<=256) {
1009                                return new GenericInstruction(FLOAD, (byte)index);
1010                            }
1011                            else {
1012                                byte[] b = Types.bytesFromInt(index);
1013                                return new WideInstruction(new byte[] {FLOAD, b[0], b[1]});
1014                            }
1015                    }
1016                case DLOAD:
1017                case DLOAD_0:
1018                case DLOAD_1:
1019                case DLOAD_2:
1020                case DLOAD_3:
1021                    switch(index) {
1022                        case 0: return new GenericInstruction(DLOAD_0);
1023                        case 1: return new GenericInstruction(DLOAD_1);
1024                        case 2: return new GenericInstruction(DLOAD_2);
1025                        case 3: return new GenericInstruction(DLOAD_3);
1026                        default:
1027                            if (index<=256) {
1028                                return new GenericInstruction(DLOAD, (byte)index);
1029                            }
1030                            else {
1031                                byte[] b = Types.bytesFromInt(index);
1032                                return new WideInstruction(new byte[] {DLOAD, b[0], b[1]});
1033                            }
1034                    }
1035                case ALOAD:
1036                case ALOAD_0:
1037                case ALOAD_1:
1038                case ALOAD_2:
1039                case ALOAD_3:
1040                    switch(index) {
1041                        case 0: return new GenericInstruction(ALOAD_0);
1042                        case 1: return new GenericInstruction(ALOAD_1);
1043                        case 2: return new GenericInstruction(ALOAD_2);
1044                        case 3: return new GenericInstruction(ALOAD_3);
1045                        default:
1046                            if (index<=256) {
1047                                return new GenericInstruction(ALOAD, (byte)index);
1048                            }
1049                            else {
1050                                byte[] b = Types.bytesFromInt(index);
1051                                return new WideInstruction(new byte[] {ALOAD, b[0], b[1]});
1052                            }
1053                    }
1054                    // store instructions
1055                case ISTORE:
1056                case ISTORE_0:
1057                case ISTORE_1:
1058                case ISTORE_2:
1059                case ISTORE_3:
1060                    switch(index) {
1061                        case 0: return new GenericInstruction(ISTORE_0);
1062                        case 1: return new GenericInstruction(ISTORE_1);
1063                        case 2: return new GenericInstruction(ISTORE_2);
1064                        case 3: return new GenericInstruction(ISTORE_3);
1065                        default:
1066                            if (index<=256) {
1067                                return new GenericInstruction(ISTORE, (byte)index);
1068                            }
1069                            else {
1070                                byte[] b = Types.bytesFromInt(index);
1071                                return new WideInstruction(new byte[] {ISTORE, b[0], b[1]});
1072                            }
1073                    }
1074                case LSTORE:
1075                case LSTORE_0:
1076                case LSTORE_1:
1077                case LSTORE_2:
1078                case LSTORE_3:
1079                    switch(index) {
1080                        case 0: return new GenericInstruction(LSTORE_0);
1081                        case 1: return new GenericInstruction(LSTORE_1);
1082                        case 2: return new GenericInstruction(LSTORE_2);
1083                        case 3: return new GenericInstruction(LSTORE_3);
1084                        default:
1085                            if (index<=256) {
1086                                return new GenericInstruction(LSTORE, (byte)index);
1087                            }
1088                            else {
1089                                byte[] b = Types.bytesFromInt(index);
1090                                return new WideInstruction(new byte[] {LSTORE, b[0], b[1]});
1091                            }
1092                    }
1093                case FSTORE:
1094                case FSTORE_0:
1095                case FSTORE_1:
1096                case FSTORE_2:
1097                case FSTORE_3:
1098                    switch(index) {
1099                        case 0: return new GenericInstruction(FSTORE_0);
1100                        case 1: return new GenericInstruction(FSTORE_1);
1101                        case 2: return new GenericInstruction(FSTORE_2);
1102                        case 3: return new GenericInstruction(FSTORE_3);
1103                        default:
1104                            if (index<=256) {
1105                                return new GenericInstruction(FSTORE, (byte)index);
1106                            }
1107                            else {
1108                                byte[] b = Types.bytesFromInt(index);
1109                                return new WideInstruction(new byte[] {FSTORE, b[0], b[1]});
1110                            }
1111                    }
1112                case DSTORE:
1113                case DSTORE_0:
1114                case DSTORE_1:
1115                case DSTORE_2:
1116                case DSTORE_3:
1117                    switch(index) {
1118                        case 0: return new GenericInstruction(DSTORE_0);
1119                        case 1: return new GenericInstruction(DSTORE_1);
1120                        case 2: return new GenericInstruction(DSTORE_2);
1121                        case 3: return new GenericInstruction(DSTORE_3);
1122                        default:
1123                            if (index<=256) {
1124                                return new GenericInstruction(DSTORE, (byte)index);
1125                            }
1126                            else {
1127                                byte[] b = Types.bytesFromInt(index);
1128                                return new WideInstruction(new byte[] {DSTORE, b[0], b[1]});
1129                            }
1130                    }
1131                case ASTORE:
1132                case ASTORE_0:
1133                case ASTORE_1:
1134                case ASTORE_2:
1135                case ASTORE_3:
1136                    switch(index) {
1137                        case 0: return new GenericInstruction(ASTORE_0);
1138                        case 1: return new GenericInstruction(ASTORE_1);
1139                        case 2: return new GenericInstruction(ASTORE_2);
1140                        case 3: return new GenericInstruction(ASTORE_3);
1141                        default:
1142                            if (index<=256) {
1143                                return new GenericInstruction(ASTORE, (byte)index);
1144                            }
1145                            else {
1146                                byte[] b = Types.bytesFromInt(index);
1147                                return new WideInstruction(new byte[] {ASTORE, b[0], b[1]});
1148                            }
1149                    }
1150                default:
1151                    throw new IllegalArgumentException("Only ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE and ASTORE allowed");
1152            }
1153        }
1154    }