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 }