1 19 20 package soot.jimple.toolkits.pointer; 21 import java.util.*; 22 import soot.toolkits.scalar.*; 23 import soot.toolkits.graph.*; 24 import soot.*; 25 import soot.util.*; 26 import soot.jimple.*; 27 28 29 public class CastCheckEliminator extends ForwardBranchedFlowAnalysis { 30 Map unitToKill = new HashMap(); 31 Map unitToGenFallThrough = new HashMap(); 32 Map unitToGenBranch = new HashMap(); 33 LocalTypeSet emptySet; 34 35 public CastCheckEliminator(BriefUnitGraph cfg) { 36 super(cfg); 37 makeInitialSet(); 38 doAnalysis(); 39 tagCasts(); 40 } 41 42 43 protected void tagCasts() { 44 for( Iterator sIt = ((UnitGraph)graph).getBody().getUnits().iterator(); sIt.hasNext(); ) { 45 final Stmt s = (Stmt) sIt.next(); 46 if( s instanceof AssignStmt ) { 47 AssignStmt as = (AssignStmt) s; 48 Value rhs = as.getRightOp(); 49 if( rhs instanceof CastExpr ) { 50 CastExpr cast = (CastExpr) rhs; 51 Type t = cast.getCastType(); 52 if( t instanceof RefType ) { 53 if( cast.getOp() instanceof Local ) { 54 Local l = (Local) cast.getOp(); 55 LocalTypeSet set = (LocalTypeSet) unitToBeforeFlow.get(s); 56 s.addTag( new CastCheckTag( set.get( set.indexOf( 57 l, (RefType) t ) ) ) ); 58 } else { 59 NullConstant nc = (NullConstant) cast.getOp(); 60 s.addTag( new CastCheckTag( true ) ); 61 } 62 } 63 } 64 } 65 } 66 } 67 68 71 protected void makeInitialSet() { 72 Chain locals = ((UnitGraph)graph).getBody().getLocals(); 74 List refLocals = new ArrayList(); 75 for( Iterator lIt = locals.iterator(); lIt.hasNext(); ) { 76 final Local l = (Local) lIt.next(); 77 if( l.getType() instanceof RefType ) { 78 refLocals.add( l ); 79 } 80 } 81 82 List types = new ArrayList(); 84 for( Iterator sIt = ((UnitGraph)graph).getBody().getUnits().iterator(); sIt.hasNext(); ) { 85 final Stmt s = (Stmt) sIt.next(); 86 if( s instanceof AssignStmt ) { 87 AssignStmt as = (AssignStmt) s; 88 Value rhs = as.getRightOp(); 89 if( rhs instanceof CastExpr ) { 90 Type t = ( (CastExpr) rhs ).getCastType(); 91 if( t instanceof RefType && !types.contains( t ) ) { 92 types.add( t ); 93 } 94 } 95 } 96 } 97 98 emptySet = new LocalTypeSet( refLocals, types ); 99 } 100 101 102 103 protected Object newInitialFlow() { 104 LocalTypeSet ret = (LocalTypeSet) emptySet.clone(); 105 ret.setAllBits(); 106 return ret; 107 } 108 109 110 protected void flowThrough( Object inValue, Unit unit, List outFallValues, 111 List outBranchValues ) 112 { 113 final LocalTypeSet in = (LocalTypeSet) inValue; 114 final LocalTypeSet out = (LocalTypeSet) in.clone(); 115 LocalTypeSet outBranch = out; final Stmt stmt = (Stmt) unit; 117 118 for( Iterator bIt = stmt.getDefBoxes().iterator(); bIt.hasNext(); ) { 120 final ValueBox b = (ValueBox) bIt.next(); 121 Value v = b.getValue(); 122 if( v instanceof Local && v.getType() instanceof RefType ) { 123 out.killLocal( (Local) v ); 124 } 125 } 126 127 if( stmt instanceof AssignStmt ) { 129 AssignStmt astmt = (AssignStmt) stmt; 130 Value rhs = astmt.getRightOp(); 131 Value lhs = astmt.getLeftOp(); 132 if( lhs instanceof Local && rhs.getType() instanceof RefType ) { 133 Local l = (Local) lhs; 134 if( rhs instanceof NewExpr ) { 135 out.localMustBeSubtypeOf( l, (RefType) rhs.getType() ); 136 } else if( rhs instanceof CastExpr ) { 137 CastExpr cast = (CastExpr) rhs; 138 Type castType = cast.getCastType(); 139 if( castType instanceof RefType 140 && cast.getOp() instanceof Local ) { 141 RefType refType = (RefType) castType; 142 Local opLocal = (Local) cast.getOp(); 143 out.localCopy( l, opLocal ); 144 out.localMustBeSubtypeOf( l, refType ); 145 out.localMustBeSubtypeOf( opLocal, refType ); 146 } 147 } else if( rhs instanceof Local ) { 148 out.localCopy( l, (Local) rhs ); 149 } 150 } 151 152 } else if( stmt instanceof IfStmt ) { 154 IfStmt ifstmt = (IfStmt) stmt; 155 156 do { 160 if( graph.getPredsOf( stmt ).size() != 1 ) break; 161 Object predecessor = (Stmt) graph.getPredsOf( stmt ).get(0); 162 if( !( predecessor instanceof AssignStmt ) ) break; 163 AssignStmt pred = (AssignStmt) predecessor; 164 if( !(pred.getRightOp() instanceof InstanceOfExpr ) ) break; 165 InstanceOfExpr iofexpr = (InstanceOfExpr) pred.getRightOp(); 166 if( !(iofexpr.getCheckType() instanceof RefType ) ) break; 167 if( !(iofexpr.getOp() instanceof Local ) ) break; 168 ConditionExpr c = (ConditionExpr) ifstmt.getCondition(); 169 if( !c.getOp1().equals( pred.getLeftOp() ) ) break; 170 if( !( c.getOp2() instanceof IntConstant ) ) break; 171 if( ( (IntConstant) c.getOp2() ).value != 0 ) break; 172 if( c instanceof NeExpr ) { 173 outBranch = (LocalTypeSet) out.clone(); 177 outBranch.localMustBeSubtypeOf( (Local) iofexpr.getOp(), 178 (RefType) iofexpr.getCheckType() ); 179 } else if( c instanceof EqExpr ) { 180 outBranch = (LocalTypeSet) out.clone(); 184 out.localMustBeSubtypeOf( (Local) iofexpr.getOp(), 185 (RefType) iofexpr.getCheckType() ); 186 } 187 } while( false ); 188 } 189 190 for( Iterator it = outFallValues.iterator(); it.hasNext(); ) { 192 copy( out, it.next() ); 193 } 194 for( Iterator it = outBranchValues.iterator(); it.hasNext(); ) { 195 copy( outBranch, it.next() ); 196 } 197 } 198 199 protected void copy( Object source, Object dest ) { 200 LocalTypeSet s = (LocalTypeSet) source; 201 LocalTypeSet d = (LocalTypeSet) dest; 202 d.and( s ); 203 d.or( s ); 204 } 205 206 protected void merge( Object in1, Object in2, Object out ) { 208 LocalTypeSet o = (LocalTypeSet) out; 209 o.setAllBits(); 210 o.and( (LocalTypeSet) in1 ); 211 o.and( (LocalTypeSet) in2 ); 212 } 213 214 215 protected Object entryInitialFlow() { 216 LocalTypeSet ret = (LocalTypeSet) emptySet.clone(); 217 return ret; 218 } 219 } 220 221 | Popular Tags |