Search in sources :

Example 41 with AssignStmt

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

the class AccessManager method createSetAccessor.

private static void createSetAccessor(SootMethod container, AssignStmt as, FieldRef ref) {
    java.util.List parameterTypes = new LinkedList();
    java.util.List<SootClass> thrownExceptions = new LinkedList<SootClass>();
    Body accessorBody = Jimple.v().newBody();
    soot.util.Chain accStmts = accessorBody.getUnits();
    LocalGenerator lg = new LocalGenerator(accessorBody);
    Body containerBody = container.getActiveBody();
    soot.util.Chain containerStmts = containerBody.getUnits();
    SootClass target = ref.getField().getDeclaringClass();
    SootMethod accessor;
    String name = createAccessorName(ref.getField(), true);
    accessor = target.getMethodByNameUnsafe(name);
    if (accessor == null) {
        Local thisLocal = lg.generateLocal(target.getType());
        int paramID = 0;
        if (ref instanceof InstanceFieldRef) {
            accStmts.add(Jimple.v().newIdentityStmt(thisLocal, Jimple.v().newParameterRef(target.getType(), paramID)));
            parameterTypes.add(target.getType());
            paramID++;
        }
        parameterTypes.add(ref.getField().getType());
        Local l = lg.generateLocal(ref.getField().getType());
        accStmts.add(Jimple.v().newIdentityStmt(l, Jimple.v().newParameterRef(ref.getField().getType(), paramID)));
        paramID++;
        if (ref instanceof InstanceFieldRef) {
            accStmts.add(Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(thisLocal, ref.getFieldRef()), l));
        } else {
            accStmts.add(Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(ref.getFieldRef()), l));
        }
        accStmts.addLast(Jimple.v().newReturnVoidStmt());
        Type returnType = VoidType.v();
        accessor = Scene.v().makeSootMethod(name, parameterTypes, returnType, Modifier.PUBLIC | Modifier.STATIC, thrownExceptions);
        accessorBody.setMethod(accessor);
        accessor.setActiveBody(accessorBody);
        target.addMethod(accessor);
    }
    java.util.List args = new LinkedList();
    if (ref instanceof InstanceFieldRef) {
        args.add(((InstanceFieldRef) ref).getBase());
    }
    args.add(as.getRightOp());
    InvokeExpr newExpr = Jimple.v().newStaticInvokeExpr(accessor.makeRef(), args);
    Stmt newStmt = Jimple.v().newInvokeStmt(newExpr);
    containerStmts.insertAfter(newStmt, as);
    containerStmts.remove(as);
}
Also used : LocalGenerator(soot.javaToJimple.LocalGenerator) Local(soot.Local) SootClass(soot.SootClass) LinkedList(java.util.LinkedList) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) Type(soot.Type) VoidType(soot.VoidType) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) SootMethod(soot.SootMethod) Body(soot.Body)

Example 42 with AssignStmt

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

the class SiteInliner method inlineSite.

/**
 *        Inlines the given site.  Note that this method does
 *        not actually check if it's safe (with respect to access modifiers and special invokes)
 *        for it to be inlined.  That functionality is handled by the InlinerSafetyManager.
 */
