KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > toolkits > base > finders > ExceptionFinder


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.finders;
21
22 import soot.*;
23 import java.util.*;
24 import soot.util.*;
25 import soot.dava.*;
26 import soot.jimple.*;
27 import soot.dava.internal.asg.*;
28 import soot.dava.internal.SET.*;
29 import soot.dava.internal.AST.*;
30
31 public class ExceptionFinder implements FactFinder
32 {
33     public ExceptionFinder( Singletons.Global g ) {}
34     public static ExceptionFinder v() { return G.v().soot_dava_toolkits_base_finders_ExceptionFinder(); }
35
36     public void find( DavaBody body, AugmentedStmtGraph asg, SETNode SET) throws RetriggerAnalysisException
37     {
38     Dava.v().log( "ExceptionFinder::find()");
39
40     Iterator it = body.get_ExceptionFacts().iterator();
41     while (it.hasNext()) {
42         ExceptionNode en = (ExceptionNode) it.next();
43
44         if (body.get_SynchronizedBlockFacts().contains( en))
45         continue;
46
47         IterableSet fullBody = new IterableSet();
48
49         Iterator cit = en.get_CatchList().iterator();
50         while (cit.hasNext())
51         fullBody.addAll( (IterableSet) cit.next());
52         
53         fullBody.addAll( en.get_TryBody());
54
55         if (SET.nest( new SETTryNode( fullBody, en, asg, body)) == false)
56         throw new RetriggerAnalysisException();
57     }
58     }
59
60     public void preprocess( DavaBody body, AugmentedStmtGraph asg)
61     {
62     Dava.v().log( "ExceptionFinder::preprocess()");
63
64     IterableSet enlist = new IterableSet();
65
66     // Find the first approximation for all the try catch bodies.
67
{
68         Iterator trapIt = body.getTraps().iterator();
69         while (trapIt.hasNext()) {
70         Trap trap = (Trap) trapIt.next();
71         Unit endUnit = trap.getEndUnit();
72
73         // get the body of the try block as a raw read of the area of protection
74
IterableSet tryBody = new IterableSet();
75         
76         Iterator btit = body.getUnits().iterator( trap.getBeginUnit());
77         for (Unit u = (Unit) btit.next(); u != endUnit; u = (Unit) btit.next())
78             tryBody.add( asg.get_AugStmt( (Stmt) u));
79
80         enlist.add( new ExceptionNode( tryBody, trap.getException(), asg.get_AugStmt( (Stmt) trap.getHandlerUnit())));
81         }
82     }
83
84
85
86     // Add in gotos that may escape the try body (created by the indirection introduced in DavaBody).
87
{
88         Iterator enlit = enlist.iterator();
89         while (enlit.hasNext()) {
90         ExceptionNode en = (ExceptionNode) enlit.next();
91         IterableSet try_body = en.get_TryBody();
92         
93         Iterator tryIt = try_body.snapshotIterator();
94         while (tryIt.hasNext()) {
95             AugmentedStmt tras = (AugmentedStmt) tryIt.next();
96             
97             Iterator ptIt = tras.cpreds.iterator();
98             while (ptIt.hasNext()) {
99             AugmentedStmt pas = (AugmentedStmt) ptIt.next();
100             Stmt ps = pas.get_Stmt();
101             
102             if ((try_body.contains( pas) == false) && (ps instanceof GotoStmt)) {
103                 boolean add_it = true;
104                 
105                 Iterator cpit = pas.cpreds.iterator();
106                 while (cpit.hasNext())
107                 if ((add_it = try_body.contains( cpit.next())) == false)
108                     break;
109                 
110                 if (add_it)
111                 en.add_TryStmt( pas);
112             }
113             }
114         }
115         }
116     }
117
118
119
120
121
122
123
124
125
126     // Split up the try blocks until they cause no nesting problems.
127
splitLoop:
128     while (true)
129     {
130         // refresh the catch bodies
131
{
132         Iterator enlit = enlist.iterator();
133         while (enlit.hasNext())
134             ((ExceptionNode) enlit.next()).refresh_CatchBody( this);
135         }
136
137         // split for inter-exception nesting problems
138
{
139         ExceptionNode[] ena = new ExceptionNode[ enlist.size()];
140         Iterator enlit = enlist.iterator();
141         for (int i=0; enlit.hasNext(); i++)
142             ena[ i] = (ExceptionNode) enlit.next();
143         
144         for (int i=0; i<ena.length-1; i++) {
145             ExceptionNode eni = ena[i];
146             for (int j=i+1; j<ena.length; j++) {
147             ExceptionNode enj = ena[j];
148             
149             IterableSet
150                 eniTryBody = eni.get_TryBody(),
151                 enjTryBody = enj.get_TryBody();
152
153             if ((eniTryBody.equals( enjTryBody) == false) && (eniTryBody.intersects( enjTryBody))) {
154
155                 if ((eniTryBody.isSupersetOf( enj.get_Body())) ||
156                 (enjTryBody.isSupersetOf( eni.get_Body())))
157
158                 continue;
159
160                 IterableSet newTryBody = eniTryBody.intersection( enjTryBody);
161
162                 if (newTryBody.equals( enjTryBody))
163                 eni.splitOff_ExceptionNode( newTryBody, asg, enlist);
164                 else
165                 enj.splitOff_ExceptionNode( newTryBody, asg, enlist);
166
167                 continue splitLoop;
168             }
169             }
170         }
171         }
172
173         // split for intra-try-body issues
174
{
175         Iterator enlit = enlist.iterator();
176         while (enlit.hasNext()) {
177             ExceptionNode en = (ExceptionNode) enlit.next();
178
179             // Get the try block entry points
180
IterableSet tryBody = en.get_TryBody();
181             LinkedList heads = new LinkedList();
182             Iterator trIt = tryBody.iterator();
183             while (trIt.hasNext()) {
184             AugmentedStmt as = (AugmentedStmt) trIt.next();
185
186             if (as.cpreds.isEmpty()) {
187                 heads.add( as);
188                 continue;
189             }
190
191             Iterator pit = as.cpreds.iterator();
192             while (pit.hasNext())
193                 if (tryBody.contains( pit.next()) == false) {
194                 heads.add( as);
195                 break;
196                 }
197             }
198
199             HashSet touchSet = new HashSet();
200             touchSet.addAll( heads);
201
202             // Break up the try block for all the so-far detectable parts.
203
AugmentedStmt head = (AugmentedStmt) heads.removeFirst();
204             IterableSet subTryBlock = new IterableSet();
205             LinkedList worklist = new LinkedList();
206             
207             worklist.add( head);
208             
209             while (worklist.isEmpty() == false) {
210             AugmentedStmt as = (AugmentedStmt) worklist.removeFirst();
211             
212             subTryBlock.add( as);
213             Iterator sit = as.csuccs.iterator();
214             while (sit.hasNext()) {
215                 AugmentedStmt sas = (AugmentedStmt) sit.next();
216                 
217                 if ((tryBody.contains( sas) == false) || (touchSet.contains( sas)))
218                 continue;
219                 
220                 touchSet.add( sas);
221                 
222                 if (sas.get_Dominators().contains( head))
223                 worklist.add( sas);
224                 else
225                 heads.addLast( sas);
226             }
227             }
228             
229             if (heads.isEmpty() == false) {
230             en.splitOff_ExceptionNode( subTryBlock, asg, enlist);
231             continue splitLoop;
232             }
233         }
234         }
235
236         break;
237     }
238
239     // Aggregate the try blocks.
240
{
241         LinkedList reps = new LinkedList();
242         HashMap
243         hCode2bucket = new HashMap(),
244         tryBody2exceptionNode = new HashMap();
245         
246         Iterator enlit = enlist.iterator();
247         while (enlit.hasNext()) {
248         ExceptionNode en = (ExceptionNode) enlit.next();
249
250         int hashCode = 0;
251         IterableSet curTryBody = en.get_TryBody();
252
253         Iterator trit = curTryBody.iterator();
254         while (trit.hasNext())
255             hashCode ^= trit.next().hashCode();
256         Integer JavaDoc I = new Integer JavaDoc( hashCode);
257
258         LinkedList bucket = (LinkedList) hCode2bucket.get( I);
259         if (bucket == null) {
260             bucket = new LinkedList();
261             hCode2bucket.put( I, bucket);
262         }
263
264         ExceptionNode repExceptionNode = null;
265
266         Iterator bit = bucket.iterator();
267         while (bit.hasNext()) {
268             IterableSet bucketTryBody = (IterableSet) bit.next();
269             
270             if (bucketTryBody.equals( curTryBody)) {
271             repExceptionNode = (ExceptionNode) tryBody2exceptionNode.get( bucketTryBody);
272             break;
273             }
274         }
275             
276         if (repExceptionNode == null) {
277             tryBody2exceptionNode.put( curTryBody, en);
278             bucket.add( curTryBody);
279             reps.add( en);
280         }
281         else
282             repExceptionNode.add_CatchBody( en);
283         }
284
285         enlist.clear();
286         enlist.addAll( reps);
287     }
288
289     body.get_ExceptionFacts().clear();
290     body.get_ExceptionFacts().addAll( enlist);
291
292
293
294
295
296
297
298     }
299
300     public IterableSet get_CatchBody( AugmentedStmt handlerAugmentedStmt)
301     {
302     IterableSet catchBody = new IterableSet();
303     LinkedList catchQueue = new LinkedList();
304     
305     catchBody.add( handlerAugmentedStmt);
306     catchQueue.addAll( handlerAugmentedStmt.csuccs);
307     
308     while (catchQueue.isEmpty() == false) {
309         AugmentedStmt as = (AugmentedStmt) catchQueue.removeFirst();
310         
311         if (catchBody.contains( as))
312         continue;
313         
314         if (as.get_Dominators().contains( handlerAugmentedStmt)) {
315         catchBody.add( as);
316         catchQueue.addAll( as.csuccs);
317         }
318     }
319
320     return catchBody;
321     }
322 }
323
Popular Tags