1 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 { 68 Iterator trapIt = body.getTraps().iterator(); 69 while (trapIt.hasNext()) { 70 Trap trap = (Trap) trapIt.next(); 71 Unit endUnit = trap.getEndUnit(); 72 73 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 { 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 splitLoop: 128 while (true) 129 { 130 { 132 Iterator enlit = enlist.iterator(); 133 while (enlit.hasNext()) 134 ((ExceptionNode) enlit.next()).refresh_CatchBody( this); 135 } 136 137 { 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 { 175 Iterator enlit = enlist.iterator(); 176 while (enlit.hasNext()) { 177 ExceptionNode en = (ExceptionNode) enlit.next(); 178 179 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 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 { 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 I = new Integer ( 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 |