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 }