/** * Look for a path in graph, from def to use. This path has to lie inside an extended basic block * (and this property implies uniqueness.). The path returned includes from and to. * * @param from start point for the path. * @param to end point for the path. * @return null if there is no such path. */ public List getExtendedBasicBlockPathBetween(Unit from, Unit to) { UnitGraph g = this; // if this holds, we're doomed to failure!!! if (g.getPredsOf(to).size() > 1) return null; // pathStack := list of succs lists // pathStackIndex := last visited index in pathStack LinkedList pathStack = new LinkedList(); LinkedList pathStackIndex = new LinkedList(); pathStack.add(from); pathStackIndex.add(new Integer(0)); int psiMax = (g.getSuccsOf((Unit) pathStack.get(0))).size(); int level = 0; while (((Integer) pathStackIndex.get(0)).intValue() != psiMax) { int p = ((Integer) (pathStackIndex.get(level))).intValue(); List succs = g.getSuccsOf((Unit) (pathStack.get(level))); if (p >= succs.size()) { // no more succs - backtrack to previous level. pathStack.remove(level); pathStackIndex.remove(level); level--; int q = ((Integer) pathStackIndex.get(level)).intValue(); pathStackIndex.set(level, new Integer(q + 1)); continue; } Unit betweenUnit = (Unit) (succs.get(p)); // we win! if (betweenUnit == to) { pathStack.add(to); return pathStack; } // check preds of betweenUnit to see if we should visit its kids. if (g.getPredsOf(betweenUnit).size() > 1) { pathStackIndex.set(level, new Integer(p + 1)); continue; } // visit kids of betweenUnit. level++; pathStackIndex.add(new Integer(0)); pathStack.add(betweenUnit); } return null; }
/** 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(); } } }