1 cananian 1.3.2.3 // Op.java, created Sun Sep 13 22:49:21 1998 by cananian 2 cananian 1.3 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.3 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1 package harpoon.IR.Bytecode; 5 cananian 1.1 6 cananian 1.3.2.2 import harpoon.Util.Util; 7 cananian 1.1 /** 8 cananian 1.1 * The <code>Op</code> class contains constants and tables that we are 9 cananian 1.1 * likely to find useful when grokking a java bytecode stream. 10 cananian 1.1 * <p> 11 cananian 1.1 * Included are: <UL> 12 cananian 1.1 * <LI>final static byte constants for all the JVM opcodes. 13 cananian 1.1 * <LI>a method to convert any byte opcode to the string naming it. 14 cananian 1.1 * <LI>a method giving the size (number of operands) of an 15 cananian 1.1 * arbitrary opcode. 16 cananian 1.1 * <LI>a way to tell whether a given opcode is a branch instruction, and 17 cananian 1.1 * if so whether the branch is conditional or unconditional. 18 cananian 1.1 * <LI>a method to decode the targets of any branch instruction. 19 cananian 1.1 * </UL> 20 cananian 1.1 * 21 cananian 1.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 22 cananian 1.6 * @version $Id: Op.java,v 1.6 2002/04/10 03:04:37 cananian Exp $ 23 cananian 1.3.2.1 * @see harpoon.IR.RawClass.AttributeCode 24 cananian 1.1 * @see harpoon.IR.Bytecode.Instr 25 cananian 1.1 * @see harpoon.IR.Bytecode.Code 26 cananian 1.1 */ 27 cananian 1.1 28 cananian 1.2 public abstract class Op { 29 cananian 1.1 30 cananian 1.1 // Set up table of opcodes. 31 cananian 1.1 public final static byte 32 cananian 1.1 NOP = (byte) 0x00, 33 cananian 1.1 ACONST_NULL = (byte) 0x01, 34 cananian 1.1 ICONST_M1 = (byte) 0x02, 35 cananian 1.1 ICONST_0 = (byte) 0x03, 36 cananian 1.1 ICONST_1 = (byte) 0x04, 37 cananian 1.1 ICONST_2 = (byte) 0x05, 38 cananian 1.1 ICONST_3 = (byte) 0x06, 39 cananian 1.1 ICONST_4 = (byte) 0x07, 40 cananian 1.1 ICONST_5 = (byte) 0x08, 41 cananian 1.1 LCONST_0 = (byte) 0x09, 42 cananian 1.1 LCONST_1 = (byte) 0x0A, 43 cananian 1.1 FCONST_0 = (byte) 0x0B, 44 cananian 1.1 FCONST_1 = (byte) 0x0C, 45 cananian 1.1 FCONST_2 = (byte) 0x0D, 46 cananian 1.1 DCONST_0 = (byte) 0x0E, 47 cananian 1.1 DCONST_1 = (byte) 0x0F, 48 cananian 1.1 BIPUSH = (byte) 0x10, 49 cananian 1.1 SIPUSH = (byte) 0x11, 50 cananian 1.1 LDC = (byte) 0x12, 51 cananian 1.1 LDC_W = (byte) 0x13, 52 cananian 1.1 LDC2_W = (byte) 0x14, 53 cananian 1.1 ILOAD = (byte) 0x15, 54 cananian 1.1 LLOAD = (byte) 0x16, 55 cananian 1.1 FLOAD = (byte) 0x17, 56 cananian 1.1 DLOAD = (byte) 0x18, 57 cananian 1.1 ALOAD = (byte) 0x19, 58 cananian 1.1 ILOAD_0 = (byte) 0x1A, 59 cananian 1.1 ILOAD_1 = (byte) 0x1B, 60 cananian 1.1 ILOAD_2 = (byte) 0x1C, 61 cananian 1.1 ILOAD_3 = (byte) 0x1D, 62 cananian 1.1 LLOAD_0 = (byte) 0x1E, 63 cananian 1.1 LLOAD_1 = (byte) 0x1F, 64 cananian 1.1 LLOAD_2 = (byte) 0x20, 65 cananian 1.1 LLOAD_3 = (byte) 0x21, 66 cananian 1.1 FLOAD_0 = (byte) 0x22, 67 cananian 1.1 FLOAD_1 = (byte) 0x23, 68 cananian 1.1 FLOAD_2 = (byte) 0x24, 69 cananian 1.1 FLOAD_3 = (byte) 0x25, 70 cananian 1.1 DLOAD_0 = (byte) 0x26, 71 cananian 1.1 DLOAD_1 = (byte) 0x27, 72 cananian 1.1 DLOAD_2 = (byte) 0x28, 73 cananian 1.1 DLOAD_3 = (byte) 0x29, 74 cananian 1.1 ALOAD_0 = (byte) 0x2A, 75 cananian 1.1 ALOAD_1 = (byte) 0x2B, 76 cananian 1.1 ALOAD_2 = (byte) 0x2C, 77 cananian 1.1 ALOAD_3 = (byte) 0x2D, 78 cananian 1.1 IALOAD = (byte) 0x2E, 79 cananian 1.1 LALOAD = (byte) 0x2F, 80 cananian 1.1 FALOAD = (byte) 0x30, 81 cananian 1.1 DALOAD = (byte) 0x31, 82 cananian 1.1 AALOAD = (byte) 0x32, 83 cananian 1.1 BALOAD = (byte) 0x33, 84 cananian 1.1 CALOAD = (byte) 0x34, 85 cananian 1.1 SALOAD = (byte) 0x35, 86 cananian 1.1 ISTORE = (byte) 0x36, 87 cananian 1.1 LSTORE = (byte) 0x37, 88 cananian 1.1 FSTORE = (byte) 0x38, 89 cananian 1.1 DSTORE = (byte) 0x39, 90 cananian 1.1 ASTORE = (byte) 0x3A, 91 cananian 1.1 ISTORE_0 = (byte) 0x3B, 92 cananian 1.1 ISTORE_1 = (byte) 0x3C, 93 cananian 1.1 ISTORE_2 = (byte) 0x3D, 94 cananian 1.1 ISTORE_3 = (byte) 0x3E, 95 cananian 1.1 LSTORE_0 = (byte) 0x3F; 96 cananian 1.1 public final static byte 97 cananian 1.1 LSTORE_1 = (byte) 0x40, 98 cananian 1.1 LSTORE_2 = (byte) 0x41, 99 cananian 1.1 LSTORE_3 = (byte) 0x42, 100 cananian 1.1 FSTORE_0 = (byte) 0x43, 101 cananian 1.1 FSTORE_1 = (byte) 0x44, 102 cananian 1.1 FSTORE_2 = (byte) 0x45, 103 cananian 1.1 FSTORE_3 = (byte) 0x46, 104 cananian 1.1 DSTORE_0 = (byte) 0x47, 105 cananian 1.1 DSTORE_1 = (byte) 0x48, 106 cananian 1.1 DSTORE_2 = (byte) 0x49, 107 cananian 1.1 DSTORE_3 = (byte) 0x4A, 108 cananian 1.1 ASTORE_0 = (byte) 0x4B, 109 cananian 1.1 ASTORE_1 = (byte) 0x4C, 110 cananian 1.1 ASTORE_2 = (byte) 0x4D, 111 cananian 1.1 ASTORE_3 = (byte) 0x4E, 112 cananian 1.1 IASTORE = (byte) 0x4F, 113 cananian 1.1 LASTORE = (byte) 0x50, 114 cananian 1.1 FASTORE = (byte) 0x51, 115 cananian 1.1 DASTORE = (byte) 0x52, 116 cananian 1.1 AASTORE = (byte) 0x53, 117 cananian 1.1 BASTORE = (byte) 0x54, 118 cananian 1.1 CASTORE = (byte) 0x55, 119 cananian 1.1 SASTORE = (byte) 0x56, 120 cananian 1.1 POP = (byte) 0x57, 121 cananian 1.1 POP2 = (byte) 0x58, 122 cananian 1.1 DUP = (byte) 0x59, 123 cananian 1.1 DUP_X1 = (byte) 0x5A, 124 cananian 1.1 DUP_X2 = (byte) 0x5B, 125 cananian 1.1 DUP2 = (byte) 0x5C, 126 cananian 1.1 DUP2_X1 = (byte) 0x5D, 127 cananian 1.1 DUP2_X2 = (byte) 0x5E, 128 cananian 1.1 SWAP = (byte) 0x5F, 129 cananian 1.1 IADD = (byte) 0x60, 130 cananian 1.1 LADD = (byte) 0x61, 131 cananian 1.1 FADD = (byte) 0x62, 132 cananian 1.1 DADD = (byte) 0x63, 133 cananian 1.1 ISUB = (byte) 0x64, 134 cananian 1.1 LSUB = (byte) 0x65, 135 cananian 1.1 FSUB = (byte) 0x66, 136 cananian 1.1 DSUB = (byte) 0x67, 137 cananian 1.1 IMUL = (byte) 0x68, 138 cananian 1.1 LMUL = (byte) 0x69, 139 cananian 1.1 FMUL = (byte) 0x6A, 140 cananian 1.1 DMUL = (byte) 0x6B, 141 cananian 1.1 IDIV = (byte) 0x6C, 142 cananian 1.1 LDIV = (byte) 0x6D, 143 cananian 1.1 FDIV = (byte) 0x6E, 144 cananian 1.1 DDIV = (byte) 0x6F, 145 cananian 1.1 IREM = (byte) 0x70, 146 cananian 1.1 LREM = (byte) 0x71, 147 cananian 1.1 FREM = (byte) 0x72, 148 cananian 1.1 DREM = (byte) 0x73, 149 cananian 1.1 INEG = (byte) 0x74, 150 cananian 1.1 LNEG = (byte) 0x75, 151 cananian 1.1 FNEG = (byte) 0x76, 152 cananian 1.1 DNEG = (byte) 0x77, 153 cananian 1.1 ISHL = (byte) 0x78, 154 cananian 1.1 LSHL = (byte) 0x79, 155 cananian 1.1 ISHR = (byte) 0x7A, 156 cananian 1.1 LSHR = (byte) 0x7B, 157 cananian 1.1 IUSHR = (byte) 0x7C, 158 cananian 1.1 LUSHR = (byte) 0x7D, 159 cananian 1.1 IAND = (byte) 0x7E, 160 cananian 1.1 LAND = (byte) 0x7F; 161 cananian 1.1 public final static byte 162 cananian 1.1 IOR = (byte) 0x80, 163 cananian 1.1 LOR = (byte) 0x81, 164 cananian 1.1 IXOR = (byte) 0x82, 165 cananian 1.1 LXOR = (byte) 0x83, 166 cananian 1.1 IINC = (byte) 0x84, 167 cananian 1.1 I2L = (byte) 0x85, 168 cananian 1.1 I2F = (byte) 0x86, 169 cananian 1.1 I2D = (byte) 0x87, 170 cananian 1.1 L2I = (byte) 0x88, 171 cananian 1.1 L2F = (byte) 0x89, 172 cananian 1.1 L2D = (byte) 0x8A, 173 cananian 1.1 F2I = (byte) 0x8B, 174 cananian 1.1 F2L = (byte) 0x8C, 175 cananian 1.1 F2D = (byte) 0x8D, 176 cananian 1.1 D2I = (byte) 0x8E, 177 cananian 1.1 D2L = (byte) 0x8F, 178 cananian 1.1 D2F = (byte) 0x90, 179 cananian 1.1 I2B = (byte) 0x91, 180 cananian 1.1 I2C = (byte) 0x92, 181 cananian 1.1 I2S = (byte) 0x93, 182 cananian 1.1 LCMP = (byte) 0x94, 183 cananian 1.1 FCMPL = (byte) 0x95, 184 cananian 1.1 FCMPG = (byte) 0x96, 185 cananian 1.1 DCMPL = (byte) 0x97, 186 cananian 1.1 DCMPG = (byte) 0x98, 187 cananian 1.1 IFEQ = (byte) 0x99, 188 cananian 1.1 IFNE = (byte) 0x9A, 189 cananian 1.1 IFLT = (byte) 0x9B, 190 cananian 1.1 IFGE = (byte) 0x9C, 191 cananian 1.1 IFGT = (byte) 0x9D, 192 cananian 1.1 IFLE = (byte) 0x9E, 193 cananian 1.1 IF_ICMPEQ = (byte) 0x9F, 194 cananian 1.1 IF_ICMPNE = (byte) 0xA0, 195 cananian 1.1 IF_ICMPLT = (byte) 0xA1, 196 cananian 1.1 IF_ICMPGE = (byte) 0xA2, 197 cananian 1.1 IF_ICMPGT = (byte) 0xA3, 198 cananian 1.1 IF_ICMPLE = (byte) 0xA4, 199 cananian 1.1 IF_ACMPEQ = (byte) 0xA5, 200 cananian 1.1 IF_ACMPNE = (byte) 0xA6, 201 cananian 1.1 GOTO = (byte) 0xA7, 202 cananian 1.1 JSR = (byte) 0xA8, 203 cananian 1.1 RET = (byte) 0xA9, 204 cananian 1.1 TABLESWITCH = (byte) 0xAA, 205 cananian 1.1 LOOKUPSWITCH = (byte) 0xAB, 206 cananian 1.1 IRETURN = (byte) 0xAC, 207 cananian 1.1 LRETURN = (byte) 0xAD, 208 cananian 1.1 FRETURN = (byte) 0xAE, 209 cananian 1.1 DRETURN = (byte) 0xAF, 210 cananian 1.1 ARETURN = (byte) 0xB0, 211 cananian 1.1 RETURN = (byte) 0xB1, 212 cananian 1.1 GETSTATIC = (byte) 0xB2, 213 cananian 1.1 PUTSTATIC = (byte) 0xB3, 214 cananian 1.1 GETFIELD = (byte) 0xB4, 215 cananian 1.1 PUTFIELD = (byte) 0xB5, 216 cananian 1.1 INVOKEVIRTUAL = (byte) 0xB6, 217 cananian 1.1 INVOKESPECIAL = (byte) 0xB7, 218 cananian 1.1 INVOKESTATIC = (byte) 0xB8, 219 cananian 1.1 INVOKEINTERFACE = (byte) 0xB9, 220 cananian 1.1 XXXUNUSEDXXX = (byte) 0xBA, 221 cananian 1.1 NEW = (byte) 0xBB, 222 cananian 1.1 NEWARRAY = (byte) 0xBC, 223 cananian 1.1 ANEWARRAY = (byte) 0xBD, 224 cananian 1.1 ARRAYLENGTH = (byte) 0xBE, 225 cananian 1.1 ATHROW = (byte) 0xBF; 226 cananian 1.1 public final static byte 227 cananian 1.1 CHECKCAST = (byte) 0xC0, 228 cananian 1.1 INSTANCEOF = (byte) 0xC1, 229 cananian 1.1 MONITORENTER = (byte) 0xC2, 230 cananian 1.1 MONITOREXIT = (byte) 0xC3, 231 cananian 1.1 WIDE = (byte) 0xC4, 232 cananian 1.1 MULTIANEWARRAY = (byte) 0xC5, 233 cananian 1.1 IFNULL = (byte) 0xC6, 234 cananian 1.1 IFNONNULL = (byte) 0xC7, 235 cananian 1.1 GOTO_W = (byte) 0xC8, 236 cananian 1.1 JSR_W = (byte) 0xC9; 237 cananian 1.1 // Reserved 238 cananian 1.1 public final static byte 239 cananian 1.1 BREAKPOINT = (byte) 0xCA; 240 cananian 1.1 // _quick opcodes (never found in class files) 241 cananian 1.1 public final static byte 242 cananian 1.1 LDC_QUICK = (byte) 0xCB, 243 cananian 1.1 LDC_W_QUICK = (byte) 0xCC, 244 cananian 1.1 LDC2_W_QUICK = (byte) 0xCD, 245 cananian 1.1 GETFIELD_QUICK = (byte) 0xCE, 246 cananian 1.1 PUTFIELD_QUICK = (byte) 0xCF, 247 cananian 1.1 GETFIELD2_QUICK = (byte) 0xD0, 248 cananian 1.1 PUTFIELD2_QUICK = (byte) 0xD1, 249 cananian 1.1 GETSTATIC_QUICK = (byte) 0xD2, 250 cananian 1.1 PUTSTATIC_QUICK = (byte) 0xD3, 251 cananian 1.1 GETSTATIC2_QUICK = (byte) 0xD4, 252 cananian 1.1 PUTSTATIC2_QUICK = (byte) 0xD5, 253 cananian 1.1 INVOKEVIRTUAL_QUICK = (byte) 0xD6, 254 cananian 1.1 INVOKENONVIRTUAL_QUICK = (byte) 0xD7, 255 cananian 1.1 INVOKESUPER_QUICK = (byte) 0xD8, 256 cananian 1.1 INVOKESTATIC_QUICK = (byte) 0xD9, 257 cananian 1.1 INVOKEINTERFACE_QUICK = (byte) 0xDA, 258 cananian 1.1 INVOKEVIRTUALOBJECT_QUICK = (byte) 0xDB, 259 cananian 1.1 UNKNOWN_DC = (byte) 0xDC, 260 cananian 1.1 NEW_QUICK = (byte) 0xDD, 261 cananian 1.1 ANEWARRAY_QUICK = (byte) 0xDE, 262 cananian 1.1 MULTIANEWARRAY_QUICK = (byte) 0xDF, 263 cananian 1.1 CHECKCAST_QUICK = (byte) 0xE0, 264 cananian 1.1 INSTANCEOF_QUICK = (byte) 0xE1, 265 cananian 1.1 INVOKEVIRTUAL_QUICK_W = (byte) 0xE2, 266 cananian 1.1 GETFIELD_QUICK_W = (byte) 0xE3, 267 cananian 1.1 PUTFIELD_QUICK_W = (byte) 0xE4; 268 cananian 1.1 // Unused 269 cananian 1.1 public final static byte 270 cananian 1.1 UNKNOWN_E5 = (byte) 0xE5, 271 cananian 1.1 UNKNOWN_E6 = (byte) 0xE6, 272 cananian 1.1 UNKNOWN_E7 = (byte) 0xE7, 273 cananian 1.1 UNKNOWN_E8 = (byte) 0xE8, 274 cananian 1.1 UNKNOWN_E9 = (byte) 0xE9, 275 cananian 1.1 UNKNOWN_EA = (byte) 0xEA, 276 cananian 1.1 UNKNOWN_EB = (byte) 0xEB, 277 cananian 1.1 UNKNOWN_EC = (byte) 0xEC, 278 cananian 1.1 UNKNOWN_ED = (byte) 0xED, 279 cananian 1.1 UNKNOWN_EE = (byte) 0xEE, 280 cananian 1.1 UNKNOWN_EF = (byte) 0xEF, 281 cananian 1.1 UNKNOWN_F0 = (byte) 0xF0, 282 cananian 1.1 UNKNOWN_F1 = (byte) 0xF1, 283 cananian 1.1 UNKNOWN_F2 = (byte) 0xF2, 284 cananian 1.1 UNKNOWN_F3 = (byte) 0xF3, 285 cananian 1.1 UNKNOWN_F4 = (byte) 0xF4, 286 cananian 1.1 UNKNOWN_F5 = (byte) 0xF5, 287 cananian 1.1 UNKNOWN_F6 = (byte) 0xF6, 288 cananian 1.1 UNKNOWN_F7 = (byte) 0xF7, 289 cananian 1.1 UNKNOWN_F8 = (byte) 0xF8, 290 cananian 1.1 UNKNOWN_F9 = (byte) 0xF9, 291 cananian 1.1 UNKNOWN_FA = (byte) 0xFA, 292 cananian 1.1 UNKNOWN_FB = (byte) 0xFB, 293 cananian 1.1 UNKNOWN_FC = (byte) 0xFC, 294 cananian 1.1 UNKNOWN_FD = (byte) 0xFD; 295 cananian 1.1 // Reserved 296 cananian 1.1 public final static byte 297 cananian 1.1 IMPDEP1 = (byte) 0xFE, 298 cananian 1.1 IMPDEP2 = (byte) 0xFF; 299 cananian 1.1 300 cananian 1.1 /** Get the human-readable name of a given opcode. */ 301 cananian 1.1 public final static String toString(byte opcode) 302 cananian 1.1 { return opcodeNames[((int)opcode)&0xFF]; } 303 cananian 1.1 // Table of opcode names 304 cananian 1.1 private final static String[] opcodeNames = new String[] { 305 cananian 1.1 /* 0x00 */ "nop", 306 cananian 1.1 /* 0x01 */ "aconst_null", 307 cananian 1.1 /* 0x02 */ "iconst_m1", 308 cananian 1.1 /* 0x03 */ "iconst_0", 309 cananian 1.1 /* 0x04 */ "iconst_1", 310 cananian 1.1 /* 0x05 */ "iconst_2", 311 cananian 1.1 /* 0x06 */ "iconst_3", 312 cananian 1.1 /* 0x07 */ "iconst_4", 313 cananian 1.1 /* 0x08 */ "iconst_5", 314 cananian 1.1 /* 0x09 */ "lconst_0", 315 cananian 1.1 /* 0x0A */ "lconst_1", 316 cananian 1.1 /* 0x0B */ "fconst_0", 317 cananian 1.1 /* 0x0C */ "fconst_1", 318 cananian 1.1 /* 0x0D */ "fconst_2", 319 cananian 1.1 /* 0x0E */ "dconst_0", 320 cananian 1.1 /* 0x0F */ "dconst_1", 321 cananian 1.1 /* 0x10 */ "bipush", 322 cananian 1.1 /* 0x11 */ "sipush", 323 cananian 1.1 /* 0x12 */ "ldc", 324 cananian 1.1 /* 0x13 */ "ldc_w", 325 cananian 1.1 /* 0x14 */ "ldc2_w", 326 cananian 1.1 /* 0x15 */ "iload", 327 cananian 1.1 /* 0x16 */ "lload", 328 cananian 1.1 /* 0x17 */ "fload", 329 cananian 1.1 /* 0x18 */ "dload", 330 cananian 1.1 /* 0x19 */ "aload", 331 cananian 1.1 /* 0x1A */ "iload_0", 332 cananian 1.1 /* 0x1B */ "iload_1", 333 cananian 1.1 /* 0x1C */ "iload_2", 334 cananian 1.1 /* 0x1D */ "iload_3", 335 cananian 1.1 /* 0x1E */ "lload_0", 336 cananian 1.1 /* 0x1F */ "lload_1", 337 cananian 1.1 /* 0x20 */ "lload_2", 338 cananian 1.1 /* 0x21 */ "lload_3", 339 cananian 1.1 /* 0x22 */ "fload_0", 340 cananian 1.1 /* 0x23 */ "fload_1", 341 cananian 1.1 /* 0x24 */ "fload_2", 342 cananian 1.1 /* 0x25 */ "fload_3", 343 cananian 1.1 /* 0x26 */ "dload_0", 344 cananian 1.1 /* 0x27 */ "dload_1", 345 cananian 1.1 /* 0x28 */ "dload_2", 346 cananian 1.1 /* 0x29 */ "dload_3", 347 cananian 1.1 /* 0x2A */ "aload_0", 348 cananian 1.1 /* 0x2B */ "aload_1", 349 cananian 1.1 /* 0x2C */ "aload_2", 350 cananian 1.1 /* 0x2D */ "aload_3", 351 cananian 1.1 /* 0x2E */ "iaload", 352 cananian 1.1 /* 0x2F */ "laload", 353 cananian 1.1 /* 0x30 */ "faload", 354 cananian 1.1 /* 0x31 */ "daload", 355 cananian 1.1 /* 0x32 */ "aaload", 356 cananian 1.1 /* 0x33 */ "baload", 357 cananian 1.1 /* 0x34 */ "caload", 358 cananian 1.1 /* 0x35 */ "saload", 359 cananian 1.1 /* 0x36 */ "istore", 360 cananian 1.1 /* 0x37 */ "lstore", 361 cananian 1.1 /* 0x38 */ "fstore", 362 cananian 1.1 /* 0x39 */ "dstore", 363 cananian 1.1 /* 0x3A */ "astore", 364 cananian 1.1 /* 0x3B */ "istore_0", 365 cananian 1.1 /* 0x3C */ "istore_1", 366 cananian 1.1 /* 0x3D */ "istore_2", 367 cananian 1.1 /* 0x3E */ "istore_3", 368 cananian 1.1 /* 0x3F */ "lstore_0", 369 cananian 1.1 /* 0x40 */ "lstore_1", 370 cananian 1.1 /* 0x41 */ "lstore_2", 371 cananian 1.1 /* 0x42 */ "lstore_3", 372 cananian 1.1 /* 0x43 */ "fstore_0", 373 cananian 1.1 /* 0x44 */ "fstore_1", 374 cananian 1.1 /* 0x45 */ "fstore_2", 375 cananian 1.1 /* 0x46 */ "fstore_3", 376 cananian 1.1 /* 0x47 */ "dstore_0", 377 cananian 1.1 /* 0x48 */ "dstore_1", 378 cananian 1.1 /* 0x49 */ "dstore_2", 379 cananian 1.1 /* 0x4A */ "dstore_3", 380 cananian 1.1 /* 0x4B */ "astore_0", 381 cananian 1.1 /* 0x4C */ "astore_1", 382 cananian 1.1 /* 0x4D */ "astore_2", 383 cananian 1.1 /* 0x4E */ "astore_3", 384 cananian 1.1 /* 0x4F */ "iastore", 385 cananian 1.1 /* 0x50 */ "lastore", 386 cananian 1.1 /* 0x51 */ "fastore", 387 cananian 1.1 /* 0x52 */ "dastore", 388 cananian 1.1 /* 0x53 */ "aastore", 389 cananian 1.1 /* 0x54 */ "bastore", 390 cananian 1.1 /* 0x55 */ "castore", 391 cananian 1.1 /* 0x56 */ "sastore", 392 cananian 1.1 /* 0x57 */ "pop", 393 cananian 1.1 /* 0x58 */ "pop2", 394 cananian 1.1 /* 0x59 */ "dup", 395 cananian 1.1 /* 0x5A */ "dup_x1", 396 cananian 1.1 /* 0x5B */ "dup_x2", 397 cananian 1.1 /* 0x5C */ "dup2", 398 cananian 1.1 /* 0x5D */ "dup2_x1", 399 cananian 1.1 /* 0x5E */ "dup2_x2", 400 cananian 1.1 /* 0x5F */ "swap", 401 cananian 1.1 /* 0x60 */ "iadd", 402 cananian 1.1 /* 0x61 */ "ladd", 403 cananian 1.1 /* 0x62 */ "fadd", 404 cananian 1.1 /* 0x63 */ "dadd", 405 cananian 1.1 /* 0x64 */ "isub", 406 cananian 1.1 /* 0x65 */ "lsub", 407 cananian 1.1 /* 0x66 */ "fsub", 408 cananian 1.1 /* 0x67 */ "dsub", 409 cananian 1.1 /* 0x68 */ "imul", 410 cananian 1.1 /* 0x69 */ "lmul", 411 cananian 1.1 /* 0x6A */ "fmul", 412 cananian 1.1 /* 0x6B */ "dmul", 413 cananian 1.1 /* 0x6C */ "idiv", 414 cananian 1.1 /* 0x6D */ "ldiv", 415 cananian 1.1 /* 0x6E */ "fdiv", 416 cananian 1.1 /* 0x6F */ "ddiv", 417 cananian 1.1 /* 0x70 */ "irem", 418 cananian 1.1 /* 0x71 */ "lrem", 419 cananian 1.1 /* 0x72 */ "frem", 420 cananian 1.1 /* 0x73 */ "drem", 421 cananian 1.1 /* 0x74 */ "ineg", 422 cananian 1.1 /* 0x75 */ "lneg", 423 cananian 1.1 /* 0x76 */ "fneg", 424 cananian 1.1 /* 0x77 */ "dneg", 425 cananian 1.1 /* 0x78 */ "ishl", 426 cananian 1.1 /* 0x79 */ "lshl", 427 cananian 1.1 /* 0x7A */ "ishr", 428 cananian 1.1 /* 0x7B */ "lshr", 429 cananian 1.1 /* 0x7C */ "iushr", 430 cananian 1.1 /* 0x7D */ "lushr", 431 cananian 1.1 /* 0x7E */ "iand", 432 cananian 1.1 /* 0x7F */ "land", 433 cananian 1.1 /* 0x80 */ "ior", 434 cananian 1.1 /* 0x81 */ "lor", 435 cananian 1.1 /* 0x82 */ "ixor", 436 cananian 1.1 /* 0x83 */ "lxor", 437 cananian 1.1 /* 0x84 */ "iinc", 438 cananian 1.1 /* 0x85 */ "i2l", 439 cananian 1.1 /* 0x86 */ "i2f", 440 cananian 1.1 /* 0x87 */ "i2d", 441 cananian 1.1 /* 0x88 */ "l2i", 442 cananian 1.1 /* 0x89 */ "l2f", 443 cananian 1.1 /* 0x8A */ "l2d", 444 cananian 1.1 /* 0x8B */ "f2i", 445 cananian 1.1 /* 0x8C */ "f2l", 446 cananian 1.1 /* 0x8D */ "f2d", 447 cananian 1.1 /* 0x8E */ "d2i", 448 cananian 1.1 /* 0x8F */ "d2l", 449 cananian 1.1 /* 0x90 */ "d2f", 450 cananian 1.1 /* 0x91 */ "i2b", 451 cananian 1.1 /* 0x92 */ "i2c", 452 cananian 1.1 /* 0x93 */ "i2s", 453 cananian 1.1 /* 0x94 */ "lcmp", 454 cananian 1.1 /* 0x95 */ "fcmpl", 455 cananian 1.1 /* 0x96 */ "fcmpg", 456 cananian 1.1 /* 0x97 */ "dcmpl", 457 cananian 1.1 /* 0x98 */ "dcmpg", 458 cananian 1.1 /* 0x99 */ "ifeq", 459 cananian 1.1 /* 0x9A */ "ifne", 460 cananian 1.1 /* 0x9B */ "iflt", 461 cananian 1.1 /* 0x9C */ "ifge", 462 cananian 1.1 /* 0x9D */ "ifgt", 463 cananian 1.1 /* 0x9E */ "ifle", 464 cananian 1.1 /* 0x9F */ "if_icmpeq", 465 cananian 1.1 /* 0xA0 */ "if_icmpne", 466 cananian 1.1 /* 0xA1 */ "if_icmplt", 467 cananian 1.1 /* 0xA2 */ "if_icmpge", 468 cananian 1.1 /* 0xA3 */ "if_icmpgt", 469 cananian 1.1 /* 0xA4 */ "if_icmple", 470 cananian 1.1 /* 0xA5 */ "if_acmpeq", 471 cananian 1.1 /* 0xA6 */ "if_acmpne", 472 cananian 1.1 /* 0xA7 */ "goto", 473 cananian 1.1 /* 0xA8 */ "jsr", 474 cananian 1.1 /* 0xA9 */ "ret", 475 cananian 1.1 /* 0xAA */ "tableswitch", 476 cananian 1.1 /* 0xAB */ "lookupswitch", 477 cananian 1.1 /* 0xAC */ "ireturn", 478 cananian 1.1 /* 0xAD */ "lreturn", 479 cananian 1.1 /* 0xAE */ "freturn", 480 cananian 1.1 /* 0xAF */ "dreturn", 481 cananian 1.1 /* 0xB0 */ "areturn", 482 cananian 1.1 /* 0xB1 */ "return", 483 cananian 1.1 /* 0xB2 */ "getstatic", 484 cananian 1.1 /* 0xB3 */ "putstatic", 485 cananian 1.1 /* 0xB4 */ "getfield", 486 cananian 1.1 /* 0xB5 */ "putfield", 487 cananian 1.1 /* 0xB6 */ "invokevirtual", 488 cananian 1.1 /* 0xB7 */ "invokespecial", 489 cananian 1.1 /* 0xB8 */ "invokestatic", 490 cananian 1.1 /* 0xB9 */ "invokeinterface", 491 cananian 1.1 /* 0xBA */ "xxxunusedxxx", 492 cananian 1.1 /* 0xBB */ "new", 493 cananian 1.1 /* 0xBC */ "newarray", 494 cananian 1.1 /* 0xBD */ "anewarray", 495 cananian 1.1 /* 0xBE */ "arraylength", 496 cananian 1.1 /* 0xBF */ "athrow", 497 cananian 1.1 /* 0xC0 */ "checkcast", 498 cananian 1.1 /* 0xC1 */ "instanceof", 499 cananian 1.1 /* 0xC2 */ "monitorenter", 500 cananian 1.1 /* 0xC3 */ "monitorexit", 501 cananian 1.1 /* 0xC4 */ "wide", 502 cananian 1.1 /* 0xC5 */ "multianewarray", 503 cananian 1.1 /* 0xC6 */ "ifnull", 504 cananian 1.1 /* 0xC7 */ "ifnonnull", 505 cananian 1.1 /* 0xC8 */ "goto_w", 506 cananian 1.1 /* 0xC9 */ "jsr_w", 507 cananian 1.1 /* 0xCA */ "breakpoint", 508 cananian 1.1 /* 0xCB */ "ldc_quick", 509 cananian 1.1 /* 0xCC */ "ldc_w_quick", 510 cananian 1.1 /* 0xCD */ "ldc2_w_quick", 511 cananian 1.1 /* 0xCE */ "getfield_quick", 512 cananian 1.1 /* 0xCF */ "putfield_quick", 513 cananian 1.1 /* 0xD0 */ "getfield2_quick", 514 cananian 1.1 /* 0xD1 */ "putfield2_quick", 515 cananian 1.1 /* 0xD2 */ "getstatic_quick", 516 cananian 1.1 /* 0xD3 */ "putstatic_quick", 517 cananian 1.1 /* 0xD4 */ "getstatic2_quick", 518 cananian 1.1 /* 0xD5 */ "putstatic2_quick", 519 cananian 1.1 /* 0xD6 */ "invokevirtual_quick", 520 cananian 1.1 /* 0xD7 */ "invokenonvirtual_quick", 521 cananian 1.1 /* 0xD8 */ "invokesuper_quick", 522 cananian 1.1 /* 0xD9 */ "invokestatic_quick", 523 cananian 1.1 /* 0xDA */ "invokeinterface_quick", 524 cananian 1.1 /* 0xDB */ "invokevirtualobject_quick", 525 cananian 1.1 /* 0xDC */ "unknown_dc", 526 cananian 1.1 /* 0xDD */ "new_quick", 527 cananian 1.1 /* 0xDE */ "anewarray_quick", 528 cananian 1.1 /* 0xDF */ "multianewarray_quick", 529 cananian 1.1 /* 0xE0 */ "checkcast_quick", 530 cananian 1.1 /* 0xE1 */ "instanceof_quick", 531 cananian 1.1 /* 0xE2 */ "invokevirtual_quick_w", 532 cananian 1.1 /* 0xE3 */ "getfield_quick_w", 533 cananian 1.1 /* 0xE4 */ "putfield_quick_w", 534 cananian 1.1 /* 0xE5 */ "unknown_e5", 535 cananian 1.1 /* 0xE6 */ "unknown_e6", 536 cananian 1.1 /* 0xE7 */ "unknown_e7", 537 cananian 1.1 /* 0xE8 */ "unknown_e8", 538 cananian 1.1 /* 0xE9 */ "unknown_e9", 539 cananian 1.1 /* 0xEA */ "unknown_ea", 540 cananian 1.1 /* 0xEB */ "unknown_eb", 541 cananian 1.1 /* 0xEC */ "unknown_ec", 542 cananian 1.1 /* 0xED */ "unknown_ed", 543 cananian 1.1 /* 0xEE */ "unknown_ee", 544 cananian 1.1 /* 0xEF */ "unknown_ef", 545 cananian 1.1 /* 0xF0 */ "unknown_f0", 546 cananian 1.1 /* 0xF1 */ "unknown_f1", 547 cananian 1.1 /* 0xF2 */ "unknown_f2", 548 cananian 1.1 /* 0xF3 */ "unknown_f3", 549 cananian 1.1 /* 0xF4 */ "unknown_f4", 550 cananian 1.1 /* 0xF5 */ "unknown_f5", 551 cananian 1.1 /* 0xF6 */ "unknown_f6", 552 cananian 1.1 /* 0xF7 */ "unknown_f7", 553 cananian 1.1 /* 0xF8 */ "unknown_f8", 554 cananian 1.1 /* 0xF9 */ "unknown_f9", 555 cananian 1.1 /* 0xFA */ "unknown_fa", 556 cananian 1.1 /* 0xFB */ "unknown_fb", 557 cananian 1.1 /* 0xFC */ "unknown_fc", 558 cananian 1.1 /* 0xFD */ "unknown_fd", 559 cananian 1.1 /* 0xFE */ "impdep1", 560 cananian 1.1 /* 0xFF */ "impdep2" 561 cananian 1.1 }; 562 cananian 1.1 563 cananian 1.1 // Set up table indicating instruction length for each opcode. 564 cananian 1.1 private static byte offset[] = new byte[256]; 565 cananian 1.1 static { 566 cananian 1.1 for (int i=0; i<offset.length; i++) offset[i]=0; 567 cananian 1.1 offset[ub2i(BIPUSH)] = 1; 568 cananian 1.1 offset[ub2i(SIPUSH)] = 2; 569 cananian 1.1 offset[ub2i(LDC)] = 1; 570 cananian 1.1 offset[ub2i(LDC_W)] = 2; 571 cananian 1.1 offset[ub2i(LDC2_W)] = 2; 572 cananian 1.1 for (int i=ub2i(ILOAD); i<=ub2i(ALOAD); i++) offset[i]=1; 573 cananian 1.1 for (int i=ub2i(ISTORE);i<=ub2i(ASTORE);i++) offset[i]=1; 574 cananian 1.1 offset[ub2i(IINC)] = 2; 575 cananian 1.1 for (int i=ub2i(IFEQ); i<=ub2i(JSR); i++) offset[i]=2; 576 cananian 1.1 offset[ub2i(RET)] = 1; 577 cananian 1.1 // TABLESWITCH and LOOKUPSWITCH are highly irregular. 578 cananian 1.1 for (int i=ub2i(GETSTATIC); i<=ub2i(INVOKESTATIC); i++) offset[i]=2; 579 cananian 1.1 offset[ub2i(INVOKEINTERFACE)] = 4; 580 cananian 1.1 offset[ub2i(NEW)] = 2; 581 cananian 1.1 offset[ub2i(NEWARRAY)] = 1; 582 cananian 1.1 offset[ub2i(ANEWARRAY)]= 2; 583 cananian 1.1 offset[ub2i(CHECKCAST)]= 2; 584 cananian 1.1 offset[ub2i(INSTANCEOF)]=2; 585 cananian 1.1 // WIDE is irregular. 586 cananian 1.1 offset[ub2i(MULTIANEWARRAY)] = 3; 587 cananian 1.1 offset[ub2i(IFNULL)] = 2; 588 cananian 1.1 offset[ub2i(IFNONNULL)]= 2; 589 cananian 1.1 offset[ub2i(GOTO_W)] = 4; 590 cananian 1.1 offset[ub2i(JSR_W)] = 4; 591 cananian 1.1 } 592 cananian 1.1 593 cananian 1.1 /** 594 cananian 1.1 * Gives the length of the instruction at the specified offset in a 595 cananian 1.1 * bytecode array. 596 cananian 1.1 * <P> 597 cananian 1.1 * The length is the number of operand bytes plus 1 byte for the opcode. 598 cananian 1.1 * @param code the bytecode array. 599 cananian 1.1 * @param pc the offset into the array where the opcode of interest is 600 cananian 1.1 * located. 601 cananian 1.1 * @return the length of the opcode and operands. 602 cananian 1.1 */ 603 cananian 1.1 public final static int instrSize(byte[] code, int pc) { 604 cananian 1.1 byte opcode = code[pc]; 605 cananian 1.1 switch(opcode) { 606 cananian 1.1 case LOOKUPSWITCH: 607 cananian 1.1 { 608 cananian 1.1 int pad = 3-(pc%4); 609 cananian 1.3.2.2 long npairs = make_s4(code, pc+pad+5); 610 cananian 1.5.2.1 assert npairs>=0; 611 cananian 1.1 return (int) (npairs*8) + pad + 9; 612 cananian 1.1 } 613 cananian 1.1 case TABLESWITCH: 614 cananian 1.1 { 615 cananian 1.1 int pad = 3-(pc%4); 616 cananian 1.3.2.2 long low = make_s4(code, pc+pad+5); 617 cananian 1.3.2.2 long high= make_s4(code, pc+pad+9); 618 cananian 1.1 long npairs = high - low + 1; 619 cananian 1.5.2.1 assert low <= high; 620 cananian 1.1 return (int) (npairs*4) + pad + 13; 621 cananian 1.1 } 622 cananian 1.1 case WIDE: 623 cananian 1.1 if (code[pc+1]==IINC) return 6; 624 cananian 1.1 return 4; 625 cananian 1.1 default: 626 cananian 1.1 return 1+offset[ub2i(opcode)]; 627 cananian 1.1 } 628 cananian 1.1 } 629 cananian 1.1 630 cananian 1.1 // Set up table to determine whether an opcode is a branch instruction. 631 cananian 1.1 private static boolean isBranch[] = new boolean[256]; 632 cananian 1.1 static { 633 cananian 1.1 for (int i=0; i<isBranch.length; i++) isBranch[i]=false; 634 cananian 1.1 for (int i=ub2i(IFEQ); i<=ub2i(RETURN); i++) isBranch[i]=true; 635 cananian 1.1 for (int i=ub2i(IFNULL); i<=ub2i(JSR_W); i++) isBranch[i]=true; 636 cananian 1.1 isBranch[ub2i(ATHROW)]=true; 637 cananian 1.1 } 638 cananian 1.1 639 cananian 1.1 /** 640 cananian 1.1 * Tells whether a given opcode is a branch instruction. 641 cananian 1.1 * @param opcode the opcode to check. 642 cananian 1.1 * @return true if the opcode is a branch instruction. 643 cananian 1.1 */ 644 cananian 1.1 public final static boolean isBranch(byte opcode) { 645 cananian 1.1 return isBranch[ub2i(opcode)]; 646 cananian 1.1 } 647 cananian 1.1 648 cananian 1.1 /** 649 cananian 1.1 * Tells whether a given opcode is an unconditional branch instruction. 650 cananian 1.1 * @param opcode the opcode to check. 651 cananian 1.1 * @return true if the opcode is an unconditional branch instruction. 652 cananian 1.1 */ 653 cananian 1.1 public final static boolean isUnconditionalBranch(byte opcode) { 654 cananian 1.1 switch(opcode) { 655 cananian 1.1 case GOTO: 656 cananian 1.1 case GOTO_W: 657 cananian 1.1 case JSR: 658 cananian 1.1 case JSR_W: 659 cananian 1.1 case RET: 660 cananian 1.1 case IRETURN: 661 cananian 1.1 case LRETURN: 662 cananian 1.1 case FRETURN: 663 cananian 1.1 case DRETURN: 664 cananian 1.1 case ARETURN: 665 cananian 1.1 case RETURN: 666 cananian 1.1 case ATHROW: 667 cananian 1.1 case LOOKUPSWITCH: 668 cananian 1.1 case TABLESWITCH: 669 cananian 1.1 return true; 670 cananian 1.1 default: 671 cananian 1.1 return false; 672 cananian 1.1 } 673 cananian 1.1 } 674 cananian 1.1 675 cananian 1.1 /** 676 cananian 1.1 * Tells whether a given opcode is a jump to subrouting (JSR) instruction. 677 cananian 1.1 * @param opcode the opcode to check. 678 cananian 1.1 * @return true if the opcode is a JSR or JSR_W instruction. 679 cananian 1.1 */ 680 cananian 1.1 public final static boolean isJSR(byte opcode) { 681 cananian 1.1 if (opcode == JSR) return true; 682 cananian 1.1 if (opcode == JSR_W) return true; 683 cananian 1.1 return false; 684 cananian 1.1 } 685 cananian 1.1 686 cananian 1.1 /** 687 cananian 1.1 * Computes all possible targets for a branch instruction. 688 cananian 1.1 * @exception Error if the opcode is not a branch instruction. 689 cananian 1.1 * @param code the bytecode array. 690 cananian 1.1 * @param pc the offset into the bytecode array at which the desired 691 cananian 1.1 * instruction is found. 692 cananian 1.1 * @return an array of all possible targets, in the same format as 693 cananian 1.1 * <code>pc</code>. (ie, offsets from the start of the 694 cananian 1.1 * bytecode array.) 695 cananian 1.1 */ 696 cananian 1.1 public final static int[] branchTargets(byte[] code, int pc) { 697 cananian 1.1 if (!isBranch(code[pc])) 698 cananian 1.1 throw new Error("Asking for target of non-branch."); 699 cananian 1.1 // Funky switch statements. 700 cananian 1.1 if (code[pc]==LOOKUPSWITCH) { 701 cananian 1.1 int pad = 3-(pc%4); 702 cananian 1.3.2.2 long deflt = make_s4(code, pc+pad+1); 703 cananian 1.3.2.2 long npairs = make_s4(code, pc+pad+5); 704 cananian 1.5.2.1 assert npairs >= 0; 705 cananian 1.1 706 cananian 1.1 int result[] = new int[(int)npairs+1]; 707 cananian 1.1 result[0] = pc + ((int) deflt); 708 cananian 1.1 for (int i=0; i<npairs; i++) { 709 cananian 1.3.2.2 long offset = make_s4(code, pc+pad+9+4+(8*i)); 710 cananian 1.1 result[i+1] = pc + ((int) offset); 711 cananian 1.1 } 712 cananian 1.1 return result; 713 cananian 1.1 } 714 cananian 1.1 if (code[pc]==TABLESWITCH) { 715 cananian 1.1 int pad = 3-(pc%4); 716 cananian 1.3.2.2 long deflt = make_s4(code, pc+pad+1); 717 cananian 1.3.2.2 long low = make_s4(code, pc+pad+5); 718 cananian 1.3.2.2 long high = make_s4(code, pc+pad+9); 719 cananian 1.1 long npairs = high - low + 1; 720 cananian 1.5.2.1 assert low <= high; 721 cananian 1.1 722 cananian 1.1 int result[] = new int[(int)npairs+1]; 723 cananian 1.1 result[0] = pc + ((int) deflt); 724 cananian 1.1 for (int i=0; i<npairs; i++) { 725 cananian 1.3.2.2 long offset = make_s4(code, pc+pad+13+(4*i)); 726 cananian 1.1 result[i+1] = pc + ((int) offset); 727 cananian 1.1 } 728 cananian 1.1 return result; 729 cananian 1.1 } 730 cananian 1.1 // Wide goto and jsr. 731 cananian 1.1 if (code[pc]==GOTO_W || code[pc]==JSR_W) { 732 cananian 1.3.2.2 long offset = make_s4(code, pc+1); 733 cananian 1.1 int result[] = new int[1]; 734 cananian 1.1 result[0] = pc + ((int)offset); 735 cananian 1.1 return result; 736 cananian 1.1 } 737 cananian 1.1 // ret/return/throw (no targets) 738 cananian 1.1 if (code[pc]==RET || code[pc]==RETURN || 739 cananian 1.1 code[pc]==IRETURN || code[pc]==LRETURN || 740 cananian 1.1 code[pc]==FRETURN || code[pc]==DRETURN || 741 cananian 1.1 code[pc]==ARETURN || code[pc]==ATHROW ) 742 cananian 1.1 return new int[0]; 743 cananian 1.1 // all other cases: 744 cananian 1.1 { 745 cananian 1.1 short offset = (short) ((ub2i(code[pc+1]) << 8) | ub2i(code[pc+2])); 746 cananian 1.1 int result[] = new int[1]; 747 cananian 1.1 result[0] = pc+offset; 748 cananian 1.1 return result; 749 cananian 1.1 } 750 cananian 1.1 } 751 cananian 1.1 752 cananian 1.1 // Helper functions. 753 cananian 1.1 private static final long make_u4(byte[] b, int off) { 754 cananian 1.3.2.2 return make4(false, b[off], b[off+1], b[off+2], b[off+3]); 755 cananian 1.1 } 756 cananian 1.3.2.2 private static final long make_s4(byte[] b, int off) { 757 cananian 1.3.2.2 return make4(true, b[off], b[off+1], b[off+2], b[off+3]); 758 cananian 1.3.2.2 } 759 cananian 1.3.2.2 private static final long make4(boolean signed, 760 cananian 1.3.2.2 byte b1, byte b2, byte b3, byte b4) { 761 cananian 1.3.2.2 long l1 = ((long) b1); // keep sign bits on msb. 762 cananian 1.1 long l2 = ((long) b2) & 0xFF; 763 cananian 1.1 long l3 = ((long) b3) & 0xFF; 764 cananian 1.1 long l4 = ((long) b4) & 0xFF; 765 cananian 1.3.2.2 if (!signed) l1 &= 0xFF; 766 cananian 1.1 return (l1<<24)|(l2<<16)|(l3<<8)|l4; 767 cananian 1.1 } 768 cananian 1.1 /** Make an unsigned byte into an integer. */ 769 cananian 1.1 private static int ub2i(byte b) { 770 cananian 1.1 return ((int) b) & 0xFF; 771 cananian 1.1 } 772 cananian 1.1 }