use of soot.toolkits.graph.ExceptionalGraph.ExceptionDest in project soot by Sable.
the class CFGToDotGraph method drawCFG.
/**
* Create a <code>DotGraph</code> whose nodes and edges depict the
* control flow in a <code>ExceptionalGraph</code>, with
* distinguished edges for exceptional control flow.
*
* @param graph the control flow graph
*
* @return a visualization of <code>graph</code>.
*/
public <N> DotGraph drawCFG(ExceptionalGraph<N> graph) {
Body body = graph.getBody();
DotGraph canvas = initDotGraph(body);
DotNamer namer = new DotNamer((int) (graph.size() / 0.7f), 0.7f);
NodeComparator nodeComparator = new NodeComparator(namer);
// comparisons between graphs of a given method.
for (Iterator<N> nodesIt = graph.iterator(); nodesIt.hasNext(); ) {
namer.getName(nodesIt.next());
}
for (Iterator<N> nodesIt = graph.iterator(); nodesIt.hasNext(); ) {
N node = nodesIt.next();
canvas.drawNode(namer.getName(node));
for (Iterator<N> succsIt = sortedIterator(graph.getUnexceptionalSuccsOf(node), nodeComparator); succsIt.hasNext(); ) {
N succ = succsIt.next();
DotGraphEdge edge = canvas.drawEdge(namer.getName(node), namer.getName(succ));
edge.setAttribute(unexceptionalControlFlowAttr);
}
for (Iterator<N> succsIt = sortedIterator(graph.getExceptionalSuccsOf(node), nodeComparator); succsIt.hasNext(); ) {
N succ = succsIt.next();
DotGraphEdge edge = canvas.drawEdge(namer.getName(node), namer.getName(succ));
edge.setAttribute(exceptionalControlFlowAttr);
}
if (showExceptions) {
for (Iterator<ExceptionDest<N>> destsIt = sortedIterator(graph.getExceptionDests(node), new ExceptionDestComparator(namer)); destsIt.hasNext(); ) {
ExceptionDest<N> dest = destsIt.next();
Object handlerStart = dest.getHandlerNode();
if (handlerStart == null) {
// Giving each escaping exception its own, invisible
// exceptional exit node produces a less cluttered
// graph.
handlerStart = new Object() {
public String toString() {
return "Esc";
}
};
DotGraphNode escapeNode = canvas.drawNode(namer.getName(handlerStart));
escapeNode.setStyle(DotGraphConstants.NODE_STYLE_INVISIBLE);
}
DotGraphEdge edge = canvas.drawEdge(namer.getName(node), namer.getName(handlerStart));
edge.setAttribute(exceptionEdgeAttr);
edge.setLabel(formatThrowableSet(dest.getThrowables()));
}
}
}
setStyle(graph.getHeads(), canvas, namer, DotGraphConstants.NODE_STYLE_FILLED, headAttr);
setStyle(graph.getTails(), canvas, namer, DotGraphConstants.NODE_STYLE_FILLED, tailAttr);
if (!isBrief) {
formatNodeText(graph.getBody(), canvas, namer);
}
return canvas;
}
use of soot.toolkits.graph.ExceptionalGraph.ExceptionDest in project soot by Sable.
the class TrapMinimizer method internalTransform.
@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
// If we have less then two traps, there's nothing to do here
if (b.getTraps().size() == 0)
return;
ExceptionalUnitGraph eug = new ExceptionalUnitGraph(b, DalvikThrowAnalysis.v(), Options.v().omit_excepting_unit_edges());
Set<Unit> unitsWithMonitor = getUnitsWithMonitor(eug);
Map<Trap, List<Trap>> replaceTrapBy = new HashMap<Trap, List<Trap>>(b.getTraps().size());
boolean updateTrap = false;
for (Trap tr : b.getTraps()) {
// will contain the new
List<Trap> newTraps = new ArrayList<Trap>();
// traps
// points to the first unit
Unit firstTrapStmt = tr.getBeginUnit();
// in the trap
// true if there is an edge from the
boolean goesToHandler = false;
// unit to the handler of the
// current trap
updateTrap = false;
for (Unit u = tr.getBeginUnit(); u != tr.getEndUnit(); u = b.getUnits().getSuccOf(u)) {
if (goesToHandler) {
goesToHandler = false;
} else {
// if the previous unit has no exceptional edge to the
// handler,
// update firstTrapStmt to point to the current unit
firstTrapStmt = u;
}
// active monitor, we need to keep the block
if (tr.getException().getName().equals("java.lang.Throwable") && unitsWithMonitor.contains(u))
goesToHandler = true;
// handler
if (!goesToHandler)
if (DalvikThrowAnalysis.v().mightThrow(u).catchableAs(tr.getException().getType())) {
// to be inside the new minimized catch block.
for (ExceptionDest<Unit> ed : eug.getExceptionDests(u)) {
if (ed.getTrap() == tr) {
goesToHandler = true;
break;
}
}
}
if (!goesToHandler) {
// if the current unit does not have an edge to the current
// trap's handler,
// add a new trap starting at firstTrapStmt ending at the
// unit before the
// current unit 'u'.
updateTrap = true;
if (// do not add an empty trap, but set
firstTrapStmt == u)
// updateTrap to true
continue;
Trap t = Jimple.v().newTrap(tr.getException(), firstTrapStmt, u, tr.getHandlerUnit());
newTraps.add(t);
} else {
// next unit is outside the current trap.
if (b.getUnits().getSuccOf(u) == tr.getEndUnit() && updateTrap) {
Trap t = Jimple.v().newTrap(tr.getException(), firstTrapStmt, tr.getEndUnit(), tr.getHandlerUnit());
newTraps.add(t);
}
}
}
// cannot throw any exceptions)
if (updateTrap) {
replaceTrapBy.put(tr, newTraps);
}
}
// replace traps where necessary
for (Trap k : replaceTrapBy.keySet()) {
// we must keep
b.getTraps().insertAfter(replaceTrapBy.get(k), k);
// the order
b.getTraps().remove(k);
}
}
Aggregations