All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.toolkits.graph.ClassicCompleteUnitGraph Maven / Gradle / Ivy

package soot.toolkits.graph;

/*-
 * #%L
 * Soot - a J*va Optimization Framework
 * %%
 * Copyright (C) 2003 John Jorgensen
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 2.1 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import soot.Body;
import soot.Trap;
import soot.Unit;
import soot.toolkits.exceptions.ThrowAnalysis;

/**
 * 

* Represents a CFG for a Body instance where the nodes are {@link Unit} instances, and where edges are a conservative * indication of unexceptional and exceptional control flow. *

* *

* ClassicCompleteUnitGraph attempts to duplicate the results that would have been produced by Soot's * CompleteUnitGraph in releases up to Soot 2.1.0 (the one known discrepancy is that the 2.1.0 * CompleteUnitGraph would include two edges joining one node to another {@link Unit}s if the first node both * branched to and fell through to the second). It is included solely for testing purposes, and should not be used in actual * analyses. *

* *

* There are two distinctions between the graphs produced by the ClassicCompleteUnitGraph and * ExceptionalUnitGraph: *

    * *
  1. ExceptionalUnitGraph only creates edges to a Trap handler for trapped Units that have the * potential to throw the particular exception type caught by the handler, according to the {@link ThrowAnalysis} used to * estimate which exceptions each {@link Unit} may throw. ClassicCompleteUnitGraph creates edges for all trapped * Units, regardless of the types of exceptions they may throw.
  2. * *
  3. When ExceptionalUnitGraph creates edges for a trapped Unit that may throw a caught exception, it * adds edges from each predecessor of the excepting Unit to the handler. If the excepting Unit itself has * no potential side effects, ExceptionalUnitGraph may omit an edge from it to the handler, depending on the * parameters passed to the ExceptionalUnitGraph constructor. * ClassicCompleteUnitGraph, on the other hand, always adds an edge from the excepting Unit itself to the * handler, and adds edges from the predecessor only of the first Unit covered by a Trap (in this one * aspect ClassicCompleteUnitGraph is less conservative than ExceptionalUnitGraph, since it ignores the * possibility of a branch into the middle of a protected area).
  4. * *
*

*/ public class ClassicCompleteUnitGraph extends TrapUnitGraph { /** * Constructs the graph from a given Body instance. * * @param the * Body instance from which the graph is built. */ public ClassicCompleteUnitGraph(Body body) { // The TrapUnitGraph constructor will use our buildExceptionalEdges: super(body); } /** * Method to compute the edges corresponding to exceptional control flow. * * @param unitToSuccs * A {@link Map} from {@link Unit}s to {@link List}s of {@link Unit}s. This is * an ``out parameter''; * buildExceptionalEdges will add a mapping for every Unit within the scope of one or more * {@link Trap}s to a List of the handler units of those Traps. * * @param unitToPreds * A {@link Map} from {@link Unit}s to {@link List}s of {@link Unit}s. This is an ``out parameter''; * buildExceptionalEdges will add a mapping for every {@link Trap} handler to all the Units * within the scope of that Trap. */ protected void buildExceptionalEdges(Map> unitToSuccs, Map> unitToPreds) { // First, add the same edges as TrapUnitGraph. super.buildExceptionalEdges(unitToSuccs, unitToPreds); // Then add edges from the predecessors of the first // trapped Unit for each Trap. for (Iterator trapIt = body.getTraps().iterator(); trapIt.hasNext();) { Trap trap = trapIt.next(); Unit firstTrapped = trap.getBeginUnit(); Unit catcher = trap.getHandlerUnit(); // Make a copy of firstTrapped's predecessors to iterate over, // just in case we're about to add new predecessors to this // very list, though that can only happen if the handler traps // itself. And to really allow for that // possibility, we should iterate here until we reach a fixed // point; but the old UnitGraph that we are attempting to // duplicate did not do that, so we won't either. List origPredsOfTrapped = new ArrayList(getPredsOf(firstTrapped)); for (Iterator unitIt = origPredsOfTrapped.iterator(); unitIt.hasNext();) { Unit pred = unitIt.next(); addEdge(unitToSuccs, unitToPreds, pred, catcher); } } } }