169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba, and others. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode;
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.PrintStream;
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtMethod;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Simple utility class for printing the instructions of a method.
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author Jason T. Greene
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class InstructionPrinter implements Opcode {
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final static String opcodes[] = Mnemonic.OPCODE;
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final PrintStream stream;
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public InstructionPrinter(PrintStream stream) {
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.stream = stream;
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static void print(CtMethod method, PrintStream stream) {
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        (new InstructionPrinter(stream)).print(method);
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void print(CtMethod method) {
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        MethodInfo info = method.getMethodInfo2();
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ConstPool pool = info.getConstPool();
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CodeAttribute code = info.getCodeAttribute();
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (code == null)
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return;
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CodeIterator iterator = code.iterator();
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (iterator.hasNext()) {
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int pos;
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                pos = iterator.next();
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            } catch (BadBytecode e) {
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException(e);
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stream.println(pos + ": " + instructionString(iterator, pos, pool));
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static String instructionString(CodeIterator iter, int pos, ConstPool pool) {
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int opcode = iter.byteAt(pos);
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode > opcodes.length || opcode < 0)
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new IllegalArgumentException("Invalid opcode, opcode: " + opcode + " pos: "+ pos);
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String opstring = opcodes[opcode];
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (opcode) {
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case BIPUSH:
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + iter.byteAt(pos + 1);
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case SIPUSH:
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + iter.s16bitAt(pos + 1);
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LDC:
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + ldc(pool, iter.byteAt(pos + 1));
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LDC_W :
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LDC2_W :
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + ldc(pool, iter.u16bitAt(pos + 1));
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ILOAD:
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LLOAD:
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FLOAD:
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DLOAD:
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ALOAD:
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISTORE:
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSTORE:
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSTORE:
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSTORE:
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ASTORE:
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + iter.byteAt(pos + 1);
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFEQ:
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFGE:
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFGT:
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFLE:
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFLT:
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFNE:
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFNONNULL:
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFNULL:
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ACMPEQ:
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ACMPNE:
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPEQ:
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPGE:
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPGT:
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPLE:
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPLT:
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPNE:
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + (iter.s16bitAt(pos + 1) + pos);
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IINC:
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + iter.byteAt(pos + 1);
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case GOTO:
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case JSR:
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + (iter.s16bitAt(pos + 1) + pos);
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case RET:
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + iter.byteAt(pos + 1);
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case TABLESWITCH:
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return tableSwitch(iter, pos);
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LOOKUPSWITCH:
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return lookupSwitch(iter, pos);
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case GETSTATIC:
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case PUTSTATIC:
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case GETFIELD:
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case PUTFIELD:
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + fieldInfo(pool, iter.u16bitAt(pos + 1));
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INVOKEVIRTUAL:
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INVOKESPECIAL:
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INVOKESTATIC:
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + methodInfo(pool, iter.u16bitAt(pos + 1));
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INVOKEINTERFACE:
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + interfaceMethodInfo(pool, iter.u16bitAt(pos + 1));
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case 186:
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException("Bad opcode 186");
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case NEW:
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1));
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case NEWARRAY:
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + arrayInfo(iter.byteAt(pos + 1));
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ANEWARRAY:
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case CHECKCAST:
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1));
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case WIDE:
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return wide(iter, pos);
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case MULTIANEWARRAY:
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + classInfo(pool, iter.u16bitAt(pos + 1));
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case GOTO_W:
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case JSR_W:
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring + " " + (iter.s32bitAt(pos + 1)+ pos);
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            default:
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opstring;
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String wide(CodeIterator iter, int pos) {
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int opcode = iter.byteAt(pos + 1);
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = iter.u16bitAt(pos + 2);
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (opcode) {
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ILOAD:
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LLOAD:
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FLOAD:
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DLOAD:
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ALOAD:
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISTORE:
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSTORE:
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSTORE:
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSTORE:
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ASTORE:
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IINC:
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case RET:
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return opcodes[opcode] + " " + index;
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            default:
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException("Invalid WIDE operand");
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String arrayInfo(int type) {
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (type) {
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_BOOLEAN:
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "boolean";
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_CHAR:
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "char";
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_BYTE:
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "byte";
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_SHORT:
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "short";
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_INT:
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "int";
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_LONG:
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "long";
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_FLOAT:
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "float";
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_DOUBLE:
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "double";
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            default:
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException("Invalid array type");
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String classInfo(ConstPool pool, int index) {
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return "#" + index + " = Class " + pool.getClassInfo(index);
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String interfaceMethodInfo(ConstPool pool, int index) {
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return "#" + index + " = Method "
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                + pool.getInterfaceMethodrefClassName(index) + "."
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                + pool.getInterfaceMethodrefName(index) + "("
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                + pool.getInterfaceMethodrefType(index) + ")";
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String methodInfo(ConstPool pool, int index) {
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return "#" + index + " = Method "
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                + pool.getMethodrefClassName(index) + "."
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                + pool.getMethodrefName(index) + "("
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                + pool.getMethodrefType(index) + ")";
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String fieldInfo(ConstPool pool, int index) {
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return "#" + index + " = Field "
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            + pool.getFieldrefClassName(index) + "."
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            + pool.getFieldrefName(index) + "("
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            + pool.getFieldrefType(index) + ")";
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String lookupSwitch(CodeIterator iter, int pos) {
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        StringBuffer buffer = new StringBuffer("lookupswitch {\n");
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = (pos & ~3) + 4;
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // default
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        buffer.append("\t\tdefault: ").append(pos + iter.s32bitAt(index)).append("\n");
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int npairs = iter.s32bitAt(index += 4);
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int end = npairs * 8 + (index += 4);
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (; index < end; index += 8) {
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int match = iter.s32bitAt(index);
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int target = iter.s32bitAt(index + 4) + pos;
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            buffer.append("\t\t").append(match).append(": ").append(target).append("\n");
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        buffer.setCharAt(buffer.length() - 1, '}');
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return buffer.toString();
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String tableSwitch(CodeIterator iter, int pos) {
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        StringBuffer buffer = new StringBuffer("tableswitch {\n");
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = (pos & ~3) + 4;
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // default
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        buffer.append("\t\tdefault: ").append(pos + iter.s32bitAt(index)).append("\n");
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int low = iter.s32bitAt(index += 4);
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int high = iter.s32bitAt(index += 4);
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int end = (high - low + 1) * 4 + (index += 4);
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // Offset table
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int key = low; index < end; index += 4, key++) {
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int target = iter.s32bitAt(index) + pos;
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            buffer.append("\t\t").append(key).append(": ").append(target).append("\n");
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        buffer.setCharAt(buffer.length() - 1, '}');
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return buffer.toString();
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String ldc(ConstPool pool, int index) {
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int tag = pool.getTag(index);
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (tag) {
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ConstPool.CONST_String:
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "#" + index + " = \"" + pool.getStringInfo(index) + "\"";
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ConstPool.CONST_Integer:
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "#" + index + " = int " + pool.getIntegerInfo(index);
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ConstPool.CONST_Float:
27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "#" + index + " = float " + pool.getFloatInfo(index);
27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ConstPool.CONST_Long:
27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "#" + index + " = long " + pool.getLongInfo(index);
27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ConstPool.CONST_Double:
27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "#" + index + " = int " + pool.getDoubleInfo(index);
27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ConstPool.CONST_Class:
27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return classInfo(pool, index);
27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            default:
27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException("bad LDC: " + tag);
27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
282