Search in sources :

Example 11 with StaticFieldRef

use of soot.jimple.StaticFieldRef in project soot by Sable.

the class SideEffectAnalysis method addValue.

protected RWSet addValue(Value v, SootMethod m, Stmt s) {
    RWSet ret = null;
    if (v instanceof InstanceFieldRef) {
        InstanceFieldRef ifr = (InstanceFieldRef) v;
        PointsToSet base = pa.reachingObjects((Local) ifr.getBase());
        ret = new StmtRWSet();
        ret.addFieldRef(base, ifr.getField());
    } else if (v instanceof StaticFieldRef) {
        StaticFieldRef sfr = (StaticFieldRef) v;
        ret = new StmtRWSet();
        ret.addGlobal(sfr.getField());
    } else if (v instanceof ArrayRef) {
        ArrayRef ar = (ArrayRef) v;
        PointsToSet base = pa.reachingObjects((Local) ar.getBase());
        ret = new StmtRWSet();
        ret.addFieldRef(base, PointsToAnalysis.ARRAY_ELEMENTS_NODE);
    }
    return ret;
}
Also used : ArrayRef(soot.jimple.ArrayRef) PointsToSet(soot.PointsToSet) InstanceFieldRef(soot.jimple.InstanceFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef)

Example 12 with StaticFieldRef

use of soot.jimple.StaticFieldRef in project soot by Sable.

