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