1 19 20 27 28 package soot.jimple.toolkits.annotation.purity; 29 import java.util.*; 30 import java.io.File ; 31 import soot.*; 32 import soot.util.*; 33 import soot.util.dot.*; 34 import soot.jimple.*; 35 import soot.toolkits.scalar.*; 36 import soot.toolkits.graph.*; 37 38 45 public class PurityIntraproceduralAnalysis extends ForwardFlowAnalysis 46 { 47 48 AbstractInterproceduralAnalysis inter; 49 50 protected Object newInitialFlow() 51 { return new PurityGraphBox(); } 52 53 protected Object entryInitialFlow() 54 { return new PurityGraphBox(); } 55 56 protected void merge(Object in1, Object in2, Object out) 57 { 58 PurityGraphBox i1 = (PurityGraphBox)in1; 59 PurityGraphBox i2 = (PurityGraphBox)in2; 60 PurityGraphBox o = (PurityGraphBox)out; 61 if (out!=i1) o.g = new PurityGraph(i1.g); 62 o.g.union(i2.g); 63 } 64 65 protected void copy(Object source, Object dest) 66 { 67 PurityGraphBox src = (PurityGraphBox)source; 68 PurityGraphBox dst = (PurityGraphBox)dest; 69 dst.g = new PurityGraph(src.g); 70 } 71 72 73 77 private Local callExtractReturn(Stmt stmt) 78 { 79 if (!(stmt instanceof AssignStmt)) return null; 80 Local v = (Local)((AssignStmt)stmt).getLeftOp(); 81 if (v.getType() instanceof RefLikeType) return v; 82 return null; 83 } 84 85 89 private Local callExtractObj(Stmt stmt) 90 { 91 InvokeExpr e; 92 if (stmt instanceof InvokeStmt) e = ((InvokeStmt)stmt).getInvokeExpr(); 93 else e = (InvokeExpr)((AssignStmt)stmt).getRightOp(); 94 if (e instanceof StaticInvokeExpr) return null; 95 return (Local)((InstanceInvokeExpr)e).getBase(); 96 } 97 98 102 private List callExtractArgs(Stmt stmt) 103 { 104 InvokeExpr e; 105 if (stmt instanceof InvokeStmt) e = ((InvokeStmt)stmt).getInvokeExpr(); 106 else e = (InvokeExpr)((AssignStmt)stmt).getRightOp(); 107 return e.getArgs(); 108 } 109 110 111 protected void flowThrough(Object inValue, Object unit, Object outValue) 112 { 113 PurityGraphBox i = (PurityGraphBox)inValue; 114 PurityGraphBox o = (PurityGraphBox)outValue; 115 Stmt stmt = (Stmt)unit; 116 117 o.g = new PurityGraph(i.g); 118 119 123 126 128 129 if (stmt.containsInvokeExpr()) { 133 inter.analyseCall(inValue, stmt, outValue); 134 } 135 136 140 else if (stmt instanceof AssignStmt) { 141 Value leftOp = ((AssignStmt)stmt).getLeftOp(); 142 Value rightOp = ((AssignStmt)stmt).getRightOp(); 143 144 if (leftOp instanceof Local) { 146 Local left = (Local)leftOp; 147 148 if (rightOp instanceof CastExpr) 150 rightOp = ((CastExpr)rightOp).getOp(); 151 152 if (!(left.getType() instanceof RefLikeType)) { 154 } 155 156 else if (rightOp instanceof Local) { 158 Local right = (Local) rightOp; 159 o.g.assignLocalToLocal(right, left); 160 } 161 162 else if (rightOp instanceof ArrayRef) { 164 Local right = (Local) ((ArrayRef)rightOp).getBase(); 165 o.g.assignFieldToLocal(stmt, right, "[]", left); 166 } 167 168 else if (rightOp instanceof InstanceFieldRef) { 170 Local right = 171 (Local) ((InstanceFieldRef)rightOp).getBase(); 172 String field = 173 ((InstanceFieldRef)rightOp).getField().getName(); 174 o.g.assignFieldToLocal(stmt, right, field, left); 175 } 176 177 else if (rightOp instanceof StaticFieldRef) { 179 o.g.localIsUnknown(left); 180 } 181 182 else if (rightOp instanceof Constant) { 184 } 186 187 188 else if (rightOp instanceof AnyNewExpr) { 190 o.g.assignNewToLocal(stmt, left); 191 } 192 193 else if (rightOp instanceof BinopExpr || 195 rightOp instanceof UnopExpr || 196 rightOp instanceof InstanceOfExpr) { 197 } 199 200 else throw new Error ("AssignStmt match failure (rightOp)"+stmt); 201 } 202 203 else if (leftOp instanceof ArrayRef) { 205 Local left = (Local) ((ArrayRef)leftOp).getBase(); 206 207 if (rightOp instanceof Local) { 209 Local right = (Local)rightOp; 210 if (right.getType() instanceof RefLikeType) 211 o.g.assignLocalToField(right, left, "[]"); 212 else 213 o.g.mutateField(left, "[]"); 214 } 215 216 else if (rightOp instanceof Constant) 218 o.g.mutateField(left, "[]"); 219 220 else throw new Error ("AssignStmt match failure (rightOp)"+stmt); 221 } 222 223 else if (leftOp instanceof InstanceFieldRef) { 225 Local left = (Local) ((InstanceFieldRef)leftOp).getBase(); 226 String field = ((InstanceFieldRef)leftOp).getField().getName(); 227 228 if (rightOp instanceof Local) { 230 Local right = (Local)rightOp; 231 if (right.getType() instanceof RefLikeType) 233 o.g.assignLocalToField(right, left, field); 234 else 235 o.g.mutateField(left, field); 236 } 237 238 else if (rightOp instanceof Constant) 240 o.g.mutateField(left, field); 241 242 else throw new Error ("AssignStmt match failure (rightOp) "+stmt); 243 } 244 245 else if (leftOp instanceof StaticFieldRef) { 247 String field = ((StaticFieldRef)leftOp).getField().getName(); 248 249 if (rightOp instanceof Local) { 251 Local right = (Local)rightOp; 252 if (right.getType() instanceof RefLikeType) 253 o.g.assignLocalToStaticField(right, field); 254 else 255 o.g.mutateStaticField(field); 256 } 257 258 else if (rightOp instanceof Constant) 260 o.g.mutateStaticField(field); 261 262 else throw new Error ("AssignStmt match failure (rightOp) "+stmt); 263 } 264 265 else throw new Error ("AssignStmt match failure (leftOp) "+stmt); 266 267 } 268 269 270 274 else if (stmt instanceof IdentityStmt) { 275 Local left = (Local)((IdentityStmt)stmt).getLeftOp(); 276 Value rightOp = ((IdentityStmt)stmt).getRightOp(); 277 278 if (rightOp instanceof ThisRef) { 279 o.g.assignThisToLocal(left); 280 } 281 282 else if (rightOp instanceof ParameterRef) { 283 ParameterRef p = (ParameterRef)rightOp; 284 if (p.getType() instanceof RefLikeType) 286 o.g.assignParamToLocal(p.getIndex(),left); 287 } 288 289 else if (rightOp instanceof CaughtExceptionRef) { 290 o.g.localIsUnknown(left); 292 } 293 294 else throw new Error ("IdentityStmt match failure (rightOp) "+stmt); 295 296 } 297 298 299 303 else if (stmt instanceof ThrowStmt) { 304 Value op = ((ThrowStmt)stmt).getOp(); 305 306 if (op instanceof Local) { 307 Local v = (Local)op; 308 o.g.localEscapes(v); 309 } 310 311 else if (op instanceof Constant) { 312 } 314 315 else throw new Error ("ThrowStmt match failure "+stmt); 316 } 317 318 319 323 else if (stmt instanceof ReturnVoidStmt) { 324 } 326 327 else if (stmt instanceof ReturnStmt) { 328 Value v = ((ReturnStmt)stmt).getOp(); 329 330 if (v instanceof Local) { 331 if (v.getType() instanceof RefLikeType) 333 o.g.returnLocal((Local)v); 334 } 335 336 else if (v instanceof Constant) { 337 } 339 340 else throw new Error ("ReturnStmt match failure "+stmt); 341 342 } 343 344 345 349 else if (stmt instanceof IfStmt || 350 stmt instanceof GotoStmt || 351 stmt instanceof LookupSwitchStmt || 352 stmt instanceof TableSwitchStmt || 353 stmt instanceof MonitorStmt || 354 stmt instanceof BreakpointStmt || 355 stmt instanceof NopStmt) { 356 } 358 359 360 else throw new Error ("Stmt match faliure "+stmt); 361 362 } 364 365 366 371 public void drawAsOneDot(String prefix, String name) 372 { 373 DotGraph dot = new DotGraph(name); 374 dot.setGraphLabel(name); 375 dot.setGraphAttribute("compound","true"); 376 dot.setGraphAttribute("rankdir","LR"); 377 Map node = new HashMap(); 378 int id = 0; 379 Iterator it = graph.iterator(); 380 while (it.hasNext()) { 381 Unit stmt = (Unit)it.next(); 382 PurityGraphBox ref = (PurityGraphBox) getFlowAfter(stmt); 383 DotGraph sub = dot.createSubGraph("cluster"+id); 384 DotGraphNode label = sub.drawNode("head"+id); 385 String lbl = stmt.toString(); 386 if (lbl.startsWith("lookupswitch")) lbl = "lookupswitch..."; 387 if (lbl.startsWith("tableswitch")) lbl = "tableswitch..."; 388 sub.setGraphLabel(" "); 389 label.setLabel(lbl); 390 label.setAttribute("fontsize","18"); 391 label.setShape("box"); 392 ref.g.fillDotGraph("X"+id,sub); 393 node.put(stmt,new Integer (id)); 394 id++; 395 } 396 it = graph.iterator(); 397 while (it.hasNext()) { 398 Object src = it.next(); 399 Iterator itt = graph.getSuccsOf(src).iterator(); 400 while (itt.hasNext()) { 401 Object dst = itt.next(); 402 DotGraphEdge edge = 403 dot.drawEdge("head"+node.get(src),"head"+node.get(dst)); 404 edge.setAttribute("ltail", "cluster"+node.get(src)); 405 edge.setAttribute("lhead", "cluster"+node.get(dst)); 406 } 407 } 408 409 File f = new File (SourceLocator.v().getOutputDir(), 410 prefix+name+DotGraph.DOT_EXTENSION); 411 dot.plot(f.getPath()); 412 } 413 414 415 422 public void copyResult(Object dst) 423 { 424 PurityGraph r = new PurityGraph(); 425 Iterator it = graph.getTails().iterator(); 426 while (it.hasNext()) { 427 Stmt stmt = (Stmt)it.next(); 428 PurityGraphBox ref = (PurityGraphBox) getFlowAfter(stmt); 429 r.union(ref.g); 430 } 431 r.removeLocals(); 432 ((PurityGraphBox)dst).g = r; 436 } 437 438 444 PurityIntraproceduralAnalysis(UnitGraph g, 445 AbstractInterproceduralAnalysis inter) 446 { 447 super(g); 448 this.inter = inter; 449 doAnalysis(); 450 } 451 } 452 453 454 | Popular Tags |