private static String lookupSwitch(CodeIterator iter, int pos) { StringBuffer buffer = new StringBuffer("lookupswitch {\n"); int index = (pos & ~3) + 4; // default buffer.append("\t\tdefault: ").append(pos + iter.s32bitAt(index)).append("\n"); int npairs = iter.s32bitAt(index += 4); int end = npairs * 8 + (index += 4); for (; index < end; index += 8) { int match = iter.s32bitAt(index); int target = iter.s32bitAt(index + 4) + pos; buffer.append("\t\t").append(match).append(": ").append(target).append("\n"); } buffer.setCharAt(buffer.length() - 1, '}'); return buffer.toString(); }
private static String tableSwitch(CodeIterator iter, int pos) { StringBuffer buffer = new StringBuffer("tableswitch {\n"); int index = (pos & ~3) + 4; // default buffer.append("\t\tdefault: ").append(pos + iter.s32bitAt(index)).append("\n"); int low = iter.s32bitAt(index += 4); int high = iter.s32bitAt(index += 4); int end = (high - low + 1) * 4 + (index += 4); // Offset table for (int key = low; index < end; index += 4, key++) { int target = iter.s32bitAt(index) + pos; buffer.append("\t\t").append(key).append(": ").append(target).append("\n"); } buffer.setCharAt(buffer.length() - 1, '}'); return buffer.toString(); }
/** Gets a string representation of the bytecode instruction at the specified position. */ public static String instructionString(CodeIterator iter, int pos, ConstPool pool) { int opcode = iter.byteAt(pos); if (opcode > opcodes.length || opcode < 0) throw new IllegalArgumentException("Invalid opcode, opcode: " + opcode + " pos: " + pos); String opstring = opcodes[opcode]; switch (opcode) { case BIPUSH: return opstring + " " + iter.byteAt(pos + 1); case SIPUSH: return opstring + " " + iter.s16bitAt(pos + 1); case LDC: return opstring + " " + ldc(pool, iter.byteAt(pos + 1)); case LDC_W: case LDC2_W: return opstring + " " + ldc(pool, iter.u16bitAt(pos + 1)); case ILOAD: case LLOAD: case FLOAD: case DLOAD: case ALOAD: case ISTORE: case LSTORE: case FSTORE: case DSTORE: case ASTORE: return opstring + " " + iter.byteAt(pos + 1); case IFEQ: case IFGE: case IFGT: case IFLE: case IFLT: case IFNE: case IFNONNULL: case IFNULL: case IF_ACMPEQ: case IF_ACMPNE: case IF_ICMPEQ: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ICMPLT: case IF_ICMPNE: return opstring + " " + (iter.s16bitAt(pos + 1) + pos); case IINC: return opstring + " " + iter.byteAt(pos + 1); case GOTO: case JSR: return opstring + " " + (iter.s16bitAt(pos + 1) + pos); case RET: return opstring + " " + iter.byteAt(pos + 1); case TABLESWITCH: return tableSwitch(iter, pos); case LOOKUPSWITCH: return lookupSwitch(iter, pos); case GETSTATIC: case PUTSTATIC: case GETFIELD: case PUTFIELD: return opstring + " " + fieldInfo(pool, iter.u16bitAt(pos + 1)); case INVOKEVIRTUAL: case INVOKESPECIAL: case INVOKESTATIC: return opstring + " " + methodInfo(pool, iter.u16bitAt(pos + 1)); case INVOKEINTERFACE: return opstring + " " + interfaceMethodInfo(pool, iter.u16bitAt(pos + 1)); case INVOKEDYNAMIC: return opstring + " " + iter.u16bitAt(pos + 1); case NEW: return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1)); case NEWARRAY: return opstring + " " + arrayInfo(iter.byteAt(pos + 1)); case ANEWARRAY: case CHECKCAST: return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1)); case WIDE: return wide(iter, pos); case MULTIANEWARRAY: return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1)); case GOTO_W: case JSR_W: return opstring + " " + (iter.s32bitAt(pos + 1) + pos); default: return opstring; } }