the class ConstraintChecker method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value l = stmt.getLeftOp();
    Value r = stmt.getRightOp();
    TypeNode left = null;
    TypeNode right = null;
    if (l instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) l;
        Type baset = ((Local) ref.getBase()).getType();
        if (baset instanceof ArrayType) {
            ArrayType base = (ArrayType) baset;
            Value index = ref.getIndex();
            if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                left = ClassHierarchy.v().typeNode(base.baseType);
            }
            if (index instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
                    } else {
                        error("Type Error(5)");
                    }
                }
            }
        }
    } else if (l instanceof Local) {
        if (((Local) l).getType() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(((Local) l).getType());
        }
    } else if (l instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) l;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else if (l instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) l;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else {
        throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
    }
    if (r instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) r;
        Type baset = ((Local) ref.getBase()).getType();
        if (!(baset instanceof NullType)) {
            ArrayType base = (ArrayType) baset;
            Value index = ref.getIndex();
            if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                right = ClassHierarchy.v().typeNode(base.baseType);
            }
            if (index instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
                    } else {
                        error("Type Error(6)");
                    }
                }
            }
        }
    } else if (r instanceof DoubleConstant) {
    } else if (r instanceof FloatConstant) {
    } else if (r instanceof IntConstant) {
        int value = ((IntConstant) r).value;
        if (value < -32768) {
            right = ClassHierarchy.v().INT;
        } else if (value < -128) {
            right = ClassHierarchy.v().SHORT;
        } else if (value < 0) {
            right = ClassHierarchy.v().BYTE;
        } else if (value < 2) {
            right = ClassHierarchy.v().R0_1;
        } else if (value < 128) {
            right = ClassHierarchy.v().R0_127;
        } else if (value < 32768) {
            right = ClassHierarchy.v().R0_32767;
        } else if (value < 65536) {
            right = ClassHierarchy.v().CHAR;
        } else {
            right = ClassHierarchy.v().INT;
        }
    } else if (r instanceof LongConstant) {
    } else if (r instanceof NullConstant) {
    } else if (r instanceof StringConstant) {
    } else if (r instanceof ClassConstant) {
    } else if (r instanceof BinopExpr) {
        // ******** BINOP EXPR ********
        BinopExpr be = (BinopExpr) r;
        Value lv = be.getOp1();
        Value rv = be.getOp2();
        TypeNode lop = null;
        TypeNode rop = null;
        // ******** LEFT ********
        if (lv instanceof Local) {
            if (((Local) lv).getType() instanceof IntegerType) {
                lop = ClassHierarchy.v().typeNode(((Local) lv).getType());
            }
        } else if (lv instanceof DoubleConstant) {
        } else if (lv instanceof FloatConstant) {
        } else if (lv instanceof IntConstant) {
            int value = ((IntConstant) lv).value;
            if (value < -32768) {
                lop = ClassHierarchy.v().INT;
            } else if (value < -128) {
                lop = ClassHierarchy.v().SHORT;
            } else if (value < 0) {
                lop = ClassHierarchy.v().BYTE;
            } else if (value < 2) {
                lop = ClassHierarchy.v().R0_1;
            } else if (value < 128) {
                lop = ClassHierarchy.v().R0_127;
            } else if (value < 32768) {
                lop = ClassHierarchy.v().R0_32767;
            } else if (value < 65536) {
                lop = ClassHierarchy.v().CHAR;
            } else {
                lop = ClassHierarchy.v().INT;
            }
        } else if (lv instanceof LongConstant) {
        } else if (lv instanceof NullConstant) {
        } else if (lv instanceof StringConstant) {
        } else if (lv instanceof ClassConstant) {
        } else {
            throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
        }
        // ******** RIGHT ********
        if (rv instanceof Local) {
            if (((Local) rv).getType() instanceof IntegerType) {
                rop = ClassHierarchy.v().typeNode(((Local) rv).getType());
            }
        } else if (rv instanceof DoubleConstant) {
        } else if (rv instanceof FloatConstant) {
        } else if (rv instanceof IntConstant) {
            int value = ((IntConstant) rv).value;
            if (value < -32768) {
                rop = ClassHierarchy.v().INT;
            } else if (value < -128) {
                rop = ClassHierarchy.v().SHORT;
            } else if (value < 0) {
                rop = ClassHierarchy.v().BYTE;
            } else if (value < 2) {
                rop = ClassHierarchy.v().R0_1;
            } else if (value < 128) {
                rop = ClassHierarchy.v().R0_127;
            } else if (value < 32768) {
                rop = ClassHierarchy.v().R0_32767;
            } else if (value < 65536) {
                rop = ClassHierarchy.v().CHAR;
            } else {
                rop = ClassHierarchy.v().INT;
            }
        } else if (rv instanceof LongConstant) {
        } else if (rv instanceof NullConstant) {
        } else if (rv instanceof StringConstant) {
        } else if (rv instanceof ClassConstant) {
        } else {
            throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
        }
        if ((be instanceof AddExpr) || (be instanceof SubExpr) || (be instanceof MulExpr) || (be instanceof DivExpr) || (be instanceof RemExpr)) {
            if (lop != null && rop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), IntType.v(), stmt));
                    } else {
                        error("Type Error(7)");
                    }
                }
                if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                    } else {
                        error("Type Error(8)");
                    }
                }
            }
            right = ClassHierarchy.v().INT;
        } else if ((be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
            if (lop != null && rop != null) {
                TypeNode lca = lop.lca_1(rop);
                if (lca == ClassHierarchy.v().TOP) {
                    if (fix) {
                        if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
                            lca = rop;
                        }
                        if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
                            lca = lop;
                        }
                    } else {
                        error("Type Error(11)");
                    }
                }
                right = lca;
            }
        } else if (be instanceof ShlExpr) {
            if (lop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), IntType.v(), stmt));
                    } else {
                        error("Type Error(9)");
                    }
                }
            }
            if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                } else {
                    error("Type Error(10)");
                }
            }
            right = (lop == null) ? null : ClassHierarchy.v().INT;
        } else if ((be instanceof ShrExpr) || (be instanceof UshrExpr)) {
            if (lop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), ByteType.v(), stmt));
                        lop = ClassHierarchy.v().BYTE;
                    } else {
                        error("Type Error(9)");
                    }
                }
            }
            if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                } else {
                    error("Type Error(10)");
                }
            }
            right = lop;
        } else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr)) {
            right = ClassHierarchy.v().BYTE;
        } else if ((be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
            if (rop != null) {
                TypeNode lca = lop.lca_1(rop);
                if (lca == ClassHierarchy.v().TOP) {
                    if (fix) {
                        if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
                        }
                        if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
                        }
                    } else {
                        error("Type Error(11)");
                    }
                }
            }
            right = ClassHierarchy.v().BOOLEAN;
        } else {
            throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
        }
    } else if (r instanceof CastExpr) {
        CastExpr ce = (CastExpr) r;
        if (ce.getCastType() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ce.getCastType());
        }
    } else if (r instanceof InstanceOfExpr) {
        right = ClassHierarchy.v().BOOLEAN;
    } else if (r instanceof InvokeExpr) {
        InvokeExpr ie = (InvokeExpr) r;
        handleInvokeExpr(ie, stmt);
        if (ie.getMethodRef().returnType() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ie.getMethodRef().returnType());
        }
    } else if (r instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) r;
        Value size = nae.getSize();
        if (size instanceof Local) {
            if (!ClassHierarchy.v().typeNode(((Local) size).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    nae.setSize(insertCast((Local) size, IntType.v(), stmt));
                } else {
                    error("Type Error(12)");
                }
            }
        }
    } else if (r instanceof NewExpr) {
    } else if (r instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
        for (int i = 0; i < nmae.getSizeCount(); i++) {
            Value size = nmae.getSize(i);
            if (size instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) size).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        nmae.setSize(i, insertCast((Local) size, IntType.v(), stmt));
                    } else {
                        error("Type Error(13)");
                    }
                }
            }
        }
    } else if (r instanceof LengthExpr) {
        right = ClassHierarchy.v().INT;
    } else if (r instanceof NegExpr) {
        NegExpr ne = (NegExpr) r;
        if (ne.getOp() instanceof Local) {
            Local local = (Local) ne.getOp();
            if (local.getType() instanceof IntegerType) {
                TypeNode ltype = ClassHierarchy.v().typeNode(local.getType());
                if (!ltype.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ne.setOp(insertCast(local, IntType.v(), stmt));
                        ltype = ClassHierarchy.v().BYTE;
                    } else {
                        error("Type Error(14)");
                    }
                }
                right = (ltype == ClassHierarchy.v().CHAR) ? ClassHierarchy.v().INT : ltype;
            }
        } else if (ne.getOp() instanceof DoubleConstant) {
        } else if (ne.getOp() instanceof FloatConstant) {
        } else if (ne.getOp() instanceof IntConstant) {
            right = ClassHierarchy.v().INT;
        } else if (ne.getOp() instanceof LongConstant) {
        } else {
            throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
        }
    } else if (r instanceof Local) {
        Local local = (Local) r;
        if (local.getType() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(local.getType());
        }
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else if (r instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else {
        throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
    }
    if (left != null && right != null) {
        if (!right.hasAncestor_1(left)) {
            if (fix) {
                stmt.setRightOp(insertCast(stmt.getRightOp(), getTypeForCast(right), getTypeForCast(left), stmt));
            } else {
                error("Type Error(15)");
            }
        }
    }
}
Also used : MulExpr(soot.jimple.MulExpr) AndExpr(soot.jimple.AndExpr) DoubleConstant(soot.jimple.DoubleConstant) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) FloatConstant(soot.jimple.FloatConstant) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) NegExpr(soot.jimple.NegExpr) GeExpr(soot.jimple.GeExpr) UshrExpr(soot.jimple.UshrExpr) LeExpr(soot.jimple.LeExpr) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) ShlExpr(soot.jimple.ShlExpr) LongConstant(soot.jimple.LongConstant) XorExpr(soot.jimple.XorExpr) NeExpr(soot.jimple.NeExpr) LengthExpr(soot.jimple.LengthExpr) SubExpr(soot.jimple.SubExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) AddExpr(soot.jimple.AddExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) StaticFieldRef(soot.jimple.StaticFieldRef) IntegerType(soot.IntegerType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) IntType(soot.IntType) NullType(soot.NullType) ArrayType(soot.ArrayType) IntegerType(soot.IntegerType) DivExpr(soot.jimple.DivExpr) NewArrayExpr(soot.jimple.NewArrayExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) CmpExpr(soot.jimple.CmpExpr) EqExpr(soot.jimple.EqExpr) CmpgExpr(soot.jimple.CmpgExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) NullType(soot.NullType) StringConstant(soot.jimple.StringConstant) CmplExpr(soot.jimple.CmplExpr) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 13 with StaticFieldRef

