Search in sources :

Example 11 with LongConstant

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

the class CopyPropagator method internalTransform.

/**
 * Cascaded copy propagator.
 *
 * If it encounters situations of the form: A: a = ...; B: ... x = a; C:...
 * use (x); where a has only one definition, and x has only one definition
 * (B), then it can propagate immediately without checking between B and C
 * for redefinitions of a (namely) A because they cannot occur. In this case
 * the propagator is global.
 *
 * Otherwise, if a has multiple definitions then it only checks for
 * redefinitions of Propagates constants and copies in extended basic
 * blocks.
 *
 * Does not propagate stack locals when the "only-regular-locals" option is
 * true.
 */
protected void internalTransform(Body b, String phaseName, Map<String, String> opts) {
    CPOptions options = new CPOptions(opts);
    StmtBody stmtBody = (StmtBody) b;
    int fastCopyPropagationCount = 0;
    int slowCopyPropagationCount = 0;
    if (Options.v().verbose())
        logger.debug("[" + stmtBody.getMethod().getName() + "] Propagating copies...");
    if (Options.v().time())
        Timers.v().propagatorTimer.start();
    Chain<Unit> units = stmtBody.getUnits();
    Map<Local, Integer> localToDefCount = new HashMap<Local, Integer>();
    // Count number of definitions for each local.
    for (Unit u : units) {
        Stmt s = (Stmt) u;
        if (s instanceof DefinitionStmt && ((DefinitionStmt) s).getLeftOp() instanceof Local) {
            Local l = (Local) ((DefinitionStmt) s).getLeftOp();
            if (!localToDefCount.containsKey(l))
                localToDefCount.put(l, new Integer(1));
            else
                localToDefCount.put(l, new Integer(localToDefCount.get(l).intValue() + 1));
        }
    }
    if (throwAnalysis == null)
        throwAnalysis = Scene.v().getDefaultThrowAnalysis();
    if (forceOmitExceptingUnitEdges == false)
        forceOmitExceptingUnitEdges = Options.v().omit_excepting_unit_edges();
    // Go through the definitions, building the webs
    UnitGraph graph = new ExceptionalUnitGraph(stmtBody, throwAnalysis, forceOmitExceptingUnitEdges);
    LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(graph);
    // Perform a local propagation pass.
    {
        Iterator<Unit> stmtIt = (new PseudoTopologicalOrderer<Unit>()).newList(graph, false).iterator();
        while (stmtIt.hasNext()) {
            Stmt stmt = (Stmt) stmtIt.next();
            for (ValueBox useBox : stmt.getUseBoxes()) {
                if (useBox.getValue() instanceof Local) {
                    Local l = (Local) useBox.getValue();
                    // null due to typing, we always inline that constant.
                    if (!(l.getType() instanceof NullType)) {
                        if (options.only_regular_locals() && l.getName().startsWith("$"))
                            continue;
                        if (options.only_stack_locals() && !l.getName().startsWith("$"))
                            continue;
                    }
                    List<Unit> defsOfUse = localDefs.getDefsOfAt(l, stmt);
                    // We can propagate the definition if we either only
                    // have
                    // one definition or all definitions are side-effect
                    // free
                    // and equal. For starters, we only support constants in
                    // the case of multiple definitions.
                    boolean propagateDef = defsOfUse.size() == 1;
                    if (!propagateDef && defsOfUse.size() > 0) {
                        boolean agrees = true;
                        Constant constVal = null;
                        for (Unit defUnit : defsOfUse) {
                            boolean defAgrees = false;
                            if (defUnit instanceof AssignStmt) {
                                AssignStmt assign = (AssignStmt) defUnit;
                                if (assign.getRightOp() instanceof Constant) {
                                    if (constVal == null) {
                                        constVal = (Constant) assign.getRightOp();
                                        defAgrees = true;
                                    } else if (constVal.equals(assign.getRightOp()))
                                        defAgrees = true;
                                }
                            }
                            agrees &= defAgrees;
                        }
                        propagateDef = agrees;
                    }
                    if (propagateDef) {
                        DefinitionStmt def = (DefinitionStmt) defsOfUse.get(0);
                        if (def.getRightOp() instanceof Constant) {
                            if (useBox.canContainValue(def.getRightOp())) {
                                useBox.setValue(def.getRightOp());
                            }
                        } else if (def.getRightOp() instanceof CastExpr) {
                            CastExpr ce = (CastExpr) def.getRightOp();
                            if (ce.getCastType() instanceof RefLikeType) {
                                boolean isConstNull = ce.getOp() instanceof IntConstant && ((IntConstant) ce.getOp()).value == 0;
                                isConstNull |= ce.getOp() instanceof LongConstant && ((LongConstant) ce.getOp()).value == 0;
                                if (isConstNull) {
                                    if (useBox.canContainValue(NullConstant.v())) {
                                        useBox.setValue(NullConstant.v());
                                    }
                                }
                            }
                        } else if (def.getRightOp() instanceof Local) {
                            Local m = (Local) def.getRightOp();
                            if (l != m) {
                                Integer defCount = localToDefCount.get(m);
                                if (defCount == null || defCount == 0)
                                    throw new RuntimeException("Variable " + m + " used without definition!");
                                if (defCount == 1) {
                                    useBox.setValue(m);
                                    fastCopyPropagationCount++;
                                    continue;
                                }
                                List<Unit> path = graph.getExtendedBasicBlockPathBetween(def, stmt);
                                if (path == null) {
                                    // no path in the extended basic block
                                    continue;
                                }
                                Iterator<Unit> pathIt = path.iterator();
                                // Skip first node
                                pathIt.next();
                                // Make sure that m is not redefined along
                                // path
                                {
                                    boolean isRedefined = false;
                                    while (pathIt.hasNext()) {
                                        Stmt s = (Stmt) pathIt.next();
                                        if (stmt == s) {
                                            break;
                                        }
                                        if (s instanceof DefinitionStmt) {
                                            if (((DefinitionStmt) s).getLeftOp() == m) {
                                                isRedefined = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (isRedefined)
                                        continue;
                                }
                                useBox.setValue(m);
                                slowCopyPropagationCount++;
                            }
                        }
                    }
                }
            }
        }
    }
    if (Options.v().verbose())
        logger.debug("[" + stmtBody.getMethod().getName() + "]     Propagated: " + fastCopyPropagationCount + " fast copies  " + slowCopyPropagationCount + " slow copies");
    if (Options.v().time())
        Timers.v().propagatorTimer.end();
}
Also used : HashMap(java.util.HashMap) NullConstant(soot.jimple.NullConstant) Constant(soot.jimple.Constant) LongConstant(soot.jimple.LongConstant) IntConstant(soot.jimple.IntConstant) AssignStmt(soot.jimple.AssignStmt) Unit(soot.Unit) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt) RefLikeType(soot.RefLikeType) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) Iterator(java.util.Iterator) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) List(java.util.List) LongConstant(soot.jimple.LongConstant) PseudoTopologicalOrderer(soot.toolkits.graph.PseudoTopologicalOrderer) Local(soot.Local) LocalDefs(soot.toolkits.scalar.LocalDefs) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) UnitGraph(soot.toolkits.graph.UnitGraph) ValueBox(soot.ValueBox) CPOptions(soot.options.CPOptions) NullType(soot.NullType) StmtBody(soot.jimple.StmtBody) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 12 with LongConstant

use of soot.jimple.LongConstant 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 LongConstant

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

the class ConstraintCollector method caseIfStmt.

public void caseIfStmt(IfStmt stmt) {
    if (uses) {
        ConditionExpr cond = (ConditionExpr) stmt.getCondition();
        BinopExpr expr = cond;
        Value lv = expr.getOp1();
        Value rv = expr.getOp2();
        TypeVariable lop = null;
        TypeVariable rop = null;
        // ******** LEFT ********
        if (lv instanceof Local) {
            if (((Local) lv).getType() instanceof IntegerType) {
                lop = resolver.typeVariable((Local) lv);
            }
        } else if (lv instanceof DoubleConstant) {
        } else if (lv instanceof FloatConstant) {
        } else if (lv instanceof IntConstant) {
            int value = ((IntConstant) lv).value;
            if (value < -32768) {
                lop = resolver.INT;
            } else if (value < -128) {
                lop = resolver.SHORT;
            } else if (value < 0) {
                lop = resolver.BYTE;
            } else if (value < 2) {
                lop = resolver.R0_1;
            } else if (value < 128) {
                lop = resolver.R0_127;
            } else if (value < 32768) {
                lop = resolver.R0_32767;
            } else if (value < 65536) {
                lop = resolver.CHAR;
            } else {
                lop = resolver.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 = resolver.typeVariable((Local) rv);
            }
        } else if (rv instanceof DoubleConstant) {
        } else if (rv instanceof FloatConstant) {
        } else if (rv instanceof IntConstant) {
            int value = ((IntConstant) rv).value;
            if (value < -32768) {
                rop = resolver.INT;
            } else if (value < -128) {
                rop = resolver.SHORT;
            } else if (value < 0) {
                rop = resolver.BYTE;
            } else if (value < 2) {
                rop = resolver.R0_1;
            } else if (value < 128) {
                rop = resolver.R0_127;
            } else if (value < 32768) {
                rop = resolver.R0_32767;
            } else if (value < 65536) {
                rop = resolver.CHAR;
            } else {
                rop = resolver.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 (rop != null && lop != null) {
            TypeVariable common = resolver.typeVariable();
            if (rop != null)
                rop.addParent(common);
            if (lop != null)
                lop.addParent(common);
        }
    }
}
Also used : LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) FloatConstant(soot.jimple.FloatConstant) Local(soot.Local) NullConstant(soot.jimple.NullConstant) IntegerType(soot.IntegerType) ConditionExpr(soot.jimple.ConditionExpr) Value(soot.Value) IntConstant(soot.jimple.IntConstant) StringConstant(soot.jimple.StringConstant) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 14 with LongConstant

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

the class StmtVisitor method buildArrayFillInsn.

private Insn buildArrayFillInsn(ArrayRef destRef, List<Value> values) {
    Local array = (Local) destRef.getBase();
    Register arrayReg = regAlloc.asLocal(array);
    // Convert the list of values into a list of numbers
    int elementSize = 0;
    List<Number> numbers = new ArrayList<Number>(values.size());
    for (Value val : values) {
        if (val instanceof IntConstant) {
            elementSize = Math.max(elementSize, 4);
            numbers.add(((IntConstant) val).value);
        } else if (val instanceof LongConstant) {
            elementSize = Math.max(elementSize, 8);
            numbers.add(((LongConstant) val).value);
        } else if (val instanceof FloatConstant) {
            elementSize = Math.max(elementSize, 4);
            numbers.add(((FloatConstant) val).value);
        } else if (val instanceof DoubleConstant) {
            elementSize = Math.max(elementSize, 8);
            numbers.add(((DoubleConstant) val).value);
        } else
            return null;
    }
    // For some local types, we know the size upfront
    if (destRef.getType() instanceof BooleanType)
        elementSize = 1;
    else if (destRef.getType() instanceof ByteType)
        elementSize = 1;
    else if (destRef.getType() instanceof CharType)
        elementSize = 2;
    else if (destRef.getType() instanceof ShortType)
        elementSize = 2;
    else if (destRef.getType() instanceof IntType)
        elementSize = 4;
    else if (destRef.getType() instanceof FloatType)
        elementSize = 4;
    else if (destRef.getType() instanceof LongType)
        elementSize = 8;
    else if (destRef.getType() instanceof DoubleType)
        elementSize = 8;
    ArrayDataPayload payload = new ArrayDataPayload(elementSize, numbers);
    payloads.add(payload);
    Insn31t insn = new Insn31t(Opcode.FILL_ARRAY_DATA, arrayReg);
    insn.setPayload(payload);
    return insn;
}
Also used : LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) LongType(soot.LongType) FloatConstant(soot.jimple.FloatConstant) ShortType(soot.ShortType) ArrayList(java.util.ArrayList) BooleanType(soot.BooleanType) Local(soot.Local) ByteType(soot.ByteType) IntType(soot.IntType) FloatType(soot.FloatType) ArrayDataPayload(soot.toDex.instructions.ArrayDataPayload) Insn31t(soot.toDex.instructions.Insn31t) DoubleType(soot.DoubleType) Value(soot.Value) IntConstant(soot.jimple.IntConstant) CharType(soot.CharType)

Example 15 with LongConstant

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

the class RegisterAllocator method asConstant.

private Register asConstant(Constant c, ConstantVisitor constantV) {
    Register constantRegister = null;
    List<Register> rArray = null;
    AtomicInteger iI = null;
    if (c instanceof ClassConstant) {
        rArray = classConstantReg;
        iI = classI;
    } else if (c instanceof NullConstant) {
        rArray = nullConstantReg;
        iI = nullI;
    } else if (c instanceof FloatConstant) {
        rArray = floatConstantReg;
        iI = floatI;
    } else if (c instanceof IntConstant) {
        rArray = intConstantReg;
        iI = intI;
    } else if (c instanceof LongConstant) {
        rArray = longConstantReg;
        iI = longI;
    } else if (c instanceof DoubleConstant) {
        rArray = doubleConstantReg;
        iI = doubleI;
    } else if (c instanceof StringConstant) {
        rArray = stringConstantReg;
        iI = stringI;
    } else {
        throw new RuntimeException("Error. Unknown constant type: '" + c.getType() + "'");
    }
    boolean inConflict = true;
    while (inConflict) {
        if (rArray.size() == 0 || iI.intValue() >= rArray.size()) {
            rArray.add(new Register(c.getType(), nextRegNum));
            nextRegNum += SootToDexUtils.getDexWords(c.getType());
        }
        constantRegister = rArray.get(iI.getAndIncrement()).clone();
        inConflict = lockedRegisters.contains(constantRegister);
    }
    // "load" constant into the register...
    constantV.setDestination(constantRegister);
    c.apply(constantV);
    // get an independent clone in case we got a cached reguster
    return constantRegister.clone();
}
Also used : LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FloatConstant(soot.jimple.FloatConstant) NullConstant(soot.jimple.NullConstant) IntConstant(soot.jimple.IntConstant) StringConstant(soot.jimple.StringConstant) ClassConstant(soot.jimple.ClassConstant)

Aggregations

IntConstant (soot.jimple.IntConstant)19 LongConstant (soot.jimple.LongConstant)19 Value (soot.Value)16 Local (soot.Local)13 DoubleConstant (soot.jimple.DoubleConstant)13 FloatConstant (soot.jimple.FloatConstant)13 NullConstant (soot.jimple.NullConstant)12 StringConstant (soot.jimple.StringConstant)10 BinopExpr (soot.jimple.BinopExpr)8 ClassConstant (soot.jimple.ClassConstant)8 Type (soot.Type)7 IntType (soot.IntType)6 NullType (soot.NullType)6 Unit (soot.Unit)6 AssignStmt (soot.jimple.AssignStmt)6 CastExpr (soot.jimple.CastExpr)6 ArrayType (soot.ArrayType)5 LongType (soot.LongType)5 HashSet (java.util.HashSet)4 DoubleType (soot.DoubleType)4