1 19 20 package soot.jimple.toolkits.annotation.nullcheck; 21 22 import java.util.*; 23 import soot.*; 24 import soot.jimple.*; 25 import soot.toolkits.graph.UnitGraph; 26 import soot.toolkits.graph.ExceptionalUnitGraph; 27 import soot.toolkits.scalar.FlowSet; 28 import soot.util.Chain; 29 30 public class NullCheckEliminator extends BodyTransformer { 31 32 public static class AnalysisFactory { 33 public BranchedRefVarsAnalysis newAnalysis(UnitGraph g) { 34 return new BranchedRefVarsAnalysis(g); 35 } 36 } 37 38 private AnalysisFactory analysisFactory; 39 40 public NullCheckEliminator() { 41 this(new AnalysisFactory()); 42 } 43 44 public NullCheckEliminator(AnalysisFactory f) { 45 this.analysisFactory=f; 46 } 47 48 public void internalTransform(Body body, String phaseName, Map options) { 49 50 boolean changed; 53 int i=0; 54 do { 55 changed=false; 56 57 BranchedRefVarsAnalysis analysis=analysisFactory.newAnalysis(new ExceptionalUnitGraph(body)); 58 59 Chain units=body.getUnits(); 60 Stmt s; 61 for(s=(Stmt) units.getFirst();s!=null;s=(Stmt) units.getSuccOf(s)) { 62 if(!(s instanceof IfStmt)) continue; 63 IfStmt is=(IfStmt) s; 64 Value c=is.getCondition(); 65 if(!(c instanceof EqExpr || c instanceof NeExpr)) continue; 66 BinopExpr e=(BinopExpr) c; 67 Value v=null; 68 if(e.getOp1() instanceof NullConstant) v=e.getOp2(); 69 if(e.getOp2() instanceof NullConstant) v=e.getOp1(); 70 if(v==null) continue; 71 int res=analysis.anyRefInfo(v,(FlowSet) analysis.getFlowBefore(s)); 72 int elim=0; if(res==BranchedRefVarsAnalysis.kNonNull) elim=c instanceof EqExpr ? -1 : 1; 74 if(res==BranchedRefVarsAnalysis.kNull) elim=c instanceof EqExpr ? 1 : -1; 75 Stmt newstmt=null; 76 if(elim==-1) newstmt=Jimple.v().newNopStmt(); 77 if(elim==1) newstmt=Jimple.v().newGotoStmt(is.getTarget()); 78 if(newstmt!=null) { 79 units.swapWith(s,newstmt); 80 s=newstmt; 81 changed=true; 82 } 83 } 84 } while(changed); 85 } 86 87 } 88 | Popular Tags |