Search in sources :

Example 1 with ValueUnitPair

use of soot.toolkits.scalar.ValueUnitPair in project soot by Sable.

the class Shimple method redirectToPreds.

/**
 * If you are removing a Unit from a Unit chain which contains
 * PhiExpr's, you might want to call this utility function in
 * order to update any PhiExpr pointers to the Unit to point to
 * the Unit's predecessor(s). This function will not modify
 * "branch target" UnitBoxes.
 *
 * <p> Normally you should not have to call this function
 * directly, since patching is taken care of Shimple's internal
 * implementation of PatchingChain.
 */
public static void redirectToPreds(Body body, Unit remove) {
    boolean debug = Options.v().debug();
    if (body instanceof ShimpleBody)
        debug |= ((ShimpleBody) body).getOptions().debug();
    Chain<Unit> units = body.getUnits();
    /* Determine whether we should continue processing or not. */
    List<UnitBox> boxesPointingToThis = remove.getBoxesPointingToThis();
    if (boxesPointingToThis.isEmpty())
        return;
    for (UnitBox pointer : boxesPointingToThis) {
        // continue iteration from where we left off.
        if (!pointer.isBranchTarget())
            break;
    }
    /* Ok, continuing... */
    Set<Unit> preds = new HashSet<Unit>();
    Set<PhiExpr> phis = new HashSet<PhiExpr>();
    // find fall-through pred
    if (!remove.equals(units.getFirst())) {
        Unit possiblePred = (Unit) units.getPredOf(remove);
        if (possiblePred.fallsThrough())
            preds.add(possiblePred);
    }
    // find the rest of the preds and all Phi's that point to remove
    for (Unit unit : units) {
        for (UnitBox targetBox : unit.getUnitBoxes()) {
            if (remove.equals(targetBox.getUnit())) {
                if (targetBox.isBranchTarget())
                    preds.add(unit);
                else {
                    PhiExpr phiExpr = Shimple.getPhiExpr(unit);
                    if (phiExpr != null)
                        phis.add(phiExpr);
                }
            }
        }
    }
    if (phis.size() == 0) {
        if (debug)
            logger.warn("Orphaned UnitBoxes to " + remove + "? Shimple.redirectToPreds is giving up.");
        return;
    }
    if (preds.size() == 0) {
        if (debug)
            logger.warn("Shimple.redirectToPreds couldn't find any predecessors for " + remove + " in " + body.getMethod() + ".");
        if (!remove.equals(units.getFirst())) {
            Unit pred = (Unit) units.getPredOf(remove);
            if (debug)
                logger.warn("Falling back to immediate chain predecessor: " + pred + ".");
            preds.add(pred);
        } else if (!remove.equals(units.getLast())) {
            Unit succ = (Unit) units.getSuccOf(remove);
            if (debug)
                logger.warn("Falling back to immediate chain successor: " + succ + ".");
            preds.add(succ);
        } else
            throw new RuntimeException("Assertion failed.");
    }
    /* At this point we have found all the preds and relevant Phi's */
    /* Each Phi needs an argument for each pred. */
    Iterator<PhiExpr> phiIt = phis.iterator();
    while (phiIt.hasNext()) {
        PhiExpr phiExpr = phiIt.next();
        ValueUnitPair argBox = phiExpr.getArgBox(remove);
        if (argBox == null)
            throw new RuntimeException("Assertion failed.");
        // now we've got the value!
        Value arg = argBox.getValue();
        phiExpr.removeArg(argBox);
        // add new arguments to Phi
        Iterator<Unit> predsIt = preds.iterator();
        while (predsIt.hasNext()) {
            Unit pred = predsIt.next();
            phiExpr.addArg(arg, pred);
        }
    }
}
Also used : UnitBox(soot.UnitBox) ValueUnitPair(soot.toolkits.scalar.ValueUnitPair) Unit(soot.Unit) SPhiExpr(soot.shimple.internal.SPhiExpr) Value(soot.Value) HashSet(java.util.HashSet)

Aggregations

HashSet (java.util.HashSet)1 Unit (soot.Unit)1 UnitBox (soot.UnitBox)1 Value (soot.Value)1 SPhiExpr (soot.shimple.internal.SPhiExpr)1 ValueUnitPair (soot.toolkits.scalar.ValueUnitPair)1