use of soot.jimple.StaticFieldRef in project soot by Sable.

the class ConstantInitializerToTagTransformer method transformClass.

/**
 * Transforms the given class, i.e. scans for a <clinit> method and
 * generates new constant value tags for all constant assignments to static
 * final fields.
 *
 * @param sc
 *            The class to transform
 * @param removeAssignments
 *            True if the assignments inside the <clinit> method shall be
 *            removed, otherwise false
 */
public void transformClass(SootClass sc, boolean removeAssignments) {
    // If this class has no <clinit> method, we're done
    SootMethod smInit = sc.getMethodByNameUnsafe("<clinit>");
    if (smInit == null || !smInit.isConcrete())
        return;
    Set<SootField> nonConstantFields = new HashSet<SootField>();
    Map<SootField, ConstantValueTag> newTags = new HashMap<SootField, ConstantValueTag>();
    // in case of
    Set<SootField> removeTagList = new HashSet<SootField>();
    for (Iterator<Unit> itU = smInit.getActiveBody().getUnits().snapshotIterator(); itU.hasNext(); ) {
        Unit u = itU.next();
        if (u instanceof AssignStmt) {
            AssignStmt assign = (AssignStmt) u;
            if (assign.getLeftOp() instanceof StaticFieldRef && assign.getRightOp() instanceof Constant) {
                SootField field = null;
                try {
                    field = ((StaticFieldRef) assign.getLeftOp()).getField();
                    if (field == null || nonConstantFields.contains(field))
                        continue;
                } catch (ConflictingFieldRefException ex) {
                    // Ignore this statement
                    continue;
                }
                if (field.getDeclaringClass().equals(sc) && field.isStatic() && field.isFinal()) {
                    // Do we already have a constant value for this field?
                    boolean found = false;
                    for (Tag t : field.getTags()) {
                        if (t instanceof ConstantValueTag) {
                            if (checkConstantValue((ConstantValueTag) t, (Constant) assign.getRightOp())) {
                                // the assignment.
                                if (removeAssignments)
                                    itU.remove();
                            } else {
                                logger.debug("" + "WARNING: Constant value for field '" + field + "' mismatch between code (" + assign.getRightOp() + ") and constant table (" + t + ")");
                                removeTagList.add(field);
                            }
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        // tags.
                        if (!checkConstantValue(newTags.get(field), (Constant) assign.getRightOp())) {
                            nonConstantFields.add(field);
                            newTags.remove(field);
                            removeTagList.add(field);
                            continue;
                        }
                        ConstantValueTag newTag = createConstantTagFromValue((Constant) assign.getRightOp());
                        if (newTag != null)
                            newTags.put(field, newTag);
                    }
                }
            } else if (assign.getLeftOp() instanceof StaticFieldRef) {
                // a non-constant is assigned to the field
                try {
                    SootField sf = ((StaticFieldRef) assign.getLeftOp()).getField();
                    if (sf != null)
                        removeTagList.add(sf);
                } catch (ConflictingFieldRefException ex) {
                // let's assume that a broken field doesn't cause any
                // harm
                }
            }
        }
    }
    // Do the actual assignment
    for (Entry<SootField, ConstantValueTag> entry : newTags.entrySet()) {
        SootField field = entry.getKey();
        if (removeTagList.contains(field))
            continue;
        field.addTag(entry.getValue());
    }
    if (removeAssignments && !newTags.isEmpty())
        for (Iterator<Unit> itU = smInit.getActiveBody().getUnits().snapshotIterator(); itU.hasNext(); ) {
            Unit u = itU.next();
            if (u instanceof AssignStmt) {
                AssignStmt assign = (AssignStmt) u;
                if (assign.getLeftOp() instanceof FieldRef)
                    try {
                        SootField fld = ((FieldRef) assign.getLeftOp()).getField();
                        if (fld != null && newTags.containsKey(fld))
                            itU.remove();
                    } catch (ConflictingFieldRefException ex) {
                    // Ignore broken code
                    }
            }
        }
    // remove constant tags
    for (SootField sf : removeTagList) {
        if (removeTagList.contains(sf)) {
            List<Tag> toRemoveTagList = new ArrayList<Tag>();
            for (Tag t : sf.getTags()) {
                if (t instanceof ConstantValueTag) {
                    toRemoveTagList.add(t);
                }
            }
            for (Tag t : toRemoveTagList) {
                sf.getTags().remove(t);
            }
        }
    }
}
Also used : FieldRef(soot.jimple.FieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) HashMap(java.util.HashMap) AssignStmt(soot.jimple.AssignStmt) Constant(soot.jimple.Constant) LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) IntConstant(soot.jimple.IntConstant) StringConstant(soot.jimple.StringConstant) FloatConstant(soot.jimple.FloatConstant) ArrayList(java.util.ArrayList) Unit(soot.Unit) ConflictingFieldRefException(soot.ConflictingFieldRefException) StaticFieldRef(soot.jimple.StaticFieldRef) ConstantValueTag(soot.tagkit.ConstantValueTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) StringConstantValueTag(soot.tagkit.StringConstantValueTag) LongConstantValueTag(soot.tagkit.LongConstantValueTag) Iterator(java.util.Iterator) SootMethod(soot.SootMethod) SootField(soot.SootField) Tag(soot.tagkit.Tag) ConstantValueTag(soot.tagkit.ConstantValueTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) StringConstantValueTag(soot.tagkit.StringConstantValueTag) LongConstantValueTag(soot.tagkit.LongConstantValueTag) HashSet(java.util.HashSet)

