KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > toolkits > exceptions > TrapTightener


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2003 John Jorgensen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 package soot.toolkits.exceptions;
21
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Map JavaDoc;
25 import soot.Body;
26 import soot.BodyTransformer;
27 import soot.G;
28 import soot.Singletons;
29 import soot.Trap;
30 import soot.Unit;
31 import soot.options.Options;
32 import soot.util.Chain;
33 import soot.toolkits.graph.ExceptionalUnitGraph;
34
35 /**
36  * A {@link BodyTransformer} that shrinks the protected area covered
37  * by each {@link Trap} in the {@link Body} so that it begins at the first of
38  * the {@link Body}'s {@link Unit}s which might throw an exception caught by
39  * the {@link Trap} and ends just after the last {@link Unit} which might
40  * throw an exception caught by the {@link Trap}. In the case where none
41  * of the {@link Unit}s protected by a {@link Trap} can throw the exception
42  * it catches, the {@link Trap}'s protected area is left completely empty,
43  * which will likely cause the {@link UnreachableCodeEliminator} to remove the
44  * {@link Trap} completely.
45  *
46  * The {@link TrapTightener} is used to reduce the risk of
47  * unverifiable code which can result from the use of {@link
48  * ExceptionalUnitGraph}s from which unrealizable exceptional
49  * control flow edges have been removed.
50  */

51
52 public final class TrapTightener extends BodyTransformer {
53
54     public TrapTightener( Singletons.Global g ) {}
55     public static TrapTightener v() { return soot.G.v().soot_toolkits_exceptions_TrapTightener(); }
56
57     protected void internalTransform(Body body, String JavaDoc phaseName, Map JavaDoc options) {
58         if(Options.v().verbose())
59             G.v().out.println("[" + body.getMethod().getName() + "] Tightening trap boundaries...");
60
61     Chain trapChain = body.getTraps();
62     Chain unitChain = body.getUnits();
63     if (trapChain.size() > 0) {
64         ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body);
65
66         for (Iterator JavaDoc trapIt = trapChain.iterator(); trapIt.hasNext(); ) {
67         Trap trap = (Trap) trapIt.next();
68         Unit firstTrappedUnit = trap.getBeginUnit();
69         Unit firstTrappedThrower = null;
70         Unit firstUntrappedUnit = trap.getEndUnit();
71         Unit lastTrappedUnit =
72             (Unit) unitChain.getPredOf(firstUntrappedUnit);
73         Unit lastTrappedThrower = null;
74         for (Unit u = firstTrappedUnit;
75              u != null && u != firstUntrappedUnit;
76              u = (Unit) unitChain.getSuccOf(u)) {
77             if (mightThrowTo(graph, u, trap)) {
78                 firstTrappedThrower = u;
79                 break;
80             }
81         }
82         if (firstTrappedThrower != null) {
83             for (Unit u = lastTrappedUnit;
84              u != null; u = (Unit) unitChain.getPredOf(u)) {
85             if (mightThrowTo(graph, u, trap)) {
86                 lastTrappedThrower = u;
87                 break;
88             }
89             }
90         }
91         if (firstTrappedThrower != null &&
92             firstTrappedUnit != firstTrappedThrower) {
93             trap.setBeginUnit(firstTrappedThrower);
94         }
95         if (lastTrappedThrower == null) {
96             lastTrappedThrower = firstTrappedUnit;
97         }
98         if (lastTrappedUnit != lastTrappedThrower) {
99             trap.setEndUnit((Unit) unitChain.getSuccOf(lastTrappedThrower));
100         }
101         }
102     }
103     }
104
105     /**
106      * A utility routine which determines if a particular {@link Unit}
107      * might throw an exception to a particular {@link Trap}, according to
108      * the information supplied by a particular control flow graph.
109      *
110      * @param g The control flow graph providing information about exceptions.
111      * @param u The unit being inquired about.
112      * @param t The trap being inquired about.
113      * @return <tt>true</tt> if <tt>u</tt> might throw an exception caught
114      * by <tt>t</tt>, according to <tt>g</tt.
115      */

116     protected boolean mightThrowTo(ExceptionalUnitGraph g, Unit u, Trap t) {
117     Collection JavaDoc dests = g.getExceptionDests(u);
118     for (Iterator JavaDoc destIt = dests.iterator(); destIt.hasNext(); ) {
119         ExceptionalUnitGraph.ExceptionDest dest =
120         (ExceptionalUnitGraph.ExceptionDest) destIt.next();
121         if (dest.getTrap() == t) {
122         return true;
123         }
124     }
125     return false;
126     }
127 }
128
Popular Tags