KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > toolkits > base > misc > ThrowFinder


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2003 Jerome Miecznikowski
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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.dava.toolkits.base.misc;
21
22 import soot.*;
23 import soot.util.*;
24 import java.util.*;
25 import soot.jimple.*;
26 import soot.jimple.toolkits.callgraph.*;
27
28 public class ThrowFinder
29 {
30     public ThrowFinder( Singletons.Global g ) {}
31     public static ThrowFinder v() { return G.v().soot_dava_toolkits_base_misc_ThrowFinder(); }
32
33     private HashSet registeredMethods;
34     private HashMap protectionSet;
35
36     public void find()
37     {
38     G.v().out.print( "Verifying exception handling.. ");
39
40     registeredMethods = new HashSet();
41     protectionSet = new HashMap();
42
43         CallGraph cg;
44         if( Scene.v().hasCallGraph() ) {
45             cg = Scene.v().getCallGraph();
46         } else {
47             new CallGraphBuilder().build();
48             cg = Scene.v().getCallGraph();
49             Scene.v().releaseCallGraph();
50         }
51
52     IterableSet worklist = new IterableSet();
53
54     G.v().out.print( "\b. ");
55     G.v().out.flush();
56
57
58     // Get all the methods, and find protection for every statement.
59
Iterator classIt = Scene.v().getApplicationClasses().iterator();
60     while (classIt.hasNext()) {
61         Iterator methodIt = ((SootClass) classIt.next()).methodIterator();
62         while (methodIt.hasNext()) {
63         SootMethod m = (SootMethod) methodIt.next();
64
65         register_AreasOfProtection( m);
66         worklist.add( m);
67         }
68     }
69
70
71     // Build the subClass and superClass mappings.
72
HashMap
73         subClassSet = new HashMap(),
74         superClassSet = new HashMap();
75
76     HashSet applicationClasses = new HashSet();
77     applicationClasses.addAll( Scene.v().getApplicationClasses());
78
79     classIt = Scene.v().getApplicationClasses().iterator();
80     while (classIt.hasNext()) {
81         SootClass c = (SootClass) classIt.next();
82         
83         IterableSet superClasses = (IterableSet) superClassSet.get( c);
84         if (superClasses == null) {
85         superClasses = new IterableSet();
86         superClassSet.put( c, superClasses);
87         }
88
89         IterableSet subClasses = (IterableSet) subClassSet.get( c);
90         if (subClasses == null) {
91         subClasses = new IterableSet();
92         subClassSet.put( c, subClasses);
93         }
94
95         if (c.hasSuperclass()) {
96         SootClass superClass = c.getSuperclass();
97
98         IterableSet superClassSubClasses = (IterableSet) subClassSet.get( superClass);
99         if (superClassSubClasses == null) {
100             superClassSubClasses = new IterableSet();
101             subClassSet.put( superClass, superClassSubClasses);
102         }
103         superClassSubClasses.add( c);
104         superClasses.add( superClass);
105         }
106
107         Iterator interfaceIt = c.getInterfaces().iterator();
108         while (interfaceIt.hasNext()) {
109         SootClass interfaceClass = (SootClass) interfaceIt.next();
110
111         IterableSet interfaceClassSubClasses = (IterableSet) subClassSet.get( interfaceClass);
112         if (interfaceClassSubClasses == null) {
113             interfaceClassSubClasses = new IterableSet();
114             subClassSet.put( interfaceClass, interfaceClassSubClasses);
115         }
116         interfaceClassSubClasses.add( c);
117         superClasses.add( interfaceClass);
118         }
119     }
120     
121     // Build the subMethod and superMethod mappings.
122
HashMap agreementMethodSet = new HashMap();
123
124     // Get exceptions from throw statements and add them to the exceptions that the method throws.
125
Iterator worklistIt = worklist.iterator();
126     while (worklistIt.hasNext()) {
127         SootMethod m = (SootMethod) worklistIt.next();
128
129         if (!m.isAbstract() && !m.isNative() ) {
130
131         List exceptionList = m.getExceptions();
132         IterableSet exceptionSet = new IterableSet( exceptionList);
133         boolean changed = false;
134         
135         Iterator it = m.retrieveActiveBody().getUnits().iterator();
136         while (it.hasNext()) {
137             Unit u = (Unit) it.next();
138             HashSet handled = (HashSet) protectionSet.get(u);
139             
140             if (u instanceof ThrowStmt) {
141             Type t = ((ThrowStmt) u).getOp().getType();
142             
143             if (t instanceof RefType) {
144                 SootClass c = ((RefType) t).getSootClass();
145                 
146                 if ((handled_Exception( handled, c) == false) && (exceptionSet.contains( c) == false)) {
147                 exceptionSet.add( c);
148                 changed = true;
149                 }
150             }
151             }
152         }
153
154         it = cg.edgesOutOf(m);
155         while (it.hasNext()) {
156                     Edge e = (Edge) it.next();
157             Stmt callSite = e.srcStmt();
158                     if( callSite == null ) continue;
159             HashSet handled = (HashSet) protectionSet.get( callSite);
160
161                     SootMethod target = e.tgt();
162
163                     Iterator exceptionIt = target.getExceptions().iterator();
164                     while (exceptionIt.hasNext()) {
165                         SootClass exception = (SootClass) exceptionIt.next();
166
167                         if ((handled_Exception( handled, exception) == false) && (exceptionSet.contains( exception) == false)) {
168                             exceptionSet.add( exception);
169                             changed = true;
170                         }
171                     }
172         }
173         
174         if (changed) {
175             exceptionList.clear();
176             exceptionList.addAll( exceptionSet);
177         }
178         }
179
180         // While we're at it, put the superMethods and the subMethods in the agreementMethodSet.
181
find_OtherMethods( m, agreementMethodSet, subClassSet, applicationClasses);
182         find_OtherMethods( m, agreementMethodSet, superClassSet, applicationClasses);
183     }
184
185     // Perform worklist algorithm to propegate the throws information.
186
while (worklist.isEmpty() == false) {
187
188         SootMethod m = (SootMethod) worklist.getFirst();
189         worklist.removeFirst();
190
191         IterableSet agreementMethods = (IterableSet) agreementMethodSet.get( m);
192         if (agreementMethods != null) {
193         Iterator amit = agreementMethods.iterator();
194         while (amit.hasNext()) {
195             SootMethod otherMethod = (SootMethod) amit.next();
196
197             List otherExceptionsList = otherMethod.getExceptions();
198             IterableSet otherExceptionSet = new IterableSet( otherExceptionsList);
199             boolean changed = false;
200
201             Iterator exceptionIt = m.getExceptions().iterator();
202             while (exceptionIt.hasNext()) {
203             SootClass exception = (SootClass) exceptionIt.next();
204
205             if (otherExceptionSet.contains( exception) == false) {
206                 otherExceptionSet.add( exception);
207                 changed = true;
208             }
209             }
210
211             if (changed) {
212             otherExceptionsList.clear();
213             otherExceptionsList.addAll( otherExceptionSet);
214
215             if (worklist.contains( otherMethod) == false)
216                 worklist.addLast( otherMethod);
217             }
218         }
219         }
220
221             Iterator it = cg.edgesOutOf(m);
222             while (it.hasNext()) {
223                 Edge e = (Edge) it.next();
224         Stmt callingSite = e.srcStmt();
225                 if( callingSite == null ) continue;
226         SootMethod callingMethod = e.src();
227         List exceptionList = callingMethod.getExceptions();
228         IterableSet exceptionSet = new IterableSet( exceptionList);
229         HashSet handled = (HashSet) protectionSet.get( callingSite);
230         boolean changed = false;
231
232         Iterator exceptionIt = m.getExceptions().iterator();
233         while (exceptionIt.hasNext()) {
234             SootClass exception = (SootClass) exceptionIt.next();
235
236             if ((handled_Exception( handled, exception) == false) && (exceptionSet.contains( exception) == false)) {
237             exceptionSet.add( exception);
238             changed = true;
239             }
240         }
241         
242         if (changed) {
243             exceptionList.clear();
244             exceptionList.addAll( exceptionSet);
245
246             if (worklist.contains( callingMethod) == false)
247             worklist.addLast( callingMethod);
248         }
249         }
250     }
251
252     G.v().out.println();
253     G.v().out.flush();
254     }
255
256
257     private void find_OtherMethods( SootMethod startingMethod, HashMap methodMapping, HashMap classMapping, HashSet applicationClasses)
258     {
259     IterableSet worklist = (IterableSet) ((IterableSet) classMapping.get( startingMethod.getDeclaringClass())).clone();
260
261     HashSet touchSet = new HashSet();
262     touchSet.addAll( worklist);
263
264     String JavaDoc signature = startingMethod.getSubSignature();
265
266     while (worklist.isEmpty() == false) {
267         SootClass currentClass = (SootClass) worklist.getFirst();
268         worklist.removeFirst();
269
270         if (applicationClasses.contains( currentClass) == false)
271         continue;
272
273         if (currentClass.declaresMethod( signature)) {
274         IterableSet otherMethods = (IterableSet) methodMapping.get( startingMethod);
275         if (otherMethods == null) {
276             otherMethods = new IterableSet();
277             methodMapping.put( startingMethod, otherMethods);
278         }
279
280         otherMethods.add( currentClass.getMethod( signature));
281         }
282
283         else {
284         IterableSet otherClasses = (IterableSet) classMapping.get( currentClass);
285         if (otherClasses != null) {
286             Iterator ocit = otherClasses.iterator();
287             while (ocit.hasNext()) {
288             SootClass otherClass = (SootClass) ocit.next();
289
290             if (touchSet.contains( otherClass) == false) {
291                 worklist.addLast( otherClass);
292                 touchSet.add( otherClass);
293             }
294             }
295         }
296         }
297     }
298     }
299
300     private void register_AreasOfProtection( SootMethod m)
301     {
302     if (registeredMethods.contains( m))
303         return;
304
305     registeredMethods.add( m);
306
307     if (m.hasActiveBody() == false)
308         return;
309
310     Body b = (Body) m.getActiveBody();
311     Chain stmts = b.getUnits();
312
313     Iterator trapIt = b.getTraps().iterator();
314     while (trapIt.hasNext()) {
315         Trap t = (Trap) trapIt.next();
316         SootClass exception = t.getException();
317
318         Iterator sit = stmts.iterator( t.getBeginUnit(), stmts.getPredOf( t.getEndUnit()));
319         while (sit.hasNext()) {
320         Stmt s = (Stmt) sit.next();
321
322         HashSet handled = null;
323         if ((handled = (HashSet) protectionSet.get( s)) == null) {
324             handled = new HashSet();
325             protectionSet.put( s, handled);
326         }
327         
328         if (handled.contains( exception) == false)
329             handled.add( exception);
330         }
331     }
332     }
333
334     private boolean handled_Exception( HashSet handledExceptions, SootClass c)
335     {
336     SootClass thrownException = c;
337
338     if (is_HandledByRuntime( thrownException))
339         return true;
340
341     if (handledExceptions == null)
342         return false;
343
344     while (true) {
345         if (handledExceptions.contains( thrownException))
346         return true;
347         
348         if (thrownException.hasSuperclass() == false)
349         return false;
350
351         thrownException = thrownException.getSuperclass();
352     }
353     }
354
355     private boolean is_HandledByRuntime( SootClass c)
356     {
357     SootClass
358         thrownException = c,
359         runtimeException = Scene.v().getSootClass( "java.lang.RuntimeException"),
360         error = Scene.v().getSootClass( "java.lang.Error");
361     
362     while (true) {
363         if ((thrownException == runtimeException) || (thrownException == error))
364         return true;
365         
366         if (thrownException.hasSuperclass() == false)
367         return false;
368
369         thrownException = thrownException.getSuperclass();
370     }
371     }
372 }
373
Popular Tags