169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. 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 Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode.stackmap;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.ByteArray;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.Opcode;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.ConstPool;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.Descriptor;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.BadBytecode;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool;
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A class for performing abstract interpretation.
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * See also MapMaker class.
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic abstract class Tracer implements TypeTag {
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected ClassPool classPool;
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected ConstPool cpool;
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected String returnType;
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected int stackTop;
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected TypeData[] stackTypes;
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected TypeData[] localsTypes;
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Tracer(ClassPool classes, ConstPool cp, int maxStack, int maxLocals,
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                  String retType) {
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classPool = classes;
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cpool = cp;
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        returnType = retType;
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTop = 0;
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTypes = new TypeData[maxStack];
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        localsTypes = new TypeData[maxLocals];
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Tracer(Tracer t, boolean copyStack) {
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classPool = t.classPool;
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cpool = t.cpool;
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        returnType = t.returnType;
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTop = t.stackTop;
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int size = t.stackTypes.length;
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTypes = new TypeData[size];
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (copyStack)
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            copyFrom(t.stackTop, t.stackTypes, stackTypes);
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int size2 = t.localsTypes.length;
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        localsTypes = new TypeData[size2];
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        copyFrom(size2, t.localsTypes, localsTypes);
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected static int copyFrom(int n, TypeData[] srcTypes, TypeData[] destTypes) {
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int k = -1;
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int i = 0; i < n; i++) {
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData t = srcTypes[i];
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            destTypes[i] = t == TOP ? TOP : t.getSelf();
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (t != TOP)
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (t.is2WordType())
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    k = i + 1;
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    k = i;
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return k + 1;
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Does abstract interpretation on the given bytecode instruction.
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * It records whether or not a local variable (i.e. register) is accessed.
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If the instruction requires that a local variable or
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * a stack element has a more specific type, this method updates the
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * type of it.
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param pos         the position of the instruction.
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return      the size of the instruction at POS.
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected int doOpcode(int pos, byte[] code) throws BadBytecode {
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int op = code[pos] & 0xff;
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (op < 96)
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (op < 54)
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return doOpcode0_53(pos, code, op);
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return doOpcode54_95(pos, code, op);
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (op < 148)
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return doOpcode96_147(pos, code, op);
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return doOpcode148_201(pos, code, op);
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (ArrayIndexOutOfBoundsException e) {
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("inconsistent stack height " + e.getMessage());
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void visitBranch(int pos, byte[] code, int offset) throws BadBytecode {}
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void visitGoto(int pos, byte[] code, int offset) throws BadBytecode {}
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void visitReturn(int pos, byte[] code) throws BadBytecode {}
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void visitThrow(int pos, byte[] code) throws BadBytecode {}
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param pos           the position of TABLESWITCH
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param code          bytecode
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param n             the number of case labels
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param offsetPos     the position of the branch-target table.
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param defaultOffset     the offset to the default branch target.
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void visitTableSwitch(int pos, byte[] code, int n,
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int offsetPos, int defaultOffset) throws BadBytecode {}
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param pos           the position of LOOKUPSWITCH
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param code          bytecode
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param n             the number of case labels
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param offsetPos     the position of the table of pairs of a value and a branch target.
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param defaultOffset     the offset to the default branch target.
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void visitLookupSwitch(int pos, byte[] code, int n,
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int pairsPos, int defaultOffset) throws BadBytecode {}
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Invoked when the visited instruction is jsr.
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Java6 or later does not allow using RET.
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void visitJSR(int pos, byte[] code) throws BadBytecode {
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        /* Since JSR pushes a return address onto the operand stack,
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * the stack map at the entry point of a subroutine is
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * stackTypes resulting after executing the following code:
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         *
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         *     stackTypes[stackTop++] = TOP;
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         */
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Invoked when the visited instruction is ret or wide ret.
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Java6 or later does not allow using RET.
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void visitRET(int pos, byte[] code) throws BadBytecode {}
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doOpcode0_53(int pos, byte[] code, int op) throws BadBytecode {
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int reg;
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        TypeData[] stackTypes = this.stackTypes;
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (op) {
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.NOP :
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ACONST_NULL :
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = new TypeData.NullType();
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ICONST_M1 :
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ICONST_0 :
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ICONST_1 :
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ICONST_2 :
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ICONST_3 :
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ICONST_4 :
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ICONST_5 :
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = INTEGER;
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LCONST_0 :
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LCONST_1 :
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = LONG;
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = TOP;
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FCONST_0 :
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FCONST_1 :
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FCONST_2 :
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = FLOAT;
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DCONST_0 :
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DCONST_1 :
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = DOUBLE;
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = TOP;
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.BIPUSH :
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.SIPUSH :
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = INTEGER;
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return op == Opcode.SIPUSH ? 3 : 2;
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LDC :
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doLDC(code[pos + 1] & 0xff);
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 2;
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LDC_W :
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LDC2_W :
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doLDC(ByteArray.readU16bit(code, pos + 1));
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3;
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ILOAD :
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doXLOAD(INTEGER, code, pos);
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LLOAD :
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doXLOAD(LONG, code, pos);
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FLOAD :
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doXLOAD(FLOAT, code, pos);
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DLOAD :
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doXLOAD(DOUBLE, code, pos);
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ALOAD :
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doALOAD(code[pos + 1] & 0xff);
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ILOAD_0 :
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ILOAD_1 :
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ILOAD_2 :
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ILOAD_3 :
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = INTEGER;
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LLOAD_0 :
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LLOAD_1 :
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LLOAD_2 :
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LLOAD_3 :
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = LONG;
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = TOP;
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FLOAD_0 :
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FLOAD_1 :
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FLOAD_2 :
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FLOAD_3 :
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = FLOAT;
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DLOAD_0 :
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DLOAD_1 :
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DLOAD_2 :
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DLOAD_3 :
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = DOUBLE;
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = TOP;
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ALOAD_0 :
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ALOAD_1 :
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ALOAD_2 :
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ALOAD_3 :
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            reg = op - Opcode.ALOAD_0;
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = localsTypes[reg];
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IALOAD :
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[--stackTop - 1] = INTEGER;
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LALOAD :
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 2] = LONG;
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = TOP;
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FALOAD :
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[--stackTop - 1] = FLOAT;
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DALOAD :
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 2] = DOUBLE;
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = TOP;
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.AALOAD : {
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int s = --stackTop - 1;
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData data = stackTypes[s];
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (data == null || !data.isObjectType())
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new BadBytecode("bad AALOAD");
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                stackTypes[s] = new TypeData.ArrayElement(data);
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break; }
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.BALOAD :
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.CALOAD :
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.SALOAD :
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[--stackTop - 1] = INTEGER;
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default :
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("fatal");
27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 1;
27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void doLDC(int index) {
27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        TypeData[] stackTypes = this.stackTypes;
27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int tag = cpool.getTag(index);
27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (tag == ConstPool.CONST_String)
27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = new TypeData.ClassName("java.lang.String");
28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (tag == ConstPool.CONST_Integer)
28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = INTEGER;
28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (tag == ConstPool.CONST_Float)
28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = FLOAT;
28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (tag == ConstPool.CONST_Long) {
28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = LONG;
28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = TOP;
28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (tag == ConstPool.CONST_Double) {
28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = DOUBLE;
29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = TOP;
29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (tag == ConstPool.CONST_Class)
29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = new TypeData.ClassName("java.lang.Class");
29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("bad LDC: " + tag);
29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doXLOAD(TypeData type, byte[] code, int pos) {
29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int localVar = code[pos + 1] & 0xff;
30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return doXLOAD(localVar, type);
30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doXLOAD(int localVar, TypeData type) {
30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTypes[stackTop++] = type;
30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (type.is2WordType())
30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = TOP;
30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 2;
30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doALOAD(int localVar) { // int localVar, TypeData type) {
31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTypes[stackTop++] = localsTypes[localVar];
31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 2;
31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doOpcode54_95(int pos, byte[] code, int op) throws BadBytecode {
31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        TypeData[] localsTypes = this.localsTypes;
31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        TypeData[] stackTypes = this.stackTypes;
31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (op) {
32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ISTORE :
32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doXSTORE(pos, code, INTEGER);
32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LSTORE :
32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doXSTORE(pos, code, LONG);
32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FSTORE :
32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doXSTORE(pos, code, FLOAT);
32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DSTORE :
32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doXSTORE(pos, code, DOUBLE);
32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ASTORE :
32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doASTORE(code[pos + 1] & 0xff);
33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ISTORE_0 :
33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ISTORE_1 :
33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ISTORE_2 :
33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ISTORE_3 :
33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal          { int var = op - Opcode.ISTORE_0;
33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            localsTypes[var] = INTEGER;
33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--; }
33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LSTORE_0 :
33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LSTORE_1 :
34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LSTORE_2 :
34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LSTORE_3 :
34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal          { int var = op - Opcode.LSTORE_0;
34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            localsTypes[var] = LONG;
34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            localsTypes[var + 1] = TOP;
34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 2; }
34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FSTORE_0 :
34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FSTORE_1 :
34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FSTORE_2 :
35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FSTORE_3 :
35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal          { int var = op - Opcode.FSTORE_0;
35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            localsTypes[var] = FLOAT;
35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--; }
35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DSTORE_0 :
35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DSTORE_1 :
35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DSTORE_2 :
35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DSTORE_3 :
35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal          { int var = op - Opcode.DSTORE_0;
36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            localsTypes[var] = DOUBLE;
36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            localsTypes[var + 1] = TOP;
36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 2; }
36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ASTORE_0 :
36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ASTORE_1 :
36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ASTORE_2 :
36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ASTORE_3 :
36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal          { int var = op - Opcode.ASTORE_0;
36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doASTORE(var);
37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break; }
37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IASTORE :
37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LASTORE :
37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FASTORE :
37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DASTORE :
37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= (op == Opcode.LASTORE || op == Opcode.DASTORE) ? 4 : 3;
37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.AASTORE :
37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[stackTop - 1],
37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                             TypeData.ArrayElement.getElementType(stackTypes[stackTop - 3].getName()),
38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                             classPool);
38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 3;
38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.BASTORE :
38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.CASTORE :
38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.SASTORE :
38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 3;
38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.POP :
38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;
39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.POP2 :
39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 2;
39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DUP : {
39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int sp = stackTop;
39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[sp] = stackTypes[sp - 1];
39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop = sp + 1;
39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break; }
39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DUP_X1 :
40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DUP_X2 : {
40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int len = op - Opcode.DUP_X1 + 2;
40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doDUP_XX(1, len);
40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int sp = stackTop;
40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[sp - len] = stackTypes[sp];
40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop = sp + 1;
40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break; }
40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DUP2 :
40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doDUP_XX(2, 2);
40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop += 2;
41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DUP2_X1 :
41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DUP2_X2 : {
41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int len = op - Opcode.DUP2_X1 + 3;
41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doDUP_XX(2, len);
41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int sp = stackTop;
41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[sp - len] = stackTypes[sp];
41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[sp - len + 1] = stackTypes[sp + 1];
41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop = sp + 2;
41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break; }
42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.SWAP : {
42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int sp = stackTop - 1;
42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData t = stackTypes[sp];
42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[sp] = stackTypes[sp - 1];
42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[sp - 1] = t;
42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break; }
42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default :
42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("fatal");
42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 1;
43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doXSTORE(int pos, byte[] code, TypeData type) {
43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = code[pos + 1] & 0xff;
43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return doXSTORE(index, type);
43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doXSTORE(int index, TypeData type) {
43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTop--;
44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        localsTypes[index] = type;
44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (type.is2WordType()) {
44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;
44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            localsTypes[index + 1] = TOP;
44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 2;
44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doASTORE(int index) {
45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTop--;
45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // implicit upcast might be done.
45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        localsTypes[index] = stackTypes[stackTop].copy();
45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 2;
45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void doDUP_XX(int delta, int len) {
45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        TypeData types[] = stackTypes;
45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int sp = stackTop - 1;
45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int end = sp - len;
46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (sp > end) {
46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[sp + delta] = types[sp];
46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            sp--;
46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doOpcode96_147(int pos, byte[] code, int op) {
46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (op <= Opcode.LXOR) {    // IADD...LXOR
46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop += Opcode.STACK_GROW[op];
46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 1;
47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (op) {
47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IINC :
47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // this does not call writeLocal().
47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3;
47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.I2L :
47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop] = LONG;
47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = TOP;
47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop++;
48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.I2F :
48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = FLOAT;
48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.I2D :
48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop] = DOUBLE;
48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = TOP;
48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop++;
48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.L2I :
49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[--stackTop - 1] = INTEGER;
49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.L2F :
49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[--stackTop - 1] = FLOAT;
49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.L2D :
49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = DOUBLE;
49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.F2I :
49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = INTEGER;
50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.F2L :
50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = TOP;
50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = LONG;
50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.F2D :
50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = TOP;
50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++] = DOUBLE;
50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.D2I :
51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[--stackTop - 1] = INTEGER;
51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.D2L :
51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = LONG;
51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.D2F :
51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[--stackTop - 1] = FLOAT;
51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.I2B :
51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.I2C :
52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.I2S :
52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default :
52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("fatal");
52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 1;
52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doOpcode148_201(int pos, byte[] code, int op) throws BadBytecode {
53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (op) {
53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LCMP :
53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 4] = INTEGER;
53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 3;
53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FCMPL :
53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FCMPG :
53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[--stackTop - 1] = INTEGER;
53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DCMPL :
54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DCMPG :
54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 4] = INTEGER;
54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 3;
54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IFEQ :
54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IFNE :
54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IFLT :
54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IFGE :
54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IFGT :
54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IFLE :
55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;     // branch
55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitBranch(pos, code, ByteArray.readS16bit(code, pos + 1));
55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3;
55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IF_ICMPEQ :
55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IF_ICMPNE :
55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IF_ICMPLT :
55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IF_ICMPGE :
55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IF_ICMPGT :
55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IF_ICMPLE :
55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IF_ACMPEQ :
56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IF_ACMPNE :
56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 2;  // branch
56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitBranch(pos, code, ByteArray.readS16bit(code, pos + 1));
56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3;
56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.GOTO :
56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitGoto(pos, code, ByteArray.readS16bit(code, pos + 1));
56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3;       // branch
56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.JSR :
56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitJSR(pos, code);
56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3;       // branch
57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.RET :
57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitRET(pos, code);
57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 2;
57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.TABLESWITCH : {
57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;     // branch
57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int pos2 = (pos & ~3) + 8;
57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int low = ByteArray.read32bit(code, pos2);
57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int high = ByteArray.read32bit(code, pos2 + 4);
57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int n = high - low + 1;
57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitTableSwitch(pos, code, n, pos2 + 8, ByteArray.read32bit(code, pos2 - 4));
58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return n * 4 + 16 - (pos & 3); }
58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LOOKUPSWITCH : {
58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;     // branch
58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int pos2 = (pos & ~3) + 8;
58469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int n = ByteArray.read32bit(code, pos2);
58569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitLookupSwitch(pos, code, n, pos2 + 4, ByteArray.read32bit(code, pos2 - 4));
58669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return n * 8 + 12 - (pos & 3); }
58769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IRETURN :
58869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;
58969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitReturn(pos, code);
59069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
59169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LRETURN :
59269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 2;
59369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitReturn(pos, code);
59469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
59569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FRETURN :
59669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;
59769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitReturn(pos, code);
59869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
59969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DRETURN :
60069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 2;
60169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitReturn(pos, code);
60269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
60369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ARETURN :
60469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[--stackTop], returnType, classPool);
60569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitReturn(pos, code);
60669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
60769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.RETURN :
60869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitReturn(pos, code);
60969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
61069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.GETSTATIC :
61169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doGetField(pos, code, false);
61269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.PUTSTATIC :
61369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doPutField(pos, code, false);
61469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.GETFIELD :
61569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doGetField(pos, code, true);
61669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.PUTFIELD :
61769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doPutField(pos, code, true);
61869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.INVOKEVIRTUAL :
61969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.INVOKESPECIAL :
62069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doInvokeMethod(pos, code, true);
62169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.INVOKESTATIC :
62269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doInvokeMethod(pos, code, false);
62369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.INVOKEINTERFACE :
62469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doInvokeIntfMethod(pos, code);
62569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 186 :
62669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("bad opcode 186");
62769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.NEW : {
62869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int i = ByteArray.readU16bit(code, pos + 1);
62969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop++]
63069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                      = new TypeData.UninitData(pos, cpool.getClassInfo(i));
63169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3; }
63269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.NEWARRAY :
63369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doNEWARRAY(pos, code);
63469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ANEWARRAY : {
63569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int i = ByteArray.readU16bit(code, pos + 1);
63669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String type = cpool.getClassInfo(i).replace('.', '/');
63769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (type.charAt(0) == '[')
63869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = "[" + type;
63969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
64069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = "[L" + type + ";";
64169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
64269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1]
64369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    = new TypeData.ClassName(type);
64469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3; }
64569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ARRAYLENGTH :
64669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[stackTop - 1], "[Ljava.lang.Object;", classPool);
64769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = INTEGER;
64869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
64969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ATHROW :
65069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[--stackTop], "java.lang.Throwable", classPool);
65169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitThrow(pos, code);
65269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
65369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.CHECKCAST : {
65469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // TypeData.setType(stackTypes[stackTop - 1], "java.lang.Object", classPool);
65569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int i = ByteArray.readU16bit(code, pos + 1);
65669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = new TypeData.ClassName(cpool.getClassInfo(i));
65769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3; }
65869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.INSTANCEOF :
65969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // TypeData.setType(stackTypes[stackTop - 1], "java.lang.Object", classPool);
66069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTypes[stackTop - 1] = INTEGER;
66169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3;
66269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.MONITORENTER :
66369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.MONITOREXIT :
66469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;
66569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // TypeData.setType(stackTypes[stackTop], "java.lang.Object", classPool);
66669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
66769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.WIDE :
66869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doWIDE(pos, code);
66969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.MULTIANEWARRAY :
67069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return doMultiANewArray(pos, code);
67169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IFNULL :
67269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IFNONNULL :
67369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;         // branch
67469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitBranch(pos, code, ByteArray.readS16bit(code, pos + 1));
67569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 3;
67669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.GOTO_W :
67769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitGoto(pos, code, ByteArray.read32bit(code, pos + 1));
67869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 5;           // branch
67969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.JSR_W :
68069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitJSR(pos, code);
68169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 5;
68269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
68369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 1;
68469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
68569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
68669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doWIDE(int pos, byte[] code) throws BadBytecode {
68769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int op = code[pos + 1] & 0xff;
68869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (op) {
68969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ILOAD :
69069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doWIDE_XLOAD(pos, code, INTEGER);
69169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
69269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LLOAD :
69369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doWIDE_XLOAD(pos, code, LONG);
69469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
69569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FLOAD :
69669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doWIDE_XLOAD(pos, code, FLOAT);
69769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
69869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DLOAD :
69969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doWIDE_XLOAD(pos, code, DOUBLE);
70069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
70169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ALOAD : {
70269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int index = ByteArray.readU16bit(code, pos + 2);
70369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doALOAD(index);
70469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break; }
70569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ISTORE :
70669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doWIDE_STORE(pos, code, INTEGER);
70769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
70869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.LSTORE :
70969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doWIDE_STORE(pos, code, LONG);
71069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
71169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.FSTORE :
71269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doWIDE_STORE(pos, code, FLOAT);
71369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
71469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.DSTORE :
71569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doWIDE_STORE(pos, code, DOUBLE);
71669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
71769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.ASTORE : {
71869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int index = ByteArray.readU16bit(code, pos + 2);
71969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            doASTORE(index);
72069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break; }
72169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.IINC :
72269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // this does not call writeLocal().
72369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 6;
72469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.RET :
72569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            visitRET(pos, code);
72669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
72769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default :
72869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("bad WIDE instruction: " + op);
72969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
73069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
73169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 4;
73269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
73369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
73469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void doWIDE_XLOAD(int pos, byte[] code, TypeData type) {
73569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = ByteArray.readU16bit(code, pos + 2);
73669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        doXLOAD(index, type);
73769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
73869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
73969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void doWIDE_STORE(int pos, byte[] code, TypeData type) {
74069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = ByteArray.readU16bit(code, pos + 2);
74169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        doXSTORE(index, type);
74269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
74369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
74469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doPutField(int pos, byte[] code, boolean notStatic) throws BadBytecode {
74569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = ByteArray.readU16bit(code, pos + 1);
74669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc = cpool.getFieldrefType(index);
74769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTop -= Descriptor.dataSize(desc);
74869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        char c = desc.charAt(0);
74969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (c == 'L')
75069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[stackTop], getFieldClassName(desc, 0), classPool);
75169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (c == '[')
75269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[stackTop], desc, classPool);
75369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
75469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        setFieldTarget(notStatic, index);
75569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 3;
75669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
75769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
75869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doGetField(int pos, byte[] code, boolean notStatic) throws BadBytecode {
75969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = ByteArray.readU16bit(code, pos + 1);
76069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        setFieldTarget(notStatic, index);
76169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc = cpool.getFieldrefType(index);
76269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        pushMemberType(desc);
76369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 3;
76469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
76569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
76669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void setFieldTarget(boolean notStatic, int index) throws BadBytecode {
76769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (notStatic) {
76869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String className = cpool.getFieldrefClassName(index);
76969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[--stackTop], className, classPool);
77069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
77169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
77269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
77369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doNEWARRAY(int pos, byte[] code) {
77469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int s = stackTop - 1;
77569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String type;
77669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (code[pos + 1] & 0xff) {
77769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_BOOLEAN :
77869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = "[Z";
77969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
78069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_CHAR :
78169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = "[C";
78269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
78369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_FLOAT :
78469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = "[F";
78569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
78669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_DOUBLE :
78769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = "[D";
78869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
78969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_BYTE :
79069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = "[B";
79169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
79269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_SHORT :
79369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = "[S";
79469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
79569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_INT :
79669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = "[I";
79769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
79869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_LONG :
79969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = "[J";
80069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
80169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default :
80269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("bad newarray");
80369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
80469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
80569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTypes[s] = new TypeData.ClassName(type);
80669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 2;
80769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
80869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
80969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doMultiANewArray(int pos, byte[] code) {
81069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int i = ByteArray.readU16bit(code, pos + 1);
81169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int dim = code[pos + 3] & 0xff;
81269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTop -= dim - 1;
81369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
81469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String type = cpool.getClassInfo(i).replace('.', '/');
81569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTypes[stackTop - 1] = new TypeData.ClassName(type);
81669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 4;
81769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
81869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
81969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doInvokeMethod(int pos, byte[] code, boolean notStatic) throws BadBytecode {
82069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int i = ByteArray.readU16bit(code, pos + 1);
82169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc = cpool.getMethodrefType(i);
82269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        checkParamTypes(desc, 1);
82369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (notStatic) {
82469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String className = cpool.getMethodrefClassName(i);
82569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[--stackTop], className, classPool);
82669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
82769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
82869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        pushMemberType(desc);
82969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 3;
83069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
83169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
83269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int doInvokeIntfMethod(int pos, byte[] code) throws BadBytecode {
83369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int i = ByteArray.readU16bit(code, pos + 1);
83469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc = cpool.getInterfaceMethodrefType(i);
83569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        checkParamTypes(desc, 1);
83669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String className = cpool.getInterfaceMethodrefClassName(i);
83769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        TypeData.setType(stackTypes[--stackTop], className, classPool);
83869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        pushMemberType(desc);
83969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return 5;
84069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
84169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
84269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void pushMemberType(String descriptor) {
84369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int top = 0;
84469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (descriptor.charAt(0) == '(') {
84569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            top = descriptor.indexOf(')') + 1;
84669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (top < 1)
84769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new IndexOutOfBoundsException("bad descriptor: "
84869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                                    + descriptor);
84969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
85069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
85169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        TypeData[] types = stackTypes;
85269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = stackTop;
85369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (descriptor.charAt(top)) {
85469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case '[' :
85569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[index] = new TypeData.ClassName(descriptor.substring(top));
85669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
85769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'L' :
85869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[index] = new TypeData.ClassName(getFieldClassName(descriptor, top));
85969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
86069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'J' :
86169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[index] = LONG;
86269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[index + 1] = TOP;
86369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop += 2;
86469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return;
86569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'F' :
86669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[index] = FLOAT;
86769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
86869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'D' :
86969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[index] = DOUBLE;
87069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[index + 1] = TOP;
87169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop += 2;
87269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return;
87369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case 'V' :
87469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return;
87569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default : // C, B, S, I, Z
87669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[index] = INTEGER;
87769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
87869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
87969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
88069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        stackTop++;
88169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
88269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
88369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static String getFieldClassName(String desc, int index) {
88469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return desc.substring(index + 1, desc.length() - 1).replace('/', '.');
88569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
88669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
88769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void checkParamTypes(String desc, int i) throws BadBytecode {
88869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        char c = desc.charAt(i);
88969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (c == ')')
89069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return;
89169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
89269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int k = i;
89369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        boolean array = false;
89469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (c == '[') {
89569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            array = true;
89669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            c = desc.charAt(++k);
89769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
89869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
89969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (c == 'L') {
90069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            k = desc.indexOf(';', k) + 1;
90169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (k <= 0)
90269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new IndexOutOfBoundsException("bad descriptor");
90369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
90469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
90569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            k++;
90669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
90769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        checkParamTypes(desc, k);
90869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (!array && (c == 'J' || c == 'D'))
90969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop -= 2;
91069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
91169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            stackTop--;
91269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
91369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (array)
91469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[stackTop],
91569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                             desc.substring(i, k), classPool);
91669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (c == 'L')
91769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeData.setType(stackTypes[stackTop],
91869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                             desc.substring(i + 1, k - 1).replace('/', '.'), classPool);
91969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
92069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
921