Example 14 with StaticFieldRef

use of soot.jimple.StaticFieldRef 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 15 with StaticFieldRef

use of soot.jimple.StaticFieldRef in project soot by Sable.

the class DavaBody method javafy_ref.

private void javafy_ref(ValueBox vb) {
    Ref r = (Ref) vb.getValue();
    if (r instanceof StaticFieldRef) {
        SootFieldRef fieldRef = ((StaticFieldRef) r).getFieldRef();
        // addPackage(fieldRef.declaringClass().getJavaPackageName());
        String className = fieldRef.declaringClass().toString();
        String packageName = fieldRef.declaringClass().getJavaPackageName();
        String classPackageName = packageName;
        if (className.lastIndexOf('.') > 0) {
            // 0 doesnt make sense
            classPackageName = className.substring(0, className.lastIndexOf('.'));
        }
        if (!packageName.equals(classPackageName))
            throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
        addToImportList(className);
        vb.setValue(new DStaticFieldRef(fieldRef, getMethod().getDeclaringClass().getName()));
    } else if (r instanceof ArrayRef) {
        ArrayRef ar = (ArrayRef) r;
        javafy(ar.getBaseBox());
        javafy(ar.getIndexBox());
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ifr = (InstanceFieldRef) r;
        javafy(ifr.getBaseBox());
        vb.setValue(new DInstanceFieldRef(ifr.getBase(), ifr.getFieldRef(), thisLocals));
    } else if (r instanceof ThisRef) {
        ThisRef tr = (ThisRef) r;
        vb.setValue(new DThisRef((RefType) tr.getType()));
    }
}
Also used : ArrayRef(soot.jimple.ArrayRef) DThisRef(soot.dava.internal.javaRep.DThisRef) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) DThisRef(soot.dava.internal.javaRep.DThisRef) ArrayRef(soot.jimple.ArrayRef) SootMethodRef(soot.SootMethodRef) SootFieldRef(soot.SootFieldRef) DStaticFieldRef(soot.dava.internal.javaRep.DStaticFieldRef) ThisRef(soot.jimple.ThisRef) DInstanceFieldRef(soot.dava.internal.javaRep.DInstanceFieldRef) Ref(soot.jimple.Ref) InstanceFieldRef(soot.jimple.InstanceFieldRef) ParameterRef(soot.jimple.ParameterRef) StaticFieldRef(soot.jimple.StaticFieldRef) DThisRef(soot.dava.internal.javaRep.DThisRef) ThisRef(soot.jimple.ThisRef) DInstanceFieldRef(soot.dava.internal.javaRep.DInstanceFieldRef) DInstanceFieldRef(soot.dava.internal.javaRep.DInstanceFieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) DStaticFieldRef(soot.dava.internal.javaRep.DStaticFieldRef) SootFieldRef(soot.SootFieldRef) DStaticFieldRef(soot.dava.internal.javaRep.DStaticFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef)

Aggregations

StaticFieldRef (soot.jimple.StaticFieldRef)18 InstanceFieldRef (soot.jimple.InstanceFieldRef)13 Value (soot.Value)11 ArrayRef (soot.jimple.ArrayRef)11 Local (soot.Local)10 InvokeExpr (soot.jimple.InvokeExpr)9 Type (soot.Type)8 NewArrayExpr (soot.jimple.NewArrayExpr)8 ArrayType (soot.ArrayType)7 AssignStmt (soot.jimple.AssignStmt)7 BinopExpr (soot.jimple.BinopExpr)7 IntConstant (soot.jimple.IntConstant)7 LengthExpr (soot.jimple.LengthExpr)7 NewExpr (soot.jimple.NewExpr)7 Unit (soot.Unit)6 CastExpr (soot.jimple.CastExpr)6 FieldRef (soot.jimple.FieldRef)6 Stmt (soot.jimple.Stmt)6 SootField (soot.SootField)5 NewMultiArrayExpr (soot.jimple.NewMultiArrayExpr)5