Search in sources :

Example 26 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class ExprVisitor method caseNewArrayExpr.

@Override
public void caseNewArrayExpr(NewArrayExpr nae) {
    Value size = nae.getSize();
    constantV.setOrigStmt(origStmt);
    Register sizeReg = regAlloc.asImmediate(size, constantV);
    ArrayType arrayType = nae.getBaseType().getArrayType();
    TypeReference arrayTypeItem = DexPrinter.toTypeReference(arrayType);
    stmtV.addInsn(new Insn22c(Opcode.NEW_ARRAY, destinationReg, sizeReg, arrayTypeItem), origStmt);
}
Also used : ArrayType(soot.ArrayType) Insn22c(soot.toDex.instructions.Insn22c) Value(soot.Value) TypeReference(org.jf.dexlib2.iface.reference.TypeReference)

Example 27 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class ExprVisitor method caseNewMultiArrayExpr.

@Override
public void caseNewMultiArrayExpr(NewMultiArrayExpr nmae) {
    constantV.setOrigStmt(origStmt);
    // get array dimensions
    if (nmae.getSizeCount() > 255) {
        throw new RuntimeException("number of dimensions is too high (> 255) for the filled-new-array* opcodes: " + nmae.getSizeCount());
    }
    short dimensions = (short) nmae.getSizeCount();
    // get array base type
    ArrayType arrayType = ArrayType.v(nmae.getBaseType().baseType, dimensions);
    TypeReference arrayTypeItem = DexPrinter.toTypeReference(arrayType);
    // get the dimension size registers
    List<Register> dimensionSizeRegs = new ArrayList<Register>();
    for (int i = 0; i < dimensions; i++) {
        Value currentDimensionSize = nmae.getSize(i);
        Register currentReg = regAlloc.asImmediate(currentDimensionSize, constantV);
        dimensionSizeRegs.add(currentReg);
    }
    // create filled-new-array instruction, depending on the dimension sizes
    if (dimensions <= 5) {
        Register[] paddedRegs = pad35cRegs(dimensionSizeRegs);
        stmtV.addInsn(new Insn35c(Opcode.FILLED_NEW_ARRAY, dimensions, paddedRegs[0], paddedRegs[1], paddedRegs[2], paddedRegs[3], paddedRegs[4], arrayTypeItem), null);
    } else {
        stmtV.addInsn(new Insn3rc(Opcode.FILLED_NEW_ARRAY_RANGE, dimensionSizeRegs, dimensions, arrayTypeItem), null);
    }
    // check for > 255 is done already
    // move the resulting array into the destination register
    stmtV.addInsn(new Insn11x(Opcode.MOVE_RESULT_OBJECT, destinationReg), origStmt);
}
Also used : Insn35c(soot.toDex.instructions.Insn35c) Insn3rc(soot.toDex.instructions.Insn3rc) ArrayList(java.util.ArrayList) ArrayType(soot.ArrayType) Value(soot.Value) TypeReference(org.jf.dexlib2.iface.reference.TypeReference) Insn11x(soot.toDex.instructions.Insn11x)

Example 28 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class ASMBackendUtils method toTypeDesc.

/**
 * Convert type to JVM style type description
 * @param type Type to convert
 * @return JVM style type description
 */
public static String toTypeDesc(Type type) {
    final StringBuilder sb = new StringBuilder(1);
    type.apply(new TypeSwitch() {

        public void defaultCase(Type t) {
            throw new RuntimeException("Invalid type " + t.toString());
        }

        public void caseDoubleType(DoubleType t) {
            sb.append('D');
        }

        public void caseFloatType(FloatType t) {
            sb.append('F');
        }

        public void caseIntType(IntType t) {
            sb.append('I');
        }

        public void caseByteType(ByteType t) {
            sb.append('B');
        }

        public void caseShortType(ShortType t) {
            sb.append('S');
        }

        public void caseCharType(CharType t) {
            sb.append('C');
        }

        public void caseBooleanType(BooleanType t) {
            sb.append('Z');
        }

        public void caseLongType(LongType t) {
            sb.append('J');
        }

        public void caseArrayType(ArrayType t) {
            sb.append('[');
            t.getElementType().apply(this);
        }

        public void caseRefType(RefType t) {
            sb.append('L');
            sb.append(slashify(t.getClassName()));
            sb.append(';');
        }

        public void caseVoidType(VoidType t) {
            sb.append('V');
        }
    });
    return sb.toString();
}
Also used : VoidType(soot.VoidType) LongType(soot.LongType) TypeSwitch(soot.TypeSwitch) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) FloatType(soot.FloatType) IntType(soot.IntType) ArrayType(soot.ArrayType) RefType(soot.RefType) RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) DoubleWordType(soot.baf.DoubleWordType) IntType(soot.IntType) ShortType(soot.ShortType) CharType(soot.CharType) LongType(soot.LongType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) ArrayType(soot.ArrayType) Type(soot.Type) VoidType(soot.VoidType) DoubleType(soot.DoubleType) CharType(soot.CharType)

Example 29 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class OutFlow method generateJimple.

