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 }