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.analysis;
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool;
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.NotFoundException;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.BadBytecode;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.CodeIterator;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.ConstPool;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.Descriptor;
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.MethodInfo;
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.Opcode;
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Executor is responsible for modeling the effects of a JVM instruction on a frame.
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author Jason T. Greene
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class Executor implements Opcode {
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final ConstPool constPool;
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final ClassPool classPool;
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final Type STRING_TYPE;
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final Type CLASS_TYPE;
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final Type THROWABLE_TYPE;
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int lastPos;
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Executor(ClassPool classPool, ConstPool constPool) {
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.constPool = constPool;
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.classPool = classPool;
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            STRING_TYPE = getType("java.lang.String");
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            CLASS_TYPE = getType("java.lang.Class");
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            THROWABLE_TYPE = getType("java.lang.Throwable");
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } catch (Exception e) {
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException(e);
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Execute the instruction, modeling the effects on the specified frame and subroutine.
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If a subroutine is passed, the access flags will be modified if this instruction accesses
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the local variable table.
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param method the method containing the instruction
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param pos the position of the instruction in the method
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param iter the code iterator used to find the instruction
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param frame the frame to modify to represent the result of the instruction
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param subroutine the optional subroutine this instruction belongs to.
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws BadBytecode if the bytecode violates the jvm spec
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void execute(MethodInfo method, int pos, CodeIterator iter, Frame frame, Subroutine subroutine) throws BadBytecode {
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.lastPos = pos;
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int opcode = iter.byteAt(pos);
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // Declared opcode in order
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (opcode) {
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case NOP:
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ACONST_NULL:
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.UNINIT);
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ICONST_M1:
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ICONST_0:
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ICONST_1:
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ICONST_2:
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ICONST_3:
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ICONST_4:
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ICONST_5:
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.INTEGER);
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LCONST_0:
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LCONST_1:
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.LONG);
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.TOP);
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FCONST_0:
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FCONST_1:
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FCONST_2:
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.FLOAT);
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DCONST_0:
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DCONST_1:
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.DOUBLE);
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.TOP);
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case BIPUSH:
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case SIPUSH:
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.INTEGER);
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LDC:
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLDC(iter.byteAt(pos + 1),  frame);
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LDC_W :
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LDC2_W :
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLDC(iter.u16bitAt(pos + 1), frame);
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ILOAD:
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.INTEGER, iter.byteAt(pos + 1), frame, subroutine);
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LLOAD:
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.LONG, iter.byteAt(pos + 1), frame, subroutine);
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FLOAD:
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.FLOAT, iter.byteAt(pos + 1), frame, subroutine);
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DLOAD:
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.DOUBLE, iter.byteAt(pos + 1), frame, subroutine);
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ALOAD:
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.OBJECT, iter.byteAt(pos + 1), frame, subroutine);
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ILOAD_0:
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ILOAD_1:
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ILOAD_2:
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ILOAD_3:
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.INTEGER, opcode - ILOAD_0, frame, subroutine);
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LLOAD_0:
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LLOAD_1:
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LLOAD_2:
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LLOAD_3:
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.LONG, opcode - LLOAD_0, frame, subroutine);
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FLOAD_0:
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FLOAD_1:
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FLOAD_2:
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FLOAD_3:
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.FLOAT, opcode - FLOAD_0, frame, subroutine);
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DLOAD_0:
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DLOAD_1:
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DLOAD_2:
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DLOAD_3:
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.DOUBLE, opcode - DLOAD_0, frame, subroutine);
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ALOAD_0:
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ALOAD_1:
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ALOAD_2:
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ALOAD_3:
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.OBJECT, opcode - ALOAD_0, frame, subroutine);
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IALOAD:
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayLoad(Type.INTEGER, frame);
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LALOAD:
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayLoad(Type.LONG, frame);
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FALOAD:
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayLoad(Type.FLOAT, frame);
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DALOAD:
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayLoad(Type.DOUBLE, frame);
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case AALOAD:
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayLoad(Type.OBJECT, frame);
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case BALOAD:
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case CALOAD:
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case SALOAD:
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayLoad(Type.INTEGER, frame);
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISTORE:
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.INTEGER, iter.byteAt(pos + 1), frame, subroutine);
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSTORE:
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.LONG, iter.byteAt(pos + 1), frame, subroutine);
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSTORE:
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.FLOAT, iter.byteAt(pos + 1), frame, subroutine);
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSTORE:
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.DOUBLE, iter.byteAt(pos + 1), frame, subroutine);
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ASTORE:
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.OBJECT, iter.byteAt(pos + 1), frame, subroutine);
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISTORE_0:
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISTORE_1:
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISTORE_2:
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISTORE_3:
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.INTEGER, opcode - ISTORE_0, frame, subroutine);
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSTORE_0:
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSTORE_1:
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSTORE_2:
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSTORE_3:
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.LONG, opcode - LSTORE_0, frame, subroutine);
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSTORE_0:
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSTORE_1:
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSTORE_2:
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSTORE_3:
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.FLOAT, opcode - FSTORE_0, frame, subroutine);
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSTORE_0:
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSTORE_1:
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSTORE_2:
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSTORE_3:
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.DOUBLE, opcode - DSTORE_0, frame, subroutine);
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ASTORE_0:
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ASTORE_1:
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ASTORE_2:
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ASTORE_3:
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.OBJECT, opcode - ASTORE_0, frame, subroutine);
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IASTORE:
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayStore(Type.INTEGER, frame);
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LASTORE:
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayStore(Type.LONG, frame);
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FASTORE:
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayStore(Type.FLOAT, frame);
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DASTORE:
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayStore(Type.DOUBLE, frame);
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case AASTORE:
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayStore(Type.OBJECT, frame);
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case BASTORE:
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case CASTORE:
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case SASTORE:
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalArrayStore(Type.INTEGER, frame);
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case POP:
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (frame.pop() == Type.TOP)
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    throw new BadBytecode("POP can not be used with a category 2 value, pos = " + pos);
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case POP2:
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.pop();
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.pop();
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DUP: {
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Type type = frame.peek();
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (type == Type.TOP)
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    throw new BadBytecode("DUP can not be used with a category 2 value, pos = " + pos);
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(frame.peek());
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DUP_X1:
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DUP_X2: {
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Type type = frame.peek();
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (type == Type.TOP)
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    throw new BadBytecode("DUP can not be used with a category 2 value, pos = " + pos);
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int end = frame.getTopIndex();
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int insert = end - (opcode - DUP_X1) - 1;
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(type);
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                while (end > insert) {
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    frame.setStack(end, frame.getStack(end - 1));
27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    end--;
27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.setStack(insert, type);
27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DUP2:
27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(frame.getStack(frame.getTopIndex() - 1));
27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(frame.getStack(frame.getTopIndex() - 1));
27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DUP2_X1:
28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DUP2_X2: {
28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int end = frame.getTopIndex();
28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int insert = end - (opcode - DUP2_X1) - 1;
28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Type type1 = frame.getStack(frame.getTopIndex() - 1);
28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Type type2 = frame.peek();
28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(type1);
28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(type2);
28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                while (end > insert) {
28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    frame.setStack(end, frame.getStack(end - 2));
28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    end--;
29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.setStack(insert, type2);
29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.setStack(insert - 1, type1);
29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case SWAP: {
29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Type type1 = frame.pop();
29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Type type2 = frame.pop();
29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (type1.getSize() == 2 || type2.getSize() == 2)
29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    throw new BadBytecode("Swap can not be used with category 2 values, pos = " + pos);
30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(type1);
30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(type2);
30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // Math
30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IADD:
30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.INTEGER, frame);
30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LADD:
31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.LONG, frame);
31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FADD:
31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.FLOAT, frame);
31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DADD:
31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.DOUBLE, frame);
31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISUB:
31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.INTEGER, frame);
32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSUB:
32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.LONG, frame);
32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSUB:
32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.FLOAT, frame);
32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSUB:
32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.DOUBLE, frame);
32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IMUL:
33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.INTEGER, frame);
33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LMUL:
33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.LONG, frame);
33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FMUL:
33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.FLOAT, frame);
33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DMUL:
34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.DOUBLE, frame);
34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IDIV:
34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.INTEGER, frame);
34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LDIV:
34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.LONG, frame);
34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FDIV:
34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.FLOAT, frame);
35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DDIV:
35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.DOUBLE, frame);
35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IREM:
35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.INTEGER, frame);
35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LREM:
35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.LONG, frame);
35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FREM:
36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.FLOAT, frame);
36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DREM:
36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.DOUBLE, frame);
36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // Unary
36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INEG:
36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, simplePeek(frame));
37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LNEG:
37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.LONG, simplePeek(frame));
37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FNEG:
37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.FLOAT, simplePeek(frame));
37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DNEG:
37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.DOUBLE, simplePeek(frame));
37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // Shifts
38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISHL:
38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalShift(Type.INTEGER, frame);
38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSHL:
38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalShift(Type.LONG, frame);
38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISHR:
38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalShift(Type.INTEGER, frame);
39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSHR:
39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalShift(Type.LONG, frame);
39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IUSHR:
39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalShift(Type.INTEGER,frame);
39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LUSHR:
39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalShift(Type.LONG, frame);
39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // Bitwise Math
40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IAND:
40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.INTEGER, frame);
40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LAND:
40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.LONG, frame);
40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IOR:
40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.INTEGER, frame);
41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LOR:
41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.LONG, frame);
41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IXOR:
41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.INTEGER, frame);
41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LXOR:
41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalBinaryMath(Type.LONG, frame);
41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IINC: {
42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int index = iter.byteAt(pos + 1);
42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, frame.getLocal(index));
42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                access(index, Type.INTEGER, subroutine);
42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // Conversion
42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case I2L:
43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, simplePop(frame));
43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.LONG, frame);
43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case I2F:
43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, simplePop(frame));
43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.FLOAT, frame);
43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case I2D:
43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, simplePop(frame));
43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.DOUBLE, frame);
44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case L2I:
44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.LONG, simplePop(frame));
44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.INTEGER, frame);
44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case L2F:
44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.LONG, simplePop(frame));
44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.FLOAT, frame);
44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case L2D:
45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.LONG, simplePop(frame));
45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.DOUBLE, frame);
45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case F2I:
45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.FLOAT, simplePop(frame));
45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.INTEGER, frame);
45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case F2L:
45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.FLOAT, simplePop(frame));
45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.LONG, frame);
46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case F2D:
46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.FLOAT, simplePop(frame));
46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.DOUBLE, frame);
46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case D2I:
46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.DOUBLE, simplePop(frame));
46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.INTEGER, frame);
46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case D2L:
47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.DOUBLE, simplePop(frame));
47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.LONG, frame);
47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case D2F:
47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.DOUBLE, simplePop(frame));
47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.FLOAT, frame);
47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case I2B:
47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case I2C:
47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case I2S:
48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, frame.peek());
48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LCMP:
48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.LONG, simplePop(frame));
48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.LONG, simplePop(frame));
48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.INTEGER);
48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FCMPL:
48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FCMPG:
48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.FLOAT, simplePop(frame));
49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.FLOAT, simplePop(frame));
49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.INTEGER);
49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DCMPL:
49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DCMPG:
49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.DOUBLE, simplePop(frame));
49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.DOUBLE, simplePop(frame));
49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.INTEGER);
49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // Control flow
50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFEQ:
50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFNE:
50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFLT:
50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFGE:
50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFGT:
50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFLE:
50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, simplePop(frame));
50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPEQ:
51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPNE:
51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPLT:
51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPGE:
51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPGT:
51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ICMPLE:
51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, simplePop(frame));
51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, simplePop(frame));
51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ACMPEQ:
51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IF_ACMPNE:
52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.OBJECT, simplePop(frame));
52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.OBJECT, simplePop(frame));
52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case GOTO:
52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case JSR:
52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.RETURN_ADDRESS);
52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case RET:
52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.RETURN_ADDRESS, frame.getLocal(iter.byteAt(pos + 1)));
53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case TABLESWITCH:
53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LOOKUPSWITCH:
53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IRETURN:
53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, simplePop(frame));
53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LRETURN:
53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.LONG, simplePop(frame));
53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FRETURN:
54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.FLOAT, simplePop(frame));
54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DRETURN:
54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.DOUBLE, simplePop(frame));
54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ARETURN:
54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                try {
54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    CtClass returnType = Descriptor.getReturnType(method.getDescriptor(), classPool);
54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    verifyAssignable(Type.get(returnType), simplePop(frame));
54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                } catch (NotFoundException e) {
55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                   throw new RuntimeException(e);
55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case RETURN:
55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case GETSTATIC:
55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalGetField(opcode, iter.u16bitAt(pos + 1), frame);
55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case PUTSTATIC:
55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalPutField(opcode, iter.u16bitAt(pos + 1), frame);
56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case GETFIELD:
56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalGetField(opcode, iter.u16bitAt(pos + 1), frame);
56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case PUTFIELD:
56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalPutField(opcode, iter.u16bitAt(pos + 1), frame);
56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INVOKEVIRTUAL:
56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INVOKESPECIAL:
56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INVOKESTATIC:
57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalInvokeMethod(opcode, iter.u16bitAt(pos + 1), frame);
57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INVOKEINTERFACE:
57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalInvokeIntfMethod(opcode, iter.u16bitAt(pos + 1), frame);
57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case 186:
57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException("Bad opcode 186");
57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case NEW:
57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(resolveClassInfo(constPool.getClassInfo(iter.u16bitAt(pos + 1))));
57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case NEWARRAY:
58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalNewArray(pos, iter, frame);
58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ANEWARRAY:
58469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalNewObjectArray(pos, iter, frame);
58569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
58669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ARRAYLENGTH: {
58769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                Type array = simplePop(frame);
58869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (! array.isArray() && array != Type.UNINIT)
58969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    throw new BadBytecode("Array length passed a non-array [pos = " + pos + "]: " + array);
59069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.INTEGER);
59169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
59269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
59369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ATHROW:
59469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(THROWABLE_TYPE, simplePop(frame));
59569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
59669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case CHECKCAST:
59769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.OBJECT, simplePop(frame));
59869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(typeFromDesc(constPool.getClassInfo(iter.u16bitAt(pos + 1))));
59969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
60069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case INSTANCEOF:
60169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.OBJECT, simplePop(frame));
60269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.INTEGER);
60369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
60469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case MONITORENTER:
60569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case MONITOREXIT:
60669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.OBJECT, simplePop(frame));
60769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
60869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case WIDE:
60969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalWide(pos, iter, frame, subroutine);
61069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
61169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case MULTIANEWARRAY:
61269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalNewObjectArray(pos, iter, frame);
61369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
61469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFNULL:
61569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IFNONNULL:
61669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.OBJECT, simplePop(frame));
61769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
61869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case GOTO_W:
61969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
62069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case JSR_W:
62169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                frame.push(Type.RETURN_ADDRESS);
62269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
62369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
62469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
62569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
62669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Type zeroExtend(Type type) {
62769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (type == Type.SHORT || type == Type.BYTE || type == Type.CHAR || type == Type.BOOLEAN)
62869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return  Type.INTEGER;
62969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
63069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return type;
63169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
63269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
63369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalArrayLoad(Type expectedComponent, Frame frame) throws BadBytecode {
63469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type index = frame.pop();
63569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type array = frame.pop();
63669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
63769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // Special case, an array defined by aconst_null
63869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // TODO - we might need to be more inteligent about this
63969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (array == Type.UNINIT) {
64069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(Type.INTEGER, index);
64169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (expectedComponent == Type.OBJECT) {
64269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(Type.UNINIT, frame);
64369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            } else {
64469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                simplePush(expectedComponent, frame);
64569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
64669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return;
64769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
64869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
64969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type component = array.getComponent();
65069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
65169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (component == null)
65269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Not an array! [pos = " + lastPos + "]: " + component);
65369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
65469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        component = zeroExtend(component);
65569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
65669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(expectedComponent, component);
65769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(Type.INTEGER, index);
65869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        simplePush(component, frame);
65969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
66069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
66169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalArrayStore(Type expectedComponent, Frame frame) throws BadBytecode {
66269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type value = simplePop(frame);
66369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type index = frame.pop();
66469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type array = frame.pop();
66569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
66669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (array == Type.UNINIT) {
66769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(Type.INTEGER, index);
66869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return;
66969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
67069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
67169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type component = array.getComponent();
67269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
67369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (component == null)
67469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Not an array! [pos = " + lastPos + "]: " + component);
67569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
67669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        component = zeroExtend(component);
67769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
67869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(expectedComponent, component);
67969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(Type.INTEGER, index);
68069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
68169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // This intentionally only checks for Object on aastore
68269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // downconverting of an array (no casts)
68369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // e.g. Object[] blah = new String[];
68469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        //      blah[2] = (Object) "test";
68569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        //      blah[3] = new Integer(); // compiler doesnt catch it (has legal bytecode),
68669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        //                               // but will throw arraystoreexception
68769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (expectedComponent == Type.OBJECT) {
68869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(expectedComponent, value);
68969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } else {
69069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(component, value);
69169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
69269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
69369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
69469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalBinaryMath(Type expected, Frame frame) throws BadBytecode {
69569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type value2 = simplePop(frame);
69669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type value1 = simplePop(frame);
69769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
69869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(expected, value2);
69969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(expected, value1);
70069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        simplePush(value1, frame);
70169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
70269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
70369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalGetField(int opcode, int index, Frame frame) throws BadBytecode {
70469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc = constPool.getFieldrefType(index);
70569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type = zeroExtend(typeFromDesc(desc));
70669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
70769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode == GETFIELD) {
70869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Type objectType = resolveClassInfo(constPool.getFieldrefClassName(index));
70969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(objectType, simplePop(frame));
71069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
71169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
71269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        simplePush(type, frame);
71369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
71469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
71569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalInvokeIntfMethod(int opcode, int index, Frame frame) throws BadBytecode {
71669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc = constPool.getInterfaceMethodrefType(index);
71769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type[] types = paramTypesFromDesc(desc);
71869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int i = types.length;
71969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
72069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (i > 0)
72169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(zeroExtend(types[--i]), simplePop(frame));
72269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
72369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String classInfo = constPool.getInterfaceMethodrefClassName(index);
72469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type objectType = resolveClassInfo(classInfo);
72569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(objectType, simplePop(frame));
72669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
72769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type returnType = returnTypeFromDesc(desc);
72869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (returnType != Type.VOID)
72969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            simplePush(zeroExtend(returnType), frame);
73069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
73169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
73269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalInvokeMethod(int opcode, int index, Frame frame) throws BadBytecode {
73369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc = constPool.getMethodrefType(index);
73469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type[] types = paramTypesFromDesc(desc);
73569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int i = types.length;
73669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
73769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (i > 0)
73869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(zeroExtend(types[--i]), simplePop(frame));
73969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
74069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode != INVOKESTATIC) {
74169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Type objectType = resolveClassInfo(constPool.getMethodrefClassName(index));
74269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(objectType, simplePop(frame));
74369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
74469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
74569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type returnType = returnTypeFromDesc(desc);
74669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (returnType != Type.VOID)
74769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            simplePush(zeroExtend(returnType), frame);
74869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
74969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
75069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
75169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalLDC(int index, Frame frame) throws BadBytecode {
75269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int tag = constPool.getTag(index);
75369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type;
75469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (tag) {
75569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case ConstPool.CONST_String:
75669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = STRING_TYPE;
75769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
75869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case ConstPool.CONST_Integer:
75969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = Type.INTEGER;
76069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
76169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case ConstPool.CONST_Float:
76269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = Type.FLOAT;
76369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
76469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case ConstPool.CONST_Long:
76569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = Type.LONG;
76669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
76769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case ConstPool.CONST_Double:
76869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = Type.DOUBLE;
76969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
77069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case ConstPool.CONST_Class:
77169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            type = CLASS_TYPE;
77269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
77369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default:
77469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("bad LDC [pos = " + lastPos + "]: " + tag);
77569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
77669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
77769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        simplePush(type, frame);
77869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
77969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
78069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalLoad(Type expected, int index, Frame frame, Subroutine subroutine) throws BadBytecode {
78169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type = frame.getLocal(index);
78269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
78369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(expected, type);
78469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
78569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        simplePush(type, frame);
78669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        access(index, type, subroutine);
78769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
78869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
78969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalNewArray(int pos, CodeIterator iter, Frame frame) throws BadBytecode {
79069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(Type.INTEGER, simplePop(frame));
79169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type = null;
79269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int typeInfo = iter.byteAt(pos + 1);
79369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (typeInfo) {
79469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_BOOLEAN:
79569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getType("boolean[]");
79669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
79769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_CHAR:
79869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getType("char[]");
79969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
80069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_BYTE:
80169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getType("byte[]");
80269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
80369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_SHORT:
80469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getType("short[]");
80569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
80669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_INT:
80769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getType("int[]");
80869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
80969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_LONG:
81069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getType("long[]");
81169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
81269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_FLOAT:
81369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getType("float[]");
81469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
81569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case T_DOUBLE:
81669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getType("double[]");
81769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
81869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            default:
81969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new BadBytecode("Invalid array type [pos = " + pos + "]: " + typeInfo);
82069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
82169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
82269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
82369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        frame.push(type);
82469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
82569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
82669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalNewObjectArray(int pos, CodeIterator iter, Frame frame) throws BadBytecode {
82769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // Convert to x[] format
82869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type = resolveClassInfo(constPool.getClassInfo(iter.u16bitAt(pos + 1)));
82969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String name = type.getCtClass().getName();
83069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int opcode = iter.byteAt(pos);
83169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int dimensions;
83269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
83369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode == MULTIANEWARRAY) {
83469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            dimensions = iter.byteAt(pos + 3);
83569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } else {
83669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            name = name + "[]";
83769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            dimensions = 1;
83869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
83969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
84069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (dimensions-- > 0) {
84169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(Type.INTEGER, simplePop(frame));
84269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
84369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
84469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        simplePush(getType(name), frame);
84569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
84669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
84769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalPutField(int opcode, int index, Frame frame) throws BadBytecode {
84869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc = constPool.getFieldrefType(index);
84969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type = zeroExtend(typeFromDesc(desc));
85069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
85169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(type, simplePop(frame));
85269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
85369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode == PUTFIELD) {
85469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Type objectType = resolveClassInfo(constPool.getFieldrefClassName(index));
85569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(objectType, simplePop(frame));
85669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
85769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
85869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
85969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalShift(Type expected, Frame frame) throws BadBytecode {
86069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type value2 = simplePop(frame);
86169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type value1 = simplePop(frame);
86269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
86369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(Type.INTEGER, value2);
86469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        verifyAssignable(expected, value1);
86569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        simplePush(value1, frame);
86669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
86769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
86869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalStore(Type expected, int index, Frame frame, Subroutine subroutine) throws BadBytecode {
86969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type = simplePop(frame);
87069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
87169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // RETURN_ADDRESS is allowed by ASTORE
87269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (! (expected == Type.OBJECT && type == Type.RETURN_ADDRESS))
87369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            verifyAssignable(expected, type);
87469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        simpleSetLocal(index, type, frame);
87569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        access(index, type, subroutine);
87669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
87769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
87869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void evalWide(int pos, CodeIterator iter, Frame frame, Subroutine subroutine) throws BadBytecode {
87969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int opcode = iter.byteAt(pos + 1);
88069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = iter.u16bitAt(pos + 2);
88169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (opcode) {
88269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ILOAD:
88369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.INTEGER, index, frame, subroutine);
88469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
88569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LLOAD:
88669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.LONG, index, frame, subroutine);
88769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
88869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FLOAD:
88969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.FLOAT, index, frame, subroutine);
89069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
89169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DLOAD:
89269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.DOUBLE, index, frame, subroutine);
89369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
89469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ALOAD:
89569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalLoad(Type.OBJECT, index, frame, subroutine);
89669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
89769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ISTORE:
89869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.INTEGER, index, frame, subroutine);
89969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
90069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case LSTORE:
90169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.LONG, index, frame, subroutine);
90269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
90369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case FSTORE:
90469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.FLOAT, index, frame, subroutine);
90569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
90669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case DSTORE:
90769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.DOUBLE, index, frame, subroutine);
90869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
90969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case ASTORE:
91069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                evalStore(Type.OBJECT, index, frame, subroutine);
91169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
91269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case IINC:
91369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.INTEGER, frame.getLocal(index));
91469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
91569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            case RET:
91669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                verifyAssignable(Type.RETURN_ADDRESS, frame.getLocal(index));
91769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
91869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            default:
91969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new BadBytecode("Invalid WIDE operand [pos = " + pos + "]: " + opcode);
92069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
92169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
92269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
92369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
92469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Type getType(String name) throws BadBytecode {
92569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
92669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return Type.get(classPool.get(name));
92769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } catch (NotFoundException e) {
92869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not find class [pos = " + lastPos + "]: " + name);
92969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
93069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
93169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
93269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Type[] paramTypesFromDesc(String desc) throws BadBytecode {
93369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass classes[] = null;
93469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
93569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            classes = Descriptor.getParameterTypes(desc, classPool);
93669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } catch (NotFoundException e) {
93769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not find class in descriptor [pos = " + lastPos + "]: " + e.getMessage());
93869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
93969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
94069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (classes == null)
94169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not obtain parameters for descriptor [pos = " + lastPos + "]: " + desc);
94269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
94369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type[] types = new Type[classes.length];
94469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int i = 0; i < types.length; i++)
94569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            types[i] = Type.get(classes[i]);
94669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
94769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return types;
94869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
94969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
95069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Type returnTypeFromDesc(String desc) throws BadBytecode {
95169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = null;
95269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
95369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = Descriptor.getReturnType(desc, classPool);
95469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } catch (NotFoundException e) {
95569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not find class in descriptor [pos = " + lastPos + "]: " + e.getMessage());
95669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
95769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
95869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null)
95969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not obtain return type for descriptor [pos = " + lastPos + "]: " + desc);
96069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
96169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return Type.get(clazz);
96269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
96369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
96469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Type simplePeek(Frame frame) {
96569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type = frame.peek();
96669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return (type == Type.TOP) ? frame.getStack(frame.getTopIndex() - 1) : type;
96769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
96869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
96969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Type simplePop(Frame frame) {
97069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Type type = frame.pop();
97169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return (type == Type.TOP) ? frame.pop() : type;
97269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
97369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
97469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void simplePush(Type type, Frame frame) {
97569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        frame.push(type);
97669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (type.getSize() == 2)
97769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            frame.push(Type.TOP);
97869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
97969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
98069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void access(int index, Type type, Subroutine subroutine) {
98169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (subroutine == null)
98269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return;
98369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        subroutine.access(index);
98469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (type.getSize() == 2)
98569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            subroutine.access(index + 1);
98669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
98769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
98869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void simpleSetLocal(int index, Type type, Frame frame) {
98969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        frame.setLocal(index, type);
99069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (type.getSize() == 2)
99169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            frame.setLocal(index + 1, Type.TOP);
99269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
99369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
99469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Type resolveClassInfo(String info) throws BadBytecode {
99569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = null;
99669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
99769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (info.charAt(0) == '[') {
99869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                clazz = Descriptor.toCtClass(info, classPool);
99969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            } else {
100069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                clazz = classPool.get(info);
100169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
100269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
100369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } catch (NotFoundException e) {
100469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not find class in descriptor [pos = " + lastPos + "]: " + e.getMessage());
100569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
100669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
100769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null)
100869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not obtain type for descriptor [pos = " + lastPos + "]: " + info);
100969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
101069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return Type.get(clazz);
101169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
101269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
101369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Type typeFromDesc(String desc) throws BadBytecode {
101469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = null;
101569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
101669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = Descriptor.toCtClass(desc, classPool);
101769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        } catch (NotFoundException e) {
101869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not find class in descriptor [pos = " + lastPos + "]: " + e.getMessage());
101969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
102069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
102169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null)
102269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Could not obtain type for descriptor [pos = " + lastPos + "]: " + desc);
102369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
102469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return Type.get(clazz);
102569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
102669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
102769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void verifyAssignable(Type expected, Type type) throws BadBytecode {
102869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (! expected.isAssignableFrom(type))
102969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("Expected type: " + expected + " Got: " + type + " [pos = " + lastPos + "]");
103069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
103169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
1032