void generateJimple(Instruction ins, TypeStack typeStack, TypeStack postTypeStack, cp_info[] constant_pool, List<Stmt> statements, BasicBlock basicBlock) {
    Value[] params;
    Local l1 = null, l2 = null, l3 = null, l4 = null;
    Expr rhs = null;
    ConditionExpr co = null;
    ArrayRef a = null;
    int args;
    Value rvalue;
    // int localIndex;
    Stmt stmt = null;
    int x = ((ins.code)) & 0xff;
    switch(x) {
        case ByteCode.BIPUSH:
            rvalue = IntConstant.v(((Instruction_Bipush) ins).arg_b);
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
            break;
        case ByteCode.SIPUSH:
            rvalue = IntConstant.v(((Instruction_Sipush) ins).arg_i);
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
            break;
        case ByteCode.LDC1:
            generateJimpleForCPEntry(constant_pool, ((Instruction_Ldc1) ins).arg_b, typeStack, postTypeStack, jmethod, statements);
            break;
        case ByteCode.LDC2:
        case ByteCode.LDC2W:
            generateJimpleForCPEntry(constant_pool, ((Instruction_intindex) ins).arg_i, typeStack, postTypeStack, jmethod, statements);
            break;
        case ByteCode.ACONST_NULL:
            rvalue = NullConstant.v();
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
            break;
        case ByteCode.ICONST_M1:
        case ByteCode.ICONST_0:
        case ByteCode.ICONST_1:
        case ByteCode.ICONST_2:
        case ByteCode.ICONST_3:
        case ByteCode.ICONST_4:
        case ByteCode.ICONST_5:
            rvalue = IntConstant.v(x - ByteCode.ICONST_0);
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
            break;
        case ByteCode.LCONST_0:
        case ByteCode.LCONST_1:
            rvalue = LongConstant.v(x - ByteCode.LCONST_0);
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
            break;
        case ByteCode.FCONST_0:
        case ByteCode.FCONST_1:
        case ByteCode.FCONST_2:
            rvalue = FloatConstant.v((x - ByteCode.FCONST_0));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
            break;
        case ByteCode.DCONST_0:
        case ByteCode.DCONST_1:
            rvalue = DoubleConstant.v((x - ByteCode.DCONST_0));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
            break;
        case ByteCode.ILOAD:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.FLOAD:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.ALOAD:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.DLOAD:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.LLOAD:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.ILOAD_0:
        case ByteCode.ILOAD_1:
        case ByteCode.ILOAD_2:
        case ByteCode.ILOAD_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.ILOAD_0), ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.FLOAD_0:
        case ByteCode.FLOAD_1:
        case ByteCode.FLOAD_2:
        case ByteCode.FLOAD_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.FLOAD_0), ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.ALOAD_0:
        case ByteCode.ALOAD_1:
        case ByteCode.ALOAD_2:
        case ByteCode.ALOAD_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.ALOAD_0), ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.LLOAD_0:
        case ByteCode.LLOAD_1:
        case ByteCode.LLOAD_2:
        case ByteCode.LLOAD_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.LLOAD_0), ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.DLOAD_0:
        case ByteCode.DLOAD_1:
        case ByteCode.DLOAD_2:
        case ByteCode.DLOAD_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.DLOAD_0), ins);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), local);
                break;
            }
        case ByteCode.ISTORE:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.FSTORE:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.ASTORE:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.LSTORE:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.DSTORE:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b, ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.ISTORE_0:
        case ByteCode.ISTORE_1:
        case ByteCode.ISTORE_2:
        case ByteCode.ISTORE_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.ISTORE_0), ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.FSTORE_0:
        case ByteCode.FSTORE_1:
        case ByteCode.FSTORE_2:
        case ByteCode.FSTORE_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.FSTORE_0), ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.ASTORE_0:
        case ByteCode.ASTORE_1:
        case ByteCode.ASTORE_2:
        case ByteCode.ASTORE_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.ASTORE_0), ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.LSTORE_0:
        case ByteCode.LSTORE_1:
        case ByteCode.LSTORE_2:
        case ByteCode.LSTORE_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.LSTORE_0), ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.DSTORE_0:
        case ByteCode.DSTORE_1:
        case ByteCode.DSTORE_2:
        case ByteCode.DSTORE_3:
            {
                Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.DSTORE_0), ins);
                stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.IINC:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_Iinc) ins).arg_b, ins);
                int amt = (((Instruction_Iinc) ins).arg_c);
                rhs = Jimple.v().newAddExpr(local, IntConstant.v(amt));
                stmt = Jimple.v().newAssignStmt(local, rhs);
                break;
            }
        case ByteCode.WIDE:
            throw new RuntimeException("WIDE instruction should not be encountered anymore");
        case ByteCode.NEWARRAY:
            {
                Type baseType = jimpleTypeOfAtype(((Instruction_Newarray) ins).atype);
                rhs = Jimple.v().newNewArrayExpr(baseType, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
                break;
            }
        case ByteCode.ANEWARRAY:
            {
                String baseName = getClassName(constant_pool, ((Instruction_Anewarray) ins).arg_i);
                Type baseType;
                if (baseName.startsWith("["))
                    baseType = Util.v().jimpleTypeOfFieldDescriptor(getClassName(constant_pool, ((Instruction_Anewarray) ins).arg_i));
                else
                    baseType = RefType.v(baseName);
                rhs = Jimple.v().newNewArrayExpr(baseType, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
                break;
            }
        case ByteCode.MULTIANEWARRAY:
            {
                int bdims = (((Instruction_Multianewarray) ins).dims);
                List<Value> dims = new ArrayList<Value>();
                for (int j = 0; j < bdims; j++) dims.add(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - bdims + j + 1));
                String mstype = constant_pool[((Instruction_Multianewarray) ins).arg_i].toString(constant_pool);
                ArrayType jimpleType = (ArrayType) Util.v().jimpleTypeOfFieldDescriptor(mstype);
                rhs = Jimple.v().newNewMultiArrayExpr(jimpleType, dims);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
                break;
            }
        case ByteCode.ARRAYLENGTH:
            rhs = Jimple.v().newLengthExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.IALOAD:
        case ByteCode.BALOAD:
        case ByteCode.CALOAD:
        case ByteCode.SALOAD:
        case ByteCode.FALOAD:
        case ByteCode.LALOAD:
        case ByteCode.DALOAD:
        case ByteCode.AALOAD:
            a = Jimple.v().newArrayRef(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), a);
            break;
        case ByteCode.IASTORE:
        case ByteCode.FASTORE:
        case ByteCode.AASTORE:
        case ByteCode.BASTORE:
        case ByteCode.CASTORE:
        case ByteCode.SASTORE:
            a = Jimple.v().newArrayRef(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(a, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            break;
        case ByteCode.LASTORE:
        case ByteCode.DASTORE:
            a = Jimple.v().newArrayRef(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2));
            stmt = Jimple.v().newAssignStmt(a, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            break;
        case ByteCode.NOP:
            stmt = Jimple.v().newNopStmt();
            break;
        case ByteCode.POP:
        case ByteCode.POP2:
            stmt = Jimple.v().newNopStmt();
            break;
        case ByteCode.DUP:
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            break;
        case ByteCode.DUP2:
            if (typeSize(typeStack.top()) == 2) {
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            } else {
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                statements.add(stmt);
                stmt = null;
            }
            break;
        case ByteCode.DUP_X1:
            l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
            l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), l1);
            statements.add(stmt);
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1), l2);
            statements.add(stmt);
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()));
            statements.add(stmt);
            stmt = null;
            break;
        case ByteCode.DUP_X2:
            if (typeSize(typeStack.get(typeStack.topIndex() - 2)) == 2) {
                l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
                l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 2), l3);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 3), l1);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), l1);
                statements.add(stmt);
                stmt = null;
            } else {
                l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
                l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
                l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), l1);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1), l2);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 2), l3);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()));
                statements.add(stmt);
                stmt = null;
            }
            break;
        case ByteCode.DUP2_X1:
            if (typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) {
                l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
                l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1), l2);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 2), l3);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 4), Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1));
                statements.add(stmt);
                stmt = null;
            } else {
                l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
                l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
                l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), l1);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1), l2);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 2), l3);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()));
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 4), Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1));
                statements.add(stmt);
                stmt = null;
            }
            break;
        case ByteCode.DUP2_X2:
            if (typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) {
                l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1), l2);
                statements.add(stmt);
            } else {
                l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1), l2);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), l1);
                statements.add(stmt);
            }
            if (typeSize(typeStack.get(typeStack.topIndex() - 3)) == 2) {
                l4 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 3), l4);
                statements.add(stmt);
            } else {
                l4 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3);
                l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 3), l4);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 2), l3);
                statements.add(stmt);
            }
            if (typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) {
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 5), Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1));
                statements.add(stmt);
            } else {
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 5), Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1));
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 4), Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()));
                statements.add(stmt);
            }
            stmt = null;
            break;
        case ByteCode.SWAP:
            {
                Local first;
                typeStack = typeStack.push(typeStack.top());
                first = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                typeStack = typeStack.pop();
                // generation of a free temporary
                Local second = Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex());
                Local third = Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1);
                stmt = Jimple.v().newAssignStmt(first, second);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(second, third);
                statements.add(stmt);
                stmt = Jimple.v().newAssignStmt(third, first);
                statements.add(stmt);
                stmt = null;
                break;
            }
        case ByteCode.FADD:
        case ByteCode.IADD:
            rhs = Jimple.v().newAddExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.DADD:
        case ByteCode.LADD:
            rhs = Jimple.v().newAddExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.FSUB:
        case ByteCode.ISUB:
            rhs = Jimple.v().newSubExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.DSUB:
        case ByteCode.LSUB:
            rhs = Jimple.v().newSubExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.FMUL:
        case ByteCode.IMUL:
            rhs = Jimple.v().newMulExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.DMUL:
        case ByteCode.LMUL:
            rhs = Jimple.v().newMulExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.FDIV:
        case ByteCode.IDIV:
            rhs = Jimple.v().newDivExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.DDIV:
        case ByteCode.LDIV:
            rhs = Jimple.v().newDivExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.FREM:
        case ByteCode.IREM:
            rhs = Jimple.v().newRemExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.DREM:
        case ByteCode.LREM:
            rhs = Jimple.v().newRemExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.INEG:
        case ByteCode.LNEG:
        case ByteCode.FNEG:
        case ByteCode.DNEG:
            rhs = Jimple.v().newNegExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.ISHL:
            rhs = Jimple.v().newShlExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.ISHR:
            rhs = Jimple.v().newShrExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.IUSHR:
            rhs = Jimple.v().newUshrExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.LSHL:
            rhs = Jimple.v().newShlExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.LSHR:
            rhs = Jimple.v().newShrExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.LUSHR:
            rhs = Jimple.v().newUshrExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.IAND:
            rhs = Jimple.v().newAndExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.LAND:
            rhs = Jimple.v().newAndExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.IOR:
            rhs = Jimple.v().newOrExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.LOR:
            rhs = Jimple.v().newOrExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.IXOR:
            rhs = Jimple.v().newXorExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.LXOR:
            rhs = Jimple.v().newXorExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.D2L:
        case ByteCode.F2L:
        case ByteCode.I2L:
            rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), LongType.v());
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.D2F:
        case ByteCode.L2F:
        case ByteCode.I2F:
            rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), FloatType.v());
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.I2D:
        case ByteCode.L2D:
        case ByteCode.F2D:
            rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), DoubleType.v());
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.L2I:
        case ByteCode.F2I:
        case ByteCode.D2I:
            rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), IntType.v());
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.INT2BYTE:
            rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), ByteType.v());
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.INT2CHAR:
            rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), CharType.v());
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.INT2SHORT:
            rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), ShortType.v());
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.IFEQ:
            co = Jimple.v().newEqExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), IntConstant.v(0));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IFNULL:
            co = Jimple.v().newEqExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), NullConstant.v());
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IFLT:
            co = Jimple.v().newLtExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), IntConstant.v(0));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IFLE:
            co = Jimple.v().newLeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), IntConstant.v(0));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IFNE:
            co = Jimple.v().newNeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), IntConstant.v(0));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IFNONNULL:
            co = Jimple.v().newNeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), NullConstant.v());
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IFGT:
            co = Jimple.v().newGtExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), IntConstant.v(0));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IFGE:
            co = Jimple.v().newGeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), IntConstant.v(0));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IF_ICMPEQ:
            co = Jimple.v().newEqExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IF_ICMPLT:
            co = Jimple.v().newLtExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IF_ICMPLE:
            co = Jimple.v().newLeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IF_ICMPNE:
            co = Jimple.v().newNeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IF_ICMPGT:
            co = Jimple.v().newGtExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IF_ICMPGE:
            co = Jimple.v().newGeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.LCMP:
            rhs = Jimple.v().newCmpExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.FCMPL:
            rhs = Jimple.v().newCmplExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.FCMPG:
            rhs = Jimple.v().newCmpgExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.DCMPL:
            rhs = Jimple.v().newCmplExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.DCMPG:
            rhs = Jimple.v().newCmpgExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
            stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
            break;
        case ByteCode.IF_ACMPEQ:
            co = Jimple.v().newEqExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.IF_ACMPNE:
            co = Jimple.v().newNeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            stmt = Jimple.v().newIfStmt(co, new FutureStmt());
            break;
        case ByteCode.GOTO:
            stmt = Jimple.v().newGotoStmt(new FutureStmt());
            break;
        case ByteCode.GOTO_W:
            stmt = Jimple.v().newGotoStmt(new FutureStmt());
            break;
        case ByteCode.RET:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_Ret) ins).arg_b, ins);
                stmt = Jimple.v().newRetStmt(local);
                break;
            }
        case ByteCode.RET_W:
            {
                Local local = Util.v().getLocalForIndex(listBody, ((Instruction_Ret_w) ins).arg_i, ins);
                stmt = Jimple.v().newRetStmt(local);
                break;
            }
        case ByteCode.RETURN:
            stmt = Jimple.v().newReturnVoidStmt();
            break;
        case ByteCode.LRETURN:
        case ByteCode.DRETURN:
        case ByteCode.IRETURN:
        case ByteCode.FRETURN:
        case ByteCode.ARETURN:
            stmt = Jimple.v().newReturnStmt(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            break;
        case ByteCode.BREAKPOINT:
            stmt = Jimple.v().newBreakpointStmt();
            break;
        case ByteCode.TABLESWITCH:
            {
                int lowIndex = ((Instruction_Tableswitch) ins).low, highIndex = ((Instruction_Tableswitch) ins).high;
                int npairs = highIndex - lowIndex + 1;
                stmt = Jimple.v().newTableSwitchStmt(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), lowIndex, highIndex, Arrays.asList(new FutureStmt[npairs]), new FutureStmt());
                break;
            }
        case ByteCode.LOOKUPSWITCH:
            {
                List<IntConstant> matches = new ArrayList<IntConstant>();
                int npairs = ((Instruction_Lookupswitch) ins).npairs;
                for (int j = 0; j < npairs; j++) matches.add(IntConstant.v(((Instruction_Lookupswitch) ins).match_offsets[j * 2]));
                stmt = Jimple.v().newLookupSwitchStmt(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), matches, Arrays.asList(new FutureStmt[npairs]), new FutureStmt());
                break;
            }
        case ByteCode.PUTFIELD:
            {
                CONSTANT_Fieldref_info fieldInfo = (CONSTANT_Fieldref_info) constant_pool[((Instruction_Putfield) ins).arg_i];
                CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
                String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
                className = className.replace('/', '.');
                CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
                String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
                String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).convert();
                Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor);
                SootClass bclass = cm.getSootClass(className);
                SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass, fieldName, fieldType, false);
                InstanceFieldRef fr = Jimple.v().newInstanceFieldRef(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - typeSize(typeStack.top())), fieldRef);
                rvalue = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                stmt = Jimple.v().newAssignStmt(fr, rvalue);
                break;
            }
        case ByteCode.GETFIELD:
            {
                InstanceFieldRef fr = null;
                CONSTANT_Fieldref_info fieldInfo = (CONSTANT_Fieldref_info) constant_pool[((Instruction_Getfield) ins).arg_i];
                CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
                String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
                className = className.replace('/', '.');
                CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
                String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
                String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).convert();
                if (className.charAt(0) == '[')
                    className = "java.lang.Object";
                SootClass bclass = cm.getSootClass(className);
                Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor);
                SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass, fieldName, fieldType, false);
                fr = Jimple.v().newInstanceFieldRef(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), fieldRef);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), fr);
                break;
            }
        case ByteCode.PUTSTATIC:
            {
                StaticFieldRef fr = null;
                CONSTANT_Fieldref_info fieldInfo = (CONSTANT_Fieldref_info) constant_pool[((Instruction_Putstatic) ins).arg_i];
                CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
                String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
                className = className.replace('/', '.');
                CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
                String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
                String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).convert();
                Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor);
                SootClass bclass = cm.getSootClass(className);
                SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass, fieldName, fieldType, true);
                fr = Jimple.v().newStaticFieldRef(fieldRef);
                stmt = Jimple.v().newAssignStmt(fr, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
                break;
            }
        case ByteCode.GETSTATIC:
            {
                StaticFieldRef fr = null;
                CONSTANT_Fieldref_info fieldInfo = (CONSTANT_Fieldref_info) constant_pool[((Instruction_Getstatic) ins).arg_i];
                CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
                String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
                className = className.replace('/', '.');
                CONSTANT_NameAndType_info i = (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
                String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
                String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).convert();
                Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor);
                SootClass bclass = cm.getSootClass(className);
                SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass, fieldName, fieldType, true);
                fr = Jimple.v().newStaticFieldRef(fieldRef);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), fr);
                break;
            }
        case ByteCode.INVOKEDYNAMIC:
            {
                Instruction_Invokedynamic iv = (Instruction_Invokedynamic) ins;
                CONSTANT_InvokeDynamic_info iv_info = (CONSTANT_InvokeDynamic_info) constant_pool[iv.invoke_dynamic_index];
                args = cp_info.countParams(constant_pool, iv_info.name_and_type_index);
                SootMethodRef bootstrapMethodRef;
                List<Value> bootstrapArgs = new LinkedList<Value>();
                {
                    short[] bootstrapMethodTable = bootstrap_methods_attribute.method_handles;
                    short methodSigIndex = bootstrapMethodTable[iv_info.bootstrap_method_index];
                    CONSTANT_MethodHandle_info mhInfo = (CONSTANT_MethodHandle_info) constant_pool[methodSigIndex];
                    CONSTANT_Methodref_info bsmInfo = (CONSTANT_Methodref_info) constant_pool[mhInfo.target_index];
                    bootstrapMethodRef = createMethodRef(constant_pool, bsmInfo, false);
                    short[] bsmArgIndices = bootstrap_methods_attribute.arg_indices[iv_info.bootstrap_method_index];
                    if (bsmArgIndices.length > 0) {
                        // logger.debug("Soot does not currently support static arguments to bootstrap methods. They will be stripped.");
                        for (short bsmArgIndex : bsmArgIndices) {
                            cp_info cpEntry = constant_pool[bsmArgIndex];
                            Value val = cpEntry.createJimpleConstantValue(constant_pool);
                            bootstrapArgs.add(val);
                        }
                    }
                }
                SootMethodRef methodRef = null;
                CONSTANT_NameAndType_info nameAndTypeInfo = (CONSTANT_NameAndType_info) constant_pool[iv_info.name_and_type_index];
                String methodName = ((CONSTANT_Utf8_info) (constant_pool[nameAndTypeInfo.name_index])).convert();
                String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[nameAndTypeInfo.descriptor_index])).convert();
                SootClass bclass = cm.getSootClass(SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME);
                List<Type> parameterTypes;
                Type returnType;
                // Generate parameters & returnType & parameterTypes
                {
                    Type[] types = Util.v().jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor);
                    parameterTypes = new ArrayList<Type>();
                    for (int k = 0; k < types.length - 1; k++) {
                        parameterTypes.add(types[k]);
                    }
                    returnType = types[types.length - 1];
                }
                // we always model invokeDynamic method refs as static method references of methods on the type SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME
                methodRef = Scene.v().makeMethodRef(bclass, methodName, parameterTypes, returnType, true);
                // build Vector of parameters
                params = new Value[args];
                for (int j = args - 1; j >= 0; j--) {
                    params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                    if (typeSize(typeStack.top()) == 2) {
                        typeStack = typeStack.pop();
                        typeStack = typeStack.pop();
                    } else
                        typeStack = typeStack.pop();
                }
                rvalue = Jimple.v().newDynamicInvokeExpr(bootstrapMethodRef, bootstrapArgs, methodRef, Arrays.asList(params));
                if (!returnType.equals(VoidType.v())) {
                    stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
                } else
                    stmt = Jimple.v().newInvokeStmt(rvalue);
                break;
            }
        case ByteCode.INVOKEVIRTUAL:
            {
                Instruction_Invokevirtual iv = (Instruction_Invokevirtual) ins;
                args = cp_info.countParams(constant_pool, iv.arg_i);
                CONSTANT_Methodref_info methodInfo = (CONSTANT_Methodref_info) constant_pool[iv.arg_i];
                SootMethodRef methodRef = createMethodRef(constant_pool, methodInfo, false);
                Type returnType = methodRef.returnType();
                // build array of parameters
                params = new Value[args];
                for (int j = args - 1; j >= 0; j--) {
                    params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                    if (typeSize(typeStack.top()) == 2) {
                        typeStack = typeStack.pop();
                        typeStack = typeStack.pop();
                    } else
                        typeStack = typeStack.pop();
                }
                rvalue = Jimple.v().newVirtualInvokeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), methodRef, Arrays.asList(params));
                if (!returnType.equals(VoidType.v())) {
                    stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
                } else
                    stmt = Jimple.v().newInvokeStmt(rvalue);
                break;
            }
        case ByteCode.INVOKENONVIRTUAL:
            {
                Instruction_Invokenonvirtual iv = (Instruction_Invokenonvirtual) ins;
                args = cp_info.countParams(constant_pool, iv.arg_i);
                CONSTANT_Methodref_info methodInfo = (CONSTANT_Methodref_info) constant_pool[iv.arg_i];
                SootMethodRef methodRef = createMethodRef(constant_pool, methodInfo, false);
                Type returnType = methodRef.returnType();
                // build array of parameters
                params = new Value[args];
                for (int j = args - 1; j >= 0; j--) {
                    params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                    if (typeSize(typeStack.top()) == 2) {
                        typeStack = typeStack.pop();
                        typeStack = typeStack.pop();
                    } else
                        typeStack = typeStack.pop();
                }
                rvalue = Jimple.v().newSpecialInvokeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), methodRef, Arrays.asList(params));
                if (!returnType.equals(VoidType.v())) {
                    stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
                } else
                    stmt = Jimple.v().newInvokeStmt(rvalue);
                break;
            }
        case ByteCode.INVOKESTATIC:
            {
                Instruction_Invokestatic is = (Instruction_Invokestatic) ins;
                args = cp_info.countParams(constant_pool, is.arg_i);
                CONSTANT_Methodref_info methodInfo = (CONSTANT_Methodref_info) constant_pool[is.arg_i];
                SootMethodRef methodRef = createMethodRef(constant_pool, methodInfo, true);
                Type returnType = methodRef.returnType();
                // build Vector of parameters
                params = new Value[args];
                for (int j = args - 1; j >= 0; j--) {
                    /* logger.debug("BeforeTypeStack");
                    typeStack.print(G.v().out);

                    logger.debug("AfterTypeStack");
                    postTypeStack.print(G.v().out);
                    */
                    params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                    if (typeSize(typeStack.top()) == 2) {
                        typeStack = typeStack.pop();
                        typeStack = typeStack.pop();
                    } else
                        typeStack = typeStack.pop();
                }
                rvalue = Jimple.v().newStaticInvokeExpr(methodRef, Arrays.asList(params));
                if (!returnType.equals(VoidType.v())) {
                    stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
                } else
                    stmt = Jimple.v().newInvokeStmt(rvalue);
                break;
            }
        case ByteCode.INVOKEINTERFACE:
            {
                Instruction_Invokeinterface ii = (Instruction_Invokeinterface) ins;
                args = cp_info.countParams(constant_pool, ii.arg_i);
                CONSTANT_InterfaceMethodref_info methodInfo = (CONSTANT_InterfaceMethodref_info) constant_pool[ii.arg_i];
                SootMethodRef methodRef = createMethodRef(constant_pool, methodInfo, false);
                Type returnType = methodRef.returnType();
                // build Vector of parameters
                params = new Value[args];
                for (int j = args - 1; j >= 0; j--) {
                    params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
                    if (typeSize(typeStack.top()) == 2) {
                        typeStack = typeStack.pop();
                        typeStack = typeStack.pop();
                    } else
                        typeStack = typeStack.pop();
                }
                rvalue = Jimple.v().newInterfaceInvokeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), methodRef, Arrays.asList(params));
                if (!returnType.equals(VoidType.v())) {
                    stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue);
                } else
                    stmt = Jimple.v().newInvokeStmt(rvalue);
                break;
            }
        case ByteCode.ATHROW:
            stmt = Jimple.v().newThrowStmt(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            break;
        case ByteCode.NEW:
            {
                SootClass bclass = cm.getSootClass(getClassName(constant_pool, ((Instruction_New) ins).arg_i));
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), Jimple.v().newNewExpr(RefType.v(bclass.getName())));
                break;
            }
        case ByteCode.CHECKCAST:
            {
                String className = getClassName(constant_pool, ((Instruction_Checkcast) ins).arg_i);
                Type castType;
                if (className.startsWith("["))
                    castType = Util.v().jimpleTypeOfFieldDescriptor(getClassName(constant_pool, ((Instruction_Checkcast) ins).arg_i));
                else
                    castType = RefType.v(className);
                rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), castType);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
                break;
            }
        case ByteCode.INSTANCEOF:
            {
                Type checkType;
                String className = getClassName(constant_pool, ((Instruction_Instanceof) ins).arg_i);
                if (className.startsWith("["))
                    checkType = Util.v().jimpleTypeOfFieldDescriptor(getClassName(constant_pool, ((Instruction_Instanceof) ins).arg_i));
                else
                    checkType = RefType.v(className);
                rhs = Jimple.v().newInstanceOfExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), checkType);
                stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rhs);
                break;
            }
        case ByteCode.MONITORENTER:
            stmt = Jimple.v().newEnterMonitorStmt(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            break;
        case ByteCode.MONITOREXIT:
            stmt = Jimple.v().newExitMonitorStmt(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
            break;
        default:
            throw new RuntimeException("Unrecognized bytecode instruction: " + x);
    }
    if (stmt != null) {
        if (Options.v().keep_offset()) {
            stmt.addTag(new BytecodeOffsetTag(ins.label));
        }
        statements.add(stmt);
    }
}
Also used : ArrayType(soot.ArrayType) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Local(soot.Local) SootFieldRef(soot.SootFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) ConditionExpr(soot.jimple.ConditionExpr) Expr(soot.jimple.Expr) Value(soot.Value) BytecodeOffsetTag(soot.tagkit.BytecodeOffsetTag) GotoStmt(soot.jimple.GotoStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) TableSwitchStmt(soot.jimple.TableSwitchStmt) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) Stmt(soot.jimple.Stmt) ArrayRef(soot.jimple.ArrayRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) IntConstant(soot.jimple.IntConstant) SootMethodRef(soot.SootMethodRef) SootClass(soot.SootClass) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) UnknownType(soot.UnknownType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) StmtAddressType(soot.StmtAddressType) ArrayType(soot.ArrayType) VoidType(soot.VoidType) ConditionExpr(soot.jimple.ConditionExpr)

Example 30 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class BafASMBackend method generateInstruction.

/**
 * Emits the bytecode for a single Baf instruction
 *
 * @param mv
 *            The ASM MethodVisitor the bytecode is to be emitted to
 * @param inst
 *            The Baf instruction to be converted into bytecode
 */
protected void generateInstruction(final MethodVisitor mv, Inst inst) {
    inst.apply(new InstSwitch() {

        @Override
        public void caseReturnVoidInst(ReturnVoidInst i) {
            mv.visitInsn(Opcodes.RETURN);
        }

        @Override
        public void caseReturnInst(ReturnInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    mv.visitInsn(Opcodes.ARETURN);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.IRETURN);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.IRETURN);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.IRETURN);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DRETURN);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FRETURN);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.IRETURN);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LRETURN);
                }

                @Override
                public void caseRefType(RefType t) {
                    mv.visitInsn(Opcodes.ARETURN);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.IRETURN);
                }

                @Override
                public void caseNullType(NullType t) {
                    mv.visitInsn(Opcodes.ARETURN);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid return type " + t.toString());
                }
            });
        }

        @Override
        public void caseNopInst(NopInst i) {
            mv.visitInsn(Opcodes.NOP);
        }

        @Override
        public void caseJSRInst(JSRInst i) {
            mv.visitJumpInsn(Opcodes.JSR, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void casePushInst(PushInst i) {
            Constant c = i.getConstant();
            if (c instanceof IntConstant) {
                int v = ((IntConstant) c).value;
                switch(v) {
                    case -1:
                        mv.visitInsn(Opcodes.ICONST_M1);
                        break;
                    case 0:
                        mv.visitInsn(Opcodes.ICONST_0);
                        break;
                    case 1:
                        mv.visitInsn(Opcodes.ICONST_1);
                        break;
                    case 2:
                        mv.visitInsn(Opcodes.ICONST_2);
                        break;
                    case 3:
                        mv.visitInsn(Opcodes.ICONST_3);
                        break;
                    case 4:
                        mv.visitInsn(Opcodes.ICONST_4);
                        break;
                    case 5:
                        mv.visitInsn(Opcodes.ICONST_5);
                        break;
                    default:
                        if (v >= Byte.MIN_VALUE && v <= Byte.MAX_VALUE) {
                            mv.visitIntInsn(Opcodes.BIPUSH, v);
                        } else if (v >= Short.MIN_VALUE && v <= Short.MAX_VALUE) {
                            mv.visitIntInsn(Opcodes.SIPUSH, v);
                        } else {
                            mv.visitLdcInsn(v);
                        }
                }
            } else if (c instanceof StringConstant) {
                mv.visitLdcInsn(((StringConstant) c).value);
            } else if (c instanceof ClassConstant) {
                mv.visitLdcInsn(org.objectweb.asm.Type.getType(((ClassConstant) c).getValue()));
            } else if (c instanceof DoubleConstant) {
                double v = ((DoubleConstant) c).value;
                /*
					 * Do not emit a DCONST_0 for negative zero, therefore we
					 * need the following check.
					 */
                if (new Double(v).equals(0.0)) {
                    mv.visitInsn(Opcodes.DCONST_0);
                } else if (v == 1) {
                    mv.visitInsn(Opcodes.DCONST_1);
                } else {
                    mv.visitLdcInsn(v);
                }
            } else if (c instanceof FloatConstant) {
                float v = ((FloatConstant) c).value;
                /*
					 * Do not emit a FCONST_0 for negative zero, therefore we
					 * need the following check.
					 */
                if (new Float(v).equals(0.0f)) {
                    mv.visitInsn(Opcodes.FCONST_0);
                } else if (v == 1) {
                    mv.visitInsn(Opcodes.FCONST_1);
                } else if (v == 2) {
                    mv.visitInsn(Opcodes.FCONST_2);
                } else {
                    mv.visitLdcInsn(v);
                }
            } else if (c instanceof LongConstant) {
                long v = ((LongConstant) c).value;
                if (v == 0) {
                    mv.visitInsn(Opcodes.LCONST_0);
                } else if (v == 1) {
                    mv.visitInsn(Opcodes.LCONST_1);
                } else {
                    mv.visitLdcInsn(v);
                }
            } else if (c instanceof NullConstant) {
                mv.visitInsn(Opcodes.ACONST_NULL);
            } else if (c instanceof MethodHandle) {
                SootMethodRef ref = ((MethodHandle) c).getMethodRef();
                int tag;
                if (ref.isStatic()) {
                    tag = Opcodes.H_INVOKESTATIC;
                } else if (ref.declaringClass().isInterface()) {
                    tag = Opcodes.H_INVOKEINTERFACE;
                } else {
                    tag = Opcodes.H_INVOKEVIRTUAL;
                }
                Handle handle = new Handle(tag, ref.declaringClass().getName(), ref.name(), ref.getSignature(), ref.declaringClass().isInnerClass());
                mv.visitLdcInsn(handle);
            } else {
                throw new RuntimeException("unsupported opcode");
            }
        }

        @Override
        public void casePopInst(PopInst i) {
            if (i.getWordCount() == 2) {
                mv.visitInsn(Opcodes.POP2);
            } else {
                mv.visitInsn(Opcodes.POP);
            }
        }

        @Override
        public void caseIdentityInst(IdentityInst i) {
            Value l = i.getLeftOp();
            Value r = i.getRightOp();
            if (r instanceof CaughtExceptionRef && l instanceof Local) {
                mv.visitVarInsn(Opcodes.ASTORE, localToSlot.get(l));
            // asm handles constant opcodes automatically here
            }
        }

        @Override
        public void caseStoreInst(StoreInst i) {
            final int slot = localToSlot.get(i.getLocal());
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    mv.visitVarInsn(Opcodes.ASTORE, slot);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitVarInsn(Opcodes.ISTORE, slot);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitVarInsn(Opcodes.ISTORE, slot);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitVarInsn(Opcodes.ISTORE, slot);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitVarInsn(Opcodes.DSTORE, slot);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitVarInsn(Opcodes.FSTORE, slot);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitVarInsn(Opcodes.ISTORE, slot);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitVarInsn(Opcodes.LSTORE, slot);
                }

                @Override
                public void caseRefType(RefType t) {
                    mv.visitVarInsn(Opcodes.ASTORE, slot);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitVarInsn(Opcodes.ISTORE, slot);
                }

                @Override
                public void caseStmtAddressType(StmtAddressType t) {
                    throw new RuntimeException("JSR not supported, use recent Java compiler!");
                }

                @Override
                public void caseNullType(NullType t) {
                    mv.visitVarInsn(Opcodes.ASTORE, slot);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid local type: " + t);
                }
            });
        }

        @Override
        public void caseGotoInst(GotoInst i) {
            mv.visitJumpInsn(Opcodes.GOTO, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseLoadInst(LoadInst i) {
            final int slot = localToSlot.get(i.getLocal());
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    mv.visitVarInsn(Opcodes.ALOAD, slot);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitVarInsn(Opcodes.ILOAD, slot);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitVarInsn(Opcodes.ILOAD, slot);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitVarInsn(Opcodes.ILOAD, slot);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitVarInsn(Opcodes.DLOAD, slot);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitVarInsn(Opcodes.FLOAD, slot);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitVarInsn(Opcodes.ILOAD, slot);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitVarInsn(Opcodes.LLOAD, slot);
                }

                @Override
                public void caseRefType(RefType t) {
                    mv.visitVarInsn(Opcodes.ALOAD, slot);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitVarInsn(Opcodes.ILOAD, slot);
                }

                @Override
                public void caseNullType(NullType t) {
                    mv.visitVarInsn(Opcodes.ALOAD, slot);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid local type: " + t);
                }
            });
        }

        @Override
        public void caseArrayWriteInst(ArrayWriteInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    mv.visitInsn(Opcodes.AASTORE);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.BASTORE);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.BASTORE);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.CASTORE);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DASTORE);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FASTORE);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.IASTORE);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LASTORE);
                }

                @Override
                public void caseRefType(RefType t) {
                    mv.visitInsn(Opcodes.AASTORE);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.SASTORE);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid type: " + t);
                }
            });
        }

        @Override
        public void caseArrayReadInst(ArrayReadInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    mv.visitInsn(Opcodes.AALOAD);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.BALOAD);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.BALOAD);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.CALOAD);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DALOAD);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FALOAD);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.IALOAD);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LALOAD);
                }

                @Override
                public void caseRefType(RefType t) {
                    mv.visitInsn(Opcodes.AALOAD);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.SALOAD);
                }

                @Override
                public void caseNullType(NullType t) {
                    mv.visitInsn(Opcodes.AALOAD);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid type: " + t);
                }
            });
        }

        @Override
        public void caseIfNullInst(IfNullInst i) {
            mv.visitJumpInsn(Opcodes.IFNULL, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseIfNonNullInst(IfNonNullInst i) {
            mv.visitJumpInsn(Opcodes.IFNONNULL, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseIfEqInst(IfEqInst i) {
            mv.visitJumpInsn(Opcodes.IFEQ, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseIfNeInst(IfNeInst i) {
            mv.visitJumpInsn(Opcodes.IFNE, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseIfGtInst(IfGtInst i) {
            mv.visitJumpInsn(Opcodes.IFGT, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseIfGeInst(IfGeInst i) {
            mv.visitJumpInsn(Opcodes.IFGE, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseIfLtInst(IfLtInst i) {
            mv.visitJumpInsn(Opcodes.IFLT, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseIfLeInst(IfLeInst i) {
            mv.visitJumpInsn(Opcodes.IFLE, getBranchTargetLabel(i.getTarget()));
        }

        @Override
        public void caseIfCmpEqInst(final IfCmpEqInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    mv.visitJumpInsn(Opcodes.IF_ACMPEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DCMPG);
                    mv.visitJumpInsn(Opcodes.IFEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FCMPG);
                    mv.visitJumpInsn(Opcodes.IFEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LCMP);
                    mv.visitJumpInsn(Opcodes.IFEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    mv.visitJumpInsn(Opcodes.IF_ACMPEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    mv.visitJumpInsn(Opcodes.IF_ACMPEQ, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpNeInst(final IfCmpNeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    mv.visitJumpInsn(Opcodes.IF_ACMPNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DCMPG);
                    mv.visitJumpInsn(Opcodes.IFNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FCMPG);
                    mv.visitJumpInsn(Opcodes.IFNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LCMP);
                    mv.visitJumpInsn(Opcodes.IFNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    mv.visitJumpInsn(Opcodes.IF_ACMPNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    mv.visitJumpInsn(Opcodes.IF_ACMPNE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpGtInst(final IfCmpGtInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DCMPG);
                    mv.visitJumpInsn(Opcodes.IFGT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FCMPG);
                    mv.visitJumpInsn(Opcodes.IFGT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LCMP);
                    mv.visitJumpInsn(Opcodes.IFGT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpGeInst(final IfCmpGeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DCMPG);
                    mv.visitJumpInsn(Opcodes.IFGE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FCMPG);
                    mv.visitJumpInsn(Opcodes.IFGE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LCMP);
                    mv.visitJumpInsn(Opcodes.IFGE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpLtInst(final IfCmpLtInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DCMPG);
                    mv.visitJumpInsn(Opcodes.IFLT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FCMPG);
                    mv.visitJumpInsn(Opcodes.IFLT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LCMP);
                    mv.visitJumpInsn(Opcodes.IFLT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLT, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpLeInst(final IfCmpLeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DCMPG);
                    mv.visitJumpInsn(Opcodes.IFLE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FCMPG);
                    mv.visitJumpInsn(Opcodes.IFLE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LCMP);
                    mv.visitJumpInsn(Opcodes.IFLE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLE, getBranchTargetLabel(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseStaticGetInst(StaticGetInst i) {
            SootFieldRef field = i.getFieldRef();
            mv.visitFieldInsn(Opcodes.GETSTATIC, slashify(field.declaringClass().getName()), field.name(), toTypeDesc(field.type()));
        }

        @Override
        public void caseStaticPutInst(StaticPutInst i) {
            SootFieldRef field = i.getFieldRef();
            mv.visitFieldInsn(Opcodes.PUTSTATIC, slashify(field.declaringClass().getName()), field.name(), toTypeDesc(field.type()));
        }

        @Override
        public void caseFieldGetInst(FieldGetInst i) {
            SootFieldRef field = i.getFieldRef();
            mv.visitFieldInsn(Opcodes.GETFIELD, slashify(field.declaringClass().getName()), field.name(), toTypeDesc(field.type()));
        }

        @Override
        public void caseFieldPutInst(FieldPutInst i) {
            SootFieldRef field = i.getFieldRef();
            mv.visitFieldInsn(Opcodes.PUTFIELD, slashify(field.declaringClass().getName()), field.name(), toTypeDesc(field.type()));
        }

        @Override
        public void caseInstanceCastInst(InstanceCastInst i) {
            Type castType = i.getCastType();
            if (castType instanceof RefType) {
                mv.visitTypeInsn(Opcodes.CHECKCAST, slashify(((RefType) castType).getClassName()));
            } else if (castType instanceof ArrayType) {
                mv.visitTypeInsn(Opcodes.CHECKCAST, toTypeDesc(castType));
            }
        }

        @Override
        public void caseInstanceOfInst(InstanceOfInst i) {
            Type checkType = i.getCheckType();
            if (checkType instanceof RefType) {
                mv.visitTypeInsn(Opcodes.INSTANCEOF, slashify(((RefType) checkType).getClassName()));
            } else if (checkType instanceof ArrayType) {
                mv.visitTypeInsn(Opcodes.INSTANCEOF, toTypeDesc(checkType));
            }
        }

        @Override
        public void casePrimitiveCastInst(PrimitiveCastInst i) {
            Type from = i.getFromType();
            final Type to = i.getToType();
            from.apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    emitIntToTypeCast();
                }

                @Override
                public void caseByteType(ByteType t) {
                    emitIntToTypeCast();
                }

                @Override
                public void caseCharType(CharType t) {
                    emitIntToTypeCast();
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    if (to.equals(IntType.v())) {
                        mv.visitInsn(Opcodes.D2I);
                    } else if (to.equals(LongType.v())) {
                        mv.visitInsn(Opcodes.D2L);
                    } else if (to.equals(FloatType.v())) {
                        mv.visitInsn(Opcodes.D2F);
                    } else {
                        throw new RuntimeException("invalid to-type from double");
                    }
                }

                @Override
                public void caseFloatType(FloatType t) {
                    if (to.equals(IntType.v())) {
                        mv.visitInsn(Opcodes.F2I);
                    } else if (to.equals(LongType.v())) {
                        mv.visitInsn(Opcodes.F2L);
                    } else if (to.equals(DoubleType.v())) {
                        mv.visitInsn(Opcodes.F2D);
                    } else {
                        throw new RuntimeException("invalid to-type from float");
                    }
                }

                @Override
                public void caseIntType(IntType t) {
                    emitIntToTypeCast();
                }

                @Override
                public void caseLongType(LongType t) {
                    if (to.equals(IntType.v())) {
                        mv.visitInsn(Opcodes.L2I);
                    } else if (to.equals(FloatType.v())) {
                        mv.visitInsn(Opcodes.L2F);
                    } else if (to.equals(DoubleType.v())) {
                        mv.visitInsn(Opcodes.L2D);
                    } else {
                        throw new RuntimeException("invalid to-type from long");
                    }
                }

                @Override
                public void caseShortType(ShortType t) {
                    emitIntToTypeCast();
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid from-type: " + t);
                }

                private void emitIntToTypeCast() {
                    if (to.equals(ByteType.v())) {
                        mv.visitInsn(Opcodes.I2B);
                    } else if (to.equals(CharType.v())) {
                        mv.visitInsn(Opcodes.I2C);
                    } else if (to.equals(ShortType.v())) {
                        mv.visitInsn(Opcodes.I2S);
                    } else if (to.equals(FloatType.v())) {
                        mv.visitInsn(Opcodes.I2F);
                    } else if (to.equals(LongType.v())) {
                        mv.visitInsn(Opcodes.I2L);
                    } else if (to.equals(DoubleType.v())) {
                        mv.visitInsn(Opcodes.I2D);
                    } else if (to.equals(IntType.v())) {
                    } else if (to.equals(BooleanType.v())) {
                    } else {
                        throw new RuntimeException("invalid to-type from int");
                    }
                }
            });
        }

        @Override
        public void caseDynamicInvokeInst(DynamicInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            SootMethodRef bsm = i.getBootstrapMethodRef();
            List<Value> args = i.getBootstrapArgs();
            final Object[] argsArray = new Object[args.size()];
            int index = 0;
            for (Value v : args) {
                final int j = index;
                v.apply(new ConstantSwitch() {

                    @Override
                    public void defaultCase(Object object) {
                        throw new RuntimeException("Unexpected constant type!");
                    }

                    @Override
                    public void caseStringConstant(StringConstant v) {
                        argsArray[j] = v.value;
                    }

                    @Override
                    public void caseNullConstant(NullConstant v) {
                        /*
							 * The Jasmin-backend throws an exception for the
							 * null-type.
							 */
                        throw new RuntimeException("Unexpected NullType as argument-type in invokedynamic!");
                    }

                    @Override
                    public void caseMethodHandle(MethodHandle handle) {
                        SootMethodRef methodRef = handle.getMethodRef();
                        argsArray[j] = new Handle(handle.tag, slashify(methodRef.declaringClass().getName()), methodRef.name(), toTypeDesc(methodRef));
                    }

                    @Override
                    public void caseLongConstant(LongConstant v) {
                        argsArray[j] = v.value;
                    }

                    @Override
                    public void caseIntConstant(IntConstant v) {
                        argsArray[j] = v.value;
                    }

                    @Override
                    public void caseFloatConstant(FloatConstant v) {
                        argsArray[j] = v.value;
                    }

                    @Override
                    public void caseDoubleConstant(DoubleConstant v) {
                        argsArray[j] = v.value;
                    }

                    @Override
                    public void caseClassConstant(ClassConstant v) {
                        argsArray[j] = org.objectweb.asm.Type.getType(v.getValue());
                    }
                });
                ++index;
            }
            mv.visitInvokeDynamicInsn(m.name(), toTypeDesc(m), new Handle(i.getHandleTag(), slashify(bsm.declaringClass().getName()), bsm.name(), toTypeDesc(bsm)), argsArray);
        }

        @Override
        public void caseStaticInvokeInst(StaticInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, slashify(m.declaringClass().getName()), m.name(), toTypeDesc(m), m.declaringClass().isInterface() && !m.isStatic());
        }

        @Override
        public void caseVirtualInvokeInst(VirtualInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, slashify(m.declaringClass().getName()), m.name(), toTypeDesc(m), m.declaringClass().isInterface());
        }

        @Override
        public void caseInterfaceInvokeInst(InterfaceInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            SootClass declaration = m.declaringClass();
            boolean isInterface = true;
            if (!declaration.isPhantom() && !declaration.isInterface()) {
                /*
					 * If the declaring class of a method called via
					 * invokeinterface is a phantom class we assume the
					 * declaring class to be an interface. This might not be
					 * true in general, but as of today Soot can not evaluate
					 * isInterface() for phantom classes correctly.
					 */
                isInterface = false;
            }
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, slashify(declaration.getName()), m.name(), toTypeDesc(m), isInterface);
        }

        @Override
        public void caseSpecialInvokeInst(SpecialInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, slashify(m.declaringClass().getName()), m.name(), toTypeDesc(m), m.declaringClass().isInterface());
        }

        @Override
        public void caseThrowInst(ThrowInst i) {
            mv.visitInsn(Opcodes.ATHROW);
        }

        @Override
        public void caseAddInst(AddInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.IADD);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.IADD);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.IADD);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DADD);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FADD);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.IADD);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LADD);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.IADD);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseAndInst(AndInst i) {
            if (i.getOpType().equals(LongType.v())) {
                mv.visitInsn(Opcodes.LAND);
            } else {
                mv.visitInsn(Opcodes.IAND);
            }
        }

        @Override
        public void caseOrInst(OrInst i) {
            if (i.getOpType().equals(LongType.v())) {
                mv.visitInsn(Opcodes.LOR);
            } else {
                mv.visitInsn(Opcodes.IOR);
            }
        }

        @Override
        public void caseXorInst(XorInst i) {
            if (i.getOpType().equals(LongType.v())) {
                mv.visitInsn(Opcodes.LXOR);
            } else {
                mv.visitInsn(Opcodes.IXOR);
            }
        }

        @Override
        public void caseArrayLengthInst(ArrayLengthInst i) {
            mv.visitInsn(Opcodes.ARRAYLENGTH);
        }

        @Override
        public void caseCmpInst(CmpInst i) {
            mv.visitInsn(Opcodes.LCMP);
        }

        @Override
        public void caseCmpgInst(CmpgInst i) {
            if (i.getOpType().equals(FloatType.v())) {
                mv.visitInsn(Opcodes.FCMPG);
            } else {
                mv.visitInsn(Opcodes.DCMPG);
            }
        }

        @Override
        public void caseCmplInst(CmplInst i) {
            if (i.getOpType().equals(FloatType.v())) {
                mv.visitInsn(Opcodes.FCMPL);
            } else {
                mv.visitInsn(Opcodes.DCMPL);
            }
        }

        @Override
        public void caseDivInst(DivInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.IDIV);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.IDIV);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.IDIV);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DDIV);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FDIV);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.IDIV);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LDIV);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.IDIV);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIncInst(IncInst i) {
            if (i.getUseBoxes().get(0).getValue() != i.getDefBoxes().get(0).getValue()) {
                throw new RuntimeException("iinc def and use boxes don't match");
            }
            if (i.getConstant() instanceof IntConstant) {
                mv.visitIincInsn(localToSlot.get(i.getLocal()), ((IntConstant) i.getConstant()).value);
            } else {
                throw new RuntimeException("Wrong constant type for increment!");
            }
        }

        @Override
        public void caseMulInst(MulInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.IMUL);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.IMUL);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.IMUL);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DMUL);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FMUL);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.IMUL);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LMUL);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.IMUL);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseRemInst(RemInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.IREM);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.IREM);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.IREM);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DREM);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FREM);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.IREM);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LREM);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.IREM);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseSubInst(SubInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.ISUB);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.ISUB);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.ISUB);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DSUB);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FSUB);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.ISUB);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LSUB);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.ISUB);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseShlInst(ShlInst i) {
            if (i.getOpType().equals(LongType.v())) {
                mv.visitInsn(Opcodes.LSHL);
            } else {
                mv.visitInsn(Opcodes.ISHL);
            }
        }

        @Override
        public void caseShrInst(ShrInst i) {
            if (i.getOpType().equals(LongType.v())) {
                mv.visitInsn(Opcodes.LSHR);
            } else {
                mv.visitInsn(Opcodes.ISHR);
            }
        }

        @Override
        public void caseUshrInst(UshrInst i) {
            if (i.getOpType().equals(LongType.v())) {
                mv.visitInsn(Opcodes.LUSHR);
            } else {
                mv.visitInsn(Opcodes.IUSHR);
            }
        }

        @Override
        public void caseNewInst(NewInst i) {
            mv.visitTypeInsn(Opcodes.NEW, slashify(i.getBaseType().getClassName()));
        }

        @Override
        public void caseNegInst(NegInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseBooleanType(BooleanType t) {
                    mv.visitInsn(Opcodes.INEG);
                }

                @Override
                public void caseByteType(ByteType t) {
                    mv.visitInsn(Opcodes.INEG);
                }

                @Override
                public void caseCharType(CharType t) {
                    mv.visitInsn(Opcodes.INEG);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    mv.visitInsn(Opcodes.DNEG);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    mv.visitInsn(Opcodes.FNEG);
                }

                @Override
                public void caseIntType(IntType t) {
                    mv.visitInsn(Opcodes.INEG);
                }

                @Override
                public void caseLongType(LongType t) {
                    mv.visitInsn(Opcodes.LNEG);
                }

                @Override
                public void caseShortType(ShortType t) {
                    mv.visitInsn(Opcodes.INEG);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseSwapInst(SwapInst i) {
            mv.visitInsn(Opcodes.SWAP);
        }

        @Override
        public void caseDup1Inst(Dup1Inst i) {
            if (sizeOfType(i.getOp1Type()) == 2) {
                mv.visitInsn(Opcodes.DUP2);
            } else {
                mv.visitInsn(Opcodes.DUP);
            }
        }

        @Override
        public void caseDup2Inst(Dup2Inst i) {
            Type firstOpType = i.getOp1Type();
            Type secondOpType = i.getOp2Type();
            // Use a pair of instructions to simulate them.
            if (sizeOfType(firstOpType) == 2) {
                mv.visitInsn(Opcodes.DUP2);
                if (sizeOfType(secondOpType) == 2) {
                    mv.visitInsn(Opcodes.DUP2);
                } else {
                    mv.visitInsn(Opcodes.DUP);
                }
            } else if (sizeOfType(secondOpType) == 2) {
                mv.visitInsn(Opcodes.DUP);
                mv.visitInsn(Opcodes.DUP2);
            } else {
                mv.visitInsn(Opcodes.DUP2);
            }
        }

        @Override
        public void caseDup1_x1Inst(Dup1_x1Inst i) {
            Type opType = i.getOp1Type();
            Type underType = i.getUnder1Type();
            if (sizeOfType(opType) == 2) {
                if (sizeOfType(underType) == 2) {
                    mv.visitInsn(Opcodes.DUP2_X2);
                } else {
                    mv.visitInsn(Opcodes.DUP2_X1);
                }
            } else {
                if (sizeOfType(underType) == 2) {
                    mv.visitInsn(Opcodes.DUP_X2);
                } else {
                    mv.visitInsn(Opcodes.DUP_X1);
                }
            }
        }

        @Override
        public void caseDup1_x2Inst(Dup1_x2Inst i) {
            int toSkip = sizeOfType(i.getUnder1Type()) + sizeOfType(i.getUnder2Type());
            if (sizeOfType(i.getOp1Type()) == 2) {
                if (toSkip == 2) {
                    mv.visitInsn(Opcodes.DUP2_X2);
                } else {
                    throw new RuntimeException("magic not implemented yet");
                }
            } else {
                if (toSkip == 2) {
                    mv.visitInsn(Opcodes.DUP_X2);
                } else {
                    throw new RuntimeException("magic not implemented yet");
                }
            }
        }

        @Override
        public void caseDup2_x1Inst(Dup2_x1Inst i) {
            int toDup = sizeOfType(i.getOp1Type()) + sizeOfType(i.getOp2Type());
            if (toDup == 2) {
                if (sizeOfType(i.getUnder1Type()) == 2) {
                    mv.visitInsn(Opcodes.DUP2_X2);
                } else {
                    mv.visitInsn(Opcodes.DUP2_X1);
                }
            } else {
                throw new RuntimeException("magic not implemented yet");
            }
        }

        @Override
        public void caseDup2_x2Inst(Dup2_x2Inst i) {
            int toDup = sizeOfType(i.getOp1Type()) + sizeOfType(i.getOp2Type());
            int toSkip = sizeOfType(i.getUnder1Type()) + sizeOfType(i.getUnder2Type());
            if (toDup > 2 || toSkip > 2) {
                throw new RuntimeException("magic not implemented yet");
            }
            if (toDup == 2 && toSkip == 2) {
                mv.visitInsn(Opcodes.DUP2_X2);
            } else {
                throw new RuntimeException("VoidType not allowed in Dup2_x2 Instruction");
            }
        }

        @Override
        public void caseNewArrayInst(NewArrayInst i) {
            Type t = i.getBaseType();
            if (t instanceof RefType) {
                mv.visitTypeInsn(Opcodes.ANEWARRAY, slashify(((RefType) t).getClassName()));
            } else if (t instanceof ArrayType) {
                mv.visitTypeInsn(Opcodes.ANEWARRAY, toTypeDesc(t));
            } else {
                int type;
                if (t.equals(BooleanType.v())) {
                    type = Opcodes.T_BOOLEAN;
                } else if (t.equals(CharType.v())) {
                    type = Opcodes.T_CHAR;
                } else if (t.equals(FloatType.v())) {
                    type = Opcodes.T_FLOAT;
                } else if (t.equals(DoubleType.v())) {
                    type = Opcodes.T_DOUBLE;
                } else if (t.equals(ByteType.v())) {
                    type = Opcodes.T_BYTE;
                } else if (t.equals(ShortType.v())) {
                    type = Opcodes.T_SHORT;
                } else if (t.equals(IntType.v())) {
                    type = Opcodes.T_INT;
                } else if (t.equals(LongType.v())) {
                    type = Opcodes.T_LONG;
                } else {
                    throw new RuntimeException("invalid type");
                }
                mv.visitIntInsn(Opcodes.NEWARRAY, type);
            }
        }

        @Override
        public void caseNewMultiArrayInst(NewMultiArrayInst i) {
            mv.visitMultiANewArrayInsn(toTypeDesc(i.getBaseType()), i.getDimensionCount());
        }

        @Override
        public void caseLookupSwitchInst(LookupSwitchInst i) {
            List<IntConstant> values = i.getLookupValues();
            List<Unit> targets = i.getTargets();
            int[] keys = new int[values.size()];
            Label[] labels = new Label[values.size()];
            for (int j = 0; j < values.size(); j++) {
                keys[j] = values.get(j).value;
                labels[j] = branchTargetLabels.get(targets.get(j));
            }
            mv.visitLookupSwitchInsn(branchTargetLabels.get(i.getDefaultTarget()), keys, labels);
        }

        @Override
        public void caseTableSwitchInst(TableSwitchInst i) {
            List<Unit> targets = i.getTargets();
            Label[] labels = new Label[targets.size()];
            for (int j = 0; j < targets.size(); j++) {
                labels[j] = branchTargetLabels.get(targets.get(j));
            }
            mv.visitTableSwitchInsn(i.getLowIndex(), i.getHighIndex(), branchTargetLabels.get(i.getDefaultTarget()), labels);
        }

        @Override
        public void caseEnterMonitorInst(EnterMonitorInst i) {
            mv.visitInsn(Opcodes.MONITORENTER);
        }

        @Override
        public void caseExitMonitorInst(ExitMonitorInst i) {
            mv.visitInsn(Opcodes.MONITOREXIT);
        }
    });
}
Also used : TypeSwitch(soot.TypeSwitch) ByteType(soot.ByteType) FloatType(soot.FloatType) ShortType(soot.ShortType) BafLocal(soot.baf.internal.BafLocal) Local(soot.Local) MethodHandle(soot.jimple.MethodHandle) Handle(org.objectweb.asm.Handle) MethodHandle(soot.jimple.MethodHandle) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) IntType(soot.IntType) IntConstant(soot.jimple.IntConstant) LongConstant(soot.jimple.LongConstant) BooleanType(soot.BooleanType) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) NullType(soot.NullType) StmtAddressType(soot.StmtAddressType) ArrayType(soot.ArrayType) ASMBackendUtils.sizeOfType(soot.util.backend.ASMBackendUtils.sizeOfType) StmtAddressType(soot.StmtAddressType) ConstantSwitch(soot.jimple.ConstantSwitch) ArrayType(soot.ArrayType) RefType(soot.RefType) List(java.util.List) SootFieldRef(soot.SootFieldRef) Value(soot.Value) CharType(soot.CharType) NullType(soot.NullType) StringConstant(soot.jimple.StringConstant) ClassConstant(soot.jimple.ClassConstant) DoubleConstant(soot.jimple.DoubleConstant) LongType(soot.LongType) NullConstant(soot.jimple.NullConstant) Constant(soot.jimple.Constant) LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) IntConstant(soot.jimple.IntConstant) ClassConstant(soot.jimple.ClassConstant) StringConstant(soot.jimple.StringConstant) FloatConstant(soot.jimple.FloatConstant) FloatConstant(soot.jimple.FloatConstant) SootMethodRef(soot.SootMethodRef) NullConstant(soot.jimple.NullConstant) SootClass(soot.SootClass) DoubleType(soot.DoubleType)

Aggregations

ArrayType (soot.ArrayType)44 Type (soot.Type)34 RefType (soot.RefType)26 Local (soot.Local)19 Value (soot.Value)18 IntType (soot.IntType)17 BooleanType (soot.BooleanType)14 NewArrayExpr (soot.jimple.NewArrayExpr)13 ByteType (soot.ByteType)12 FloatType (soot.FloatType)12 NullType (soot.NullType)12 ShortType (soot.ShortType)12 ArrayRef (soot.jimple.ArrayRef)12 CharType (soot.CharType)11 DoubleType (soot.DoubleType)11 LongType (soot.LongType)11 AssignStmt (soot.jimple.AssignStmt)11 SootClass (soot.SootClass)10 InvokeExpr (soot.jimple.InvokeExpr)10 PrimType (soot.PrimType)9