public static List inlineSite(SootMethod inlinee, Stmt toInline, SootMethod container, Map options) {
    boolean enableNullPointerCheckInsertion = PhaseOptions.getBoolean(options, "insert-null-checks");
    boolean enableRedundantCastInsertion = PhaseOptions.getBoolean(options, "insert-redundant-casts");
    Hierarchy hierarchy = Scene.v().getActiveHierarchy();
    JimpleBody containerB = (JimpleBody) container.getActiveBody();
    Chain<Unit> containerUnits = containerB.getUnits();
    if (!(inlinee.getDeclaringClass().isApplicationClass() || inlinee.getDeclaringClass().isLibraryClass()))
        return null;
    Body inlineeB = inlinee.getActiveBody();
    Chain<Unit> inlineeUnits = inlineeB.getUnits();
    InvokeExpr ie = toInline.getInvokeExpr();
    Value thisToAdd = null;
    if (ie instanceof InstanceInvokeExpr)
        thisToAdd = ((InstanceInvokeExpr) ie).getBase();
    // Insert casts to please the verifier.
    {
        boolean targetUsesThis = true;
        if (enableRedundantCastInsertion && ie instanceof InstanceInvokeExpr && targetUsesThis) {
            // The verifier will complain if targetUsesThis, and:
            // the argument passed to the method is not the same type.
            // For instance, Bottle.price_static takes a cost.
            // Cost is an interface implemented by Bottle.
            SootClass localType, parameterType;
            localType = ((RefType) ((InstanceInvokeExpr) ie).getBase().getType()).getSootClass();
            parameterType = inlinee.getDeclaringClass();
            if (localType.isInterface() || hierarchy.isClassSuperclassOf(localType, parameterType)) {
                Local castee = Jimple.v().newLocal("__castee", parameterType.getType());
                containerB.getLocals().add(castee);
                containerB.getUnits().insertBefore(Jimple.v().newAssignStmt(castee, Jimple.v().newCastExpr(((InstanceInvokeExpr) ie).getBase(), parameterType.getType())), toInline);
                thisToAdd = castee;
            }
        }
    }
    // (If enabled), add a null pointer check.
    {
        if (enableNullPointerCheckInsertion && ie instanceof InstanceInvokeExpr) {
            boolean caught = TrapManager.isExceptionCaughtAt(Scene.v().getSootClass("java.lang.NullPointerException"), toInline, containerB);
            /* Ah ha.  Caught again! */
            if (caught) {
                /* In this case, we don't use throwPoint;
                     * instead, put the code right there. */
                Stmt insertee = Jimple.v().newIfStmt(Jimple.v().newNeExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), toInline);
                containerB.getUnits().insertBefore(insertee, toInline);
                // This sucks (but less than before).
                ((IfStmt) insertee).setTarget(toInline);
                ThrowManager.addThrowAfter(containerB, insertee);
            } else {
                Stmt throwPoint = ThrowManager.getNullPointerExceptionThrower(containerB);
                containerB.getUnits().insertBefore(Jimple.v().newIfStmt(Jimple.v().newEqExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), throwPoint), toInline);
            }
        }
    }
    // Add synchronizing stuff.
    {
        if (inlinee.isSynchronized()) {
            // Need to get the class object if ie is a static invoke.
            if (ie instanceof InstanceInvokeExpr)
                SynchronizerManager.v().synchronizeStmtOn(toInline, containerB, (Local) ((InstanceInvokeExpr) ie).getBase());
            else {
                // synchronization.
                if (!container.getDeclaringClass().isInterface()) {
                    // Whew!
                    Local l = SynchronizerManager.v().addStmtsToFetchClassBefore(containerB, toInline);
                    SynchronizerManager.v().synchronizeStmtOn(toInline, containerB, l);
                }
            }
        }
    }
    Stmt exitPoint = (Stmt) containerUnits.getSuccOf(toInline);
    // First, clone all of the inlinee's units & locals.
    HashMap<Local, Local> oldLocalsToNew = new HashMap<Local, Local>();
    HashMap<Stmt, Stmt> oldUnitsToNew = new HashMap<Stmt, Stmt>();
    {
        Stmt cursor = toInline;
        for (Iterator<Unit> currIt = inlineeUnits.iterator(); currIt.hasNext(); ) {
            final Stmt curr = (Stmt) currIt.next();
            Stmt currPrime = (Stmt) curr.clone();
            if (currPrime == null)
                throw new RuntimeException("getting null from clone!");
            currPrime.addAllTagsOf(curr);
            containerUnits.insertAfter(currPrime, cursor);
            cursor = currPrime;
            oldUnitsToNew.put(curr, currPrime);
        }
        for (Iterator<Local> lIt = inlineeB.getLocals().iterator(); lIt.hasNext(); ) {
            final Local l = lIt.next();
            Local lPrime = (Local) l.clone();
            if (lPrime == null)
                throw new RuntimeException("getting null from local clone!");
            containerB.getLocals().add(lPrime);
            oldLocalsToNew.put(l, lPrime);
        }
    }
    // Backpatch the newly-inserted units using newly-constructed maps.
    {
        Iterator<Unit> it = containerUnits.iterator(containerUnits.getSuccOf(toInline), containerUnits.getPredOf(exitPoint));
        while (it.hasNext()) {
            Stmt patchee = (Stmt) it.next();
            for (ValueBox box : patchee.getUseAndDefBoxes()) {
                if (!(box.getValue() instanceof Local))
                    continue;
                Local lPrime = oldLocalsToNew.get(box.getValue());
                if (lPrime != null)
                    box.setValue(lPrime);
                else
                    throw new RuntimeException("local has no clone!");
            }
            for (UnitBox box : patchee.getUnitBoxes()) {
                Unit uPrime = (oldUnitsToNew.get(box.getUnit()));
                if (uPrime != null)
                    box.setUnit(uPrime);
                else
                    throw new RuntimeException("inlined stmt has no clone!");
            }
        }
    }
    // Copy & backpatch the traps; preserve their same order.
    {
        Trap prevTrap = null;
        for (Trap t : inlineeB.getTraps()) {
            Stmt newBegin = oldUnitsToNew.get(t.getBeginUnit()), newEnd = oldUnitsToNew.get(t.getEndUnit()), newHandler = oldUnitsToNew.get(t.getHandlerUnit());
            if (newBegin == null || newEnd == null || newHandler == null)
                throw new RuntimeException("couldn't map trap!");
            Trap trap = Jimple.v().newTrap(t.getException(), newBegin, newEnd, newHandler);
            if (prevTrap == null)
                containerB.getTraps().addFirst(trap);
            else
                containerB.getTraps().insertAfter(trap, prevTrap);
            prevTrap = trap;
        }
    }
    // Handle identity stmt's and returns.
    {
        Iterator<Unit> it = containerUnits.iterator(containerUnits.getSuccOf(toInline), containerUnits.getPredOf(exitPoint));
        ArrayList<Unit> cuCopy = new ArrayList<Unit>();
        while (it.hasNext()) {
            cuCopy.add(it.next());
        }
        for (Unit u : cuCopy) {
            Stmt s = (Stmt) u;
            if (s instanceof IdentityStmt) {
                IdentityRef rhs = (IdentityRef) ((IdentityStmt) s).getRightOp();
                if (rhs instanceof CaughtExceptionRef)
                    continue;
                else if (rhs instanceof ThisRef) {
                    if (!(ie instanceof InstanceInvokeExpr))
                        throw new RuntimeException("thisref with no receiver!");
                    containerUnits.swapWith(s, Jimple.v().newAssignStmt(((IdentityStmt) s).getLeftOp(), thisToAdd));
                } else if (rhs instanceof ParameterRef) {
                    ParameterRef pref = (ParameterRef) rhs;
                    containerUnits.swapWith(s, Jimple.v().newAssignStmt(((IdentityStmt) s).getLeftOp(), ie.getArg(pref.getIndex())));
                }
            } else if (s instanceof ReturnStmt) {
                if (toInline instanceof InvokeStmt) {
                    // munch, munch.
                    containerUnits.swapWith(s, Jimple.v().newGotoStmt(exitPoint));
                    continue;
                }
                if (!(toInline instanceof AssignStmt))
                    throw new RuntimeException("invoking stmt neither InvokeStmt nor AssignStmt!??!?!");
                Value ro = ((ReturnStmt) s).getOp();
                Value lhs = ((AssignStmt) toInline).getLeftOp();
                AssignStmt as = Jimple.v().newAssignStmt(lhs, ro);
                containerUnits.insertBefore(as, s);
                containerUnits.swapWith(s, Jimple.v().newGotoStmt(exitPoint));
            } else if (s instanceof ReturnVoidStmt)
                containerUnits.swapWith(s, Jimple.v().newGotoStmt(exitPoint));
        }
    }
    List<Unit> newStmts = new ArrayList<Unit>();
    for (Iterator<Unit> i = containerUnits.iterator(containerUnits.getSuccOf(toInline), containerUnits.getPredOf(exitPoint)); i.hasNext(); ) {
        newStmts.add(i.next());
    }
    // Remove the original statement toInline.
    containerUnits.remove(toInline);
    // Resolve name collisions.
    LocalNameStandardizer.v().transform(containerB, "ji.lns");
    return newStmts;
}
Also used : CaughtExceptionRef(soot.jimple.CaughtExceptionRef) InvokeStmt(soot.jimple.InvokeStmt) HashMap(java.util.HashMap) AssignStmt(soot.jimple.AssignStmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) ArrayList(java.util.ArrayList) Unit(soot.Unit) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) InvokeStmt(soot.jimple.InvokeStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) RefType(soot.RefType) Hierarchy(soot.Hierarchy) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) IdentityRef(soot.jimple.IdentityRef) Iterator(java.util.Iterator) JimpleBody(soot.jimple.JimpleBody) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) IdentityStmt(soot.jimple.IdentityStmt) UnitBox(soot.UnitBox) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Local(soot.Local) Trap(soot.Trap) SootClass(soot.SootClass) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) ReturnStmt(soot.jimple.ReturnStmt)

Example 43 with AssignStmt

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

the class IFDSLocalInfoFlow method createFlowFunctionsFactory.

public FlowFunctions<Unit, Local, SootMethod> createFlowFunctionsFactory() {
    return new FlowFunctions<Unit, Local, SootMethod>() {

        @Override
        public FlowFunction<Local> getNormalFlowFunction(Unit src, Unit dest) {
            if (src instanceof IdentityStmt && interproceduralCFG().getMethodOf(src) == Scene.v().getMainMethod()) {
                IdentityStmt is = (IdentityStmt) src;
                Local leftLocal = (Local) is.getLeftOp();
                Value right = is.getRightOp();
                if (right instanceof ParameterRef) {
                    return new Gen<Local>(leftLocal, zeroValue());
                }
            }
            if (src instanceof AssignStmt) {
                AssignStmt assignStmt = (AssignStmt) src;
                Value right = assignStmt.getRightOp();
                if (assignStmt.getLeftOp() instanceof Local) {
                    final Local leftLocal = (Local) assignStmt.getLeftOp();
                    if (right instanceof Local) {
                        final Local rightLocal = (Local) right;
                        return new Transfer<Local>(leftLocal, rightLocal);
                    } else {
                        return new Kill<Local>(leftLocal);
                    }
                }
            }
            return Identity.v();
        }

        @Override
        public FlowFunction<Local> getCallFlowFunction(Unit src, final SootMethod dest) {
            Stmt s = (Stmt) src;
            InvokeExpr ie = s.getInvokeExpr();
            final List<Value> callArgs = ie.getArgs();
            final List<Local> paramLocals = new ArrayList<Local>();
            for (int i = 0; i < dest.getParameterCount(); i++) {
                paramLocals.add(dest.getActiveBody().getParameterLocal(i));
            }
            return new FlowFunction<Local>() {

                public Set<Local> computeTargets(Local source) {
                    // ignore implicit calls to static initializers
                    if (dest.getName().equals(SootMethod.staticInitializerName) && dest.getParameterCount() == 0)
                        return Collections.emptySet();
                    Set<Local> taintsInCaller = new HashSet<Local>();
                    for (int i = 0; i < callArgs.size(); i++) {
                        if (callArgs.get(i).equivTo(source)) {
                            taintsInCaller.add(paramLocals.get(i));
                        }
                    }
                    return taintsInCaller;
                }
            };
        }

        @Override
        public FlowFunction<Local> getReturnFlowFunction(Unit callSite, SootMethod callee, Unit exitStmt, Unit retSite) {
            if (exitStmt instanceof ReturnStmt) {
                ReturnStmt returnStmt = (ReturnStmt) exitStmt;
                Value op = returnStmt.getOp();
                if (op instanceof Local) {
                    if (callSite instanceof DefinitionStmt) {
                        DefinitionStmt defnStmt = (DefinitionStmt) callSite;
                        Value leftOp = defnStmt.getLeftOp();
                        if (leftOp instanceof Local) {
                            final Local tgtLocal = (Local) leftOp;
                            final Local retLocal = (Local) op;
                            return new FlowFunction<Local>() {

                                public Set<Local> computeTargets(Local source) {
                                    if (source == retLocal)
                                        return Collections.singleton(tgtLocal);
                                    return Collections.emptySet();
                                }
                            };
                        }
                    }
                }
            }
            return KillAll.v();
        }

        @Override
        public FlowFunction<Local> getCallToReturnFlowFunction(Unit call, Unit returnSite) {
            return Identity.v();
        }
    };
}
Also used : AssignStmt(soot.jimple.AssignStmt) FlowFunction(heros.FlowFunction) ArrayList(java.util.ArrayList) JimpleLocal(soot.jimple.internal.JimpleLocal) Local(soot.Local) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) IdentityStmt(soot.jimple.IdentityStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt) Gen(heros.flowfunc.Gen) ParameterRef(soot.jimple.ParameterRef) InvokeExpr(soot.jimple.InvokeExpr) Value(soot.Value) Transfer(heros.flowfunc.Transfer) SootMethod(soot.SootMethod) Kill(heros.flowfunc.Kill) ReturnStmt(soot.jimple.ReturnStmt) DefinitionStmt(soot.jimple.DefinitionStmt) IdentityStmt(soot.jimple.IdentityStmt) HashSet(java.util.HashSet)

Example 44 with AssignStmt

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

the class ConstantCastEliminator method internalTransform.

@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    // Check for all assignments that perform casts on primitive constants
    for (Unit u : b.getUnits()) {
        if (u instanceof AssignStmt) {
            AssignStmt assign = (AssignStmt) u;
            if (assign.getRightOp() instanceof CastExpr) {
                CastExpr ce = (CastExpr) assign.getRightOp();
                if (ce.getOp() instanceof Constant) {
                    // a = (float) 42
                    if (ce.getType() instanceof FloatType && ce.getOp() instanceof IntConstant) {
                        IntConstant it = (IntConstant) ce.getOp();
                        assign.setRightOp(FloatConstant.v(it.value));
                    } else // a = (double) 42
                    if (ce.getType() instanceof DoubleType && ce.getOp() instanceof IntConstant) {
                        IntConstant it = (IntConstant) ce.getOp();
                        assign.setRightOp(DoubleConstant.v(it.value));
                    }
                }
            }
        }
    }
}
Also used : AssignStmt(soot.jimple.AssignStmt) IntConstant(soot.jimple.IntConstant) Constant(soot.jimple.Constant) DoubleConstant(soot.jimple.DoubleConstant) FloatConstant(soot.jimple.FloatConstant) DoubleType(soot.DoubleType) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) Unit(soot.Unit) FloatType(soot.FloatType)

Example 45 with AssignStmt

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

Aggregations

AssignStmt (soot.jimple.AssignStmt)83 Local (soot.Local)50 Value (soot.Value)44 Unit (soot.Unit)40 Type (soot.Type)28 Stmt (soot.jimple.Stmt)24 InvokeExpr (soot.jimple.InvokeExpr)20 RefType (soot.RefType)19 ArrayRef (soot.jimple.ArrayRef)19 ArrayType (soot.ArrayType)17 CastExpr (soot.jimple.CastExpr)17 InvokeStmt (soot.jimple.InvokeStmt)17 ArrayList (java.util.ArrayList)15 IdentityStmt (soot.jimple.IdentityStmt)15 DefinitionStmt (soot.jimple.DefinitionStmt)13 FieldRef (soot.jimple.FieldRef)13 InstanceFieldRef (soot.jimple.InstanceFieldRef)13 IntConstant (soot.jimple.IntConstant)13 ReturnStmt (soot.jimple.ReturnStmt)13 HashSet (java.util.HashSet)12