Example #1
0
  private int addJimpleLnTags(int lnNum, Unit stmt, int endLn) {

    if (endLn - lnNum <= 1) {
      stmt.addTag(new JimpleLineNumberTag(lnNum));
      // G.v().out.println(stmt.getClass().toString());
      lnNum++;
      return lnNum;
    } else {
      stmt.addTag(new JimpleLineNumberTag(lnNum, endLn));
      // G.v().out.println("multi-line: "+stmt.getClass().toString());
      endLn++;
      return endLn;
    }
  }
  /**
   * Traverse the statements in the given body, looking for aggregation possibilities; that is,
   * given a def d and a use u, d has no other uses, u has no other defs, collapse d and u.
   *
   * <p>option: only-stack-locals; if this is true, only aggregate variables starting with $
   */
  protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    StmtBody body = (StmtBody) b;
    boolean onlyStackVars = PhaseOptions.getBoolean(options, "only-stack-locals");

    int aggregateCount = 1;

    if (Options.v().time()) Timers.v().aggregationTimer.start();
    boolean changed = false;

    Map<ValueBox, Zone> boxToZone =
        new HashMap<ValueBox, Zone>(body.getUnits().size() * 2 + 1, 0.7f);

    // Determine the zone of every box
    {
      Zonation zonation = new Zonation(body);

      for (Unit u : body.getUnits()) {
        Zone zone = zonation.getZoneOf(u);

        for (ValueBox box : u.getUseBoxes()) {
          boxToZone.put(box, zone);
        }

        for (ValueBox box : u.getDefBoxes()) {
          boxToZone.put(box, zone);
        }
      }
    }

    do {
      if (Options.v().verbose())
        G.v()
            .out
            .println(
                "["
                    + body.getMethod().getName()
                    + "] Aggregating iteration "
                    + aggregateCount
                    + "...");

      // body.printTo(new java.io.PrintWriter(G.v().out, true));

      changed = internalAggregate(body, boxToZone, onlyStackVars);

      aggregateCount++;
    } while (changed);

    if (Options.v().time()) Timers.v().aggregationTimer.end();
  }
  SimpleLiveLocalsAnalysis(UnitGraph g) {
    super(g);

    if (Options.v().time()) Timers.v().liveSetupTimer.start();

    emptySet = new ArraySparseSet();

    // Create kill sets.
    {
      unitToKillSet = new HashMap<Unit, FlowSet>(g.size() * 2 + 1, 0.7f);

      Iterator unitIt = g.iterator();

      while (unitIt.hasNext()) {
        Unit s = (Unit) unitIt.next();

        FlowSet killSet = emptySet.clone();

        Iterator boxIt = s.getDefBoxes().iterator();

        while (boxIt.hasNext()) {
          ValueBox box = (ValueBox) boxIt.next();

          if (box.getValue() instanceof Local) killSet.add(box.getValue(), killSet);
        }

        unitToKillSet.put(s, killSet);
      }
    }

    // Create generate sets
    {
      unitToGenerateSet = new HashMap<Unit, FlowSet>(g.size() * 2 + 1, 0.7f);

      Iterator unitIt = g.iterator();

      while (unitIt.hasNext()) {
        Unit s = (Unit) unitIt.next();

        FlowSet genSet = emptySet.clone();

        Iterator boxIt = s.getUseBoxes().iterator();

        while (boxIt.hasNext()) {
          ValueBox box = (ValueBox) boxIt.next();

          if (box.getValue() instanceof Local) genSet.add(box.getValue(), genSet);
        }

        unitToGenerateSet.put(s, genSet);
      }
    }

    if (Options.v().time()) Timers.v().liveSetupTimer.end();

    if (Options.v().time()) Timers.v().liveAnalysisTimer.start();

    doAnalysis();

    if (Options.v().time()) Timers.v().liveAnalysisTimer.end();
  }
  /**
   * This method pushes all newExpr down to be the stmt directly before every invoke of the init
   * only if they are in the types list
   */
  public void internalTransform(Body b, String phaseName, Map options) {
    JimpleBody body = (JimpleBody) b;

    if (Options.v().verbose())
      G.v().out.println("[" + body.getMethod().getName() + "] Folding Jimple constructors...");

    Chain units = body.getUnits();
    List<Unit> stmtList = new ArrayList<Unit>();
    stmtList.addAll(units);

    Iterator<Unit> it = stmtList.iterator();
    Iterator<Unit> nextStmtIt = stmtList.iterator();
    // start ahead one
    nextStmtIt.next();

    SmartLocalDefs localDefs = SmartLocalDefsPool.v().getSmartLocalDefsFor(body);
    UnitGraph graph = localDefs.getGraph();
    LocalUses localUses = new SimpleLocalUses(graph, localDefs);

    /* fold in NewExpr's with specialinvoke's */
    while (it.hasNext()) {
      Stmt s = (Stmt) it.next();

      if (!(s instanceof AssignStmt)) continue;

      /* this should be generalized to ArrayRefs */
      // only deal with stmts that are an local = newExpr
      Value lhs = ((AssignStmt) s).getLeftOp();
      if (!(lhs instanceof Local)) continue;

      Value rhs = ((AssignStmt) s).getRightOp();
      if (!(rhs instanceof NewExpr)) continue;

      // check if very next statement is invoke -->
      // this indicates there is no control flow between
      // new and invoke and should do nothing
      if (nextStmtIt.hasNext()) {
        Stmt next = (Stmt) nextStmtIt.next();
        if (next instanceof InvokeStmt) {
          InvokeStmt invoke = (InvokeStmt) next;

          if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) {
            SpecialInvokeExpr invokeExpr = (SpecialInvokeExpr) invoke.getInvokeExpr();
            if (invokeExpr.getBase() == lhs) {
              break;
            }
          }
        }
      }

      // check if new is in the types list - only process these
      if (!types.contains(((NewExpr) rhs).getType())) continue;

      List lu = localUses.getUsesOf(s);
      Iterator luIter = lu.iterator();
      boolean MadeNewInvokeExpr = false;

      while (luIter.hasNext()) {
        Unit use = ((UnitValueBoxPair) (luIter.next())).unit;
        if (!(use instanceof InvokeStmt)) continue;
        InvokeStmt is = (InvokeStmt) use;
        if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr)
            || lhs != ((SpecialInvokeExpr) is.getInvokeExpr()).getBase()) continue;

        // make a new one here
        AssignStmt constructStmt =
            Jimple.v()
                .newAssignStmt(((DefinitionStmt) s).getLeftOp(), ((DefinitionStmt) s).getRightOp());
        constructStmt.setRightOp(Jimple.v().newNewExpr(((NewExpr) rhs).getBaseType()));
        MadeNewInvokeExpr = true;

        // redirect jumps
        use.redirectJumpsToThisTo(constructStmt);
        // insert new one here
        units.insertBefore(constructStmt, use);

        constructStmt.addTag(s.getTag("SourceLnPosTag"));
      }
      if (MadeNewInvokeExpr) {
        units.remove(s);
      }
    }
  }
Example #5
0
  /** Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>. */
  private void printStatementsInBody(
      Body body, java.io.PrintWriter out, LabeledUnitPrinter up, UnitGraph unitGraph) {
    Chain units = body.getUnits();
    Iterator unitIt = units.iterator();
    Unit currentStmt = null, previousStmt;

    while (unitIt.hasNext()) {

      previousStmt = currentStmt;
      currentStmt = (Unit) unitIt.next();

      // Print appropriate header.
      {
        // Put an empty line if the previous node was a branch node, the current node is a join node
        //   or the previous statement does not have body statement as a successor, or if
        //   body statement has a label on it

        if (currentStmt != units.getFirst()) {
          if (unitGraph.getSuccsOf(previousStmt).size() != 1
              || unitGraph.getPredsOf(currentStmt).size() != 1
              || up.labels().containsKey(currentStmt)) {
            up.newline();
          } else {
            // Or if the previous node does not have body statement as a successor.

            List succs = unitGraph.getSuccsOf(previousStmt);

            if (succs.get(0) != currentStmt) {
              up.newline();
            }
          }
        }

        if (up.labels().containsKey(currentStmt)) {
          up.unitRef(currentStmt, true);
          up.literal(":");
          up.newline();
        }

        if (up.references().containsKey(currentStmt)) {
          up.unitRef(currentStmt, false);
        }
      }

      up.startUnit(currentStmt);
      currentStmt.toString(up);
      up.endUnit(currentStmt);

      up.literal(";");
      up.newline();

      // only print them if not generating attributes files
      // because they mess up line number
      // if (!addJimpleLn()) {
      if (Options.v().print_tags_in_output()) {
        Iterator tagIterator = currentStmt.getTags().iterator();
        while (tagIterator.hasNext()) {
          Tag t = (Tag) tagIterator.next();
          up.noIndent();
          up.literal("/*");
          up.literal(t.toString());
          up.literal("*/");
          up.newline();
        }
        /*Iterator udIt = currentStmt.getUseAndDefBoxes().iterator();
        while (udIt.hasNext()) {
            ValueBox temp = (ValueBox)udIt.next();
            Iterator vbtags = temp.getTags().iterator();
            while (vbtags.hasNext()) {
                Tag t = (Tag) vbtags.next();
                up.noIndent();
                up.literal("VB Tag: "+t.toString());
                up.newline();
            }
        }*/
      }
    }

    out.print(up.toString());
    if (addJimpleLn()) {
      setJimpleLnNum(up.getPositionTagger().getEndLn());
    }

    // Print out exceptions
    {
      Iterator trapIt = body.getTraps().iterator();

      if (trapIt.hasNext()) {
        out.println();
        incJimpleLnNum();
      }

      while (trapIt.hasNext()) {
        Trap trap = (Trap) trapIt.next();

        out.println(
            "        catch "
                + Scene.v().quotedNameOf(trap.getException().getName())
                + " from "
                + up.labels().get(trap.getBeginUnit())
                + " to "
                + up.labels().get(trap.getEndUnit())
                + " with "
                + up.labels().get(trap.getHandlerUnit())
                + ";");

        incJimpleLnNum();
      }
    }
  }