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 }