1 19 20 package soot.jimple.spark.builder; 21 import soot.jimple.spark.*; 22 import soot.jimple.spark.pag.*; 23 import soot.jimple.*; 24 import soot.*; 25 import soot.util.*; 26 import soot.toolkits.scalar.Pair; 27 import soot.jimple.spark.internal.*; 28 import soot.jimple.toolkits.callgraph.Edge; 29 import soot.shimple.*; 30 import java.util.*; 31 32 36 public class MethodNodeFactory extends AbstractShimpleValueSwitch { 37 public MethodNodeFactory( PAG pag, MethodPAG mpag ) { 38 this.pag = pag; 39 this.mpag = mpag; 40 setCurrentMethod( mpag.getMethod() ); 41 } 42 43 private void setCurrentMethod( SootMethod m ) { 44 method = m; 45 if( !m.isStatic() ) { 46 SootClass c = m.getDeclaringClass(); 47 if( c == null ) { 48 throw new RuntimeException ( "Method "+m+" has no declaring lass" ); 49 } 50 caseThis(); 51 } 52 for( int i = 0; i < m.getParameterCount(); i++ ) { 53 if( m.getParameterType(i) instanceof RefLikeType ) { 54 caseParm( i ); 55 } 56 } 57 Type retType = m.getReturnType(); 58 if( retType instanceof RefLikeType ) { 59 caseRet(); 60 } 61 } 62 63 public Node getNode( Value v ) { 64 v.apply( this ); 65 return getNode(); 66 } 67 68 final public void handleStmt( Stmt s ) { 69 if( s.containsInvokeExpr() ) { 70 return; 71 } 72 s.apply( new AbstractStmtSwitch() { 73 final public void caseAssignStmt(AssignStmt as) { 74 Value l = as.getLeftOp(); 75 Value r = as.getRightOp(); 76 if( !( l.getType() instanceof RefLikeType ) ) return; 77 l.apply( MethodNodeFactory.this ); 78 Node dest = getNode(); 79 r.apply( MethodNodeFactory.this ); 80 Node src = getNode(); 81 if( l instanceof InstanceFieldRef ) { 82 ((InstanceFieldRef) l).getBase().apply( MethodNodeFactory.this ); 83 pag.addDereference( (VarNode) getNode() ); 84 } 85 if( r instanceof InstanceFieldRef ) { 86 ((InstanceFieldRef) r).getBase().apply( MethodNodeFactory.this ); 87 pag.addDereference( (VarNode) getNode() ); 88 } 89 mpag.addInternalEdge( src, dest ); 90 } 91 final public void caseReturnStmt(ReturnStmt rs) { 92 if( !( rs.getOp().getType() instanceof RefLikeType ) ) return; 93 rs.getOp().apply( MethodNodeFactory.this ); 94 Node retNode = getNode(); 95 mpag.addInternalEdge( retNode, caseRet() ); 96 } 97 final public void caseIdentityStmt(IdentityStmt is) { 98 if( !( is.getLeftOp().getType() instanceof RefLikeType ) ) return; 99 is.getLeftOp().apply( MethodNodeFactory.this ); 100 Node dest = getNode(); 101 is.getRightOp().apply( MethodNodeFactory.this ); 102 Node src = getNode(); 103 mpag.addInternalEdge( src, dest ); 104 } 105 final public void caseThrowStmt(ThrowStmt ts) { 106 ts.getOp().apply( MethodNodeFactory.this ); 107 mpag.addOutEdge( getNode(), pag.nodeFactory().caseThrow() ); 108 } 109 } ); 110 } 111 final public Node getNode() { 112 return (Node) getResult(); 113 } 114 final public Node caseThis() { 115 VarNode ret = pag.makeLocalVarNode( 116 new Pair( method, PointsToAnalysis.THIS_NODE ), 117 method.getDeclaringClass().getType(), method ); 118 ret.setInterProcTarget(); 119 return ret; 120 } 121 122 final public Node caseParm( int index ) { 123 VarNode ret = pag.makeLocalVarNode( 124 new Pair( method, new Integer ( index ) ), 125 method.getParameterType( index ), method ); 126 ret.setInterProcTarget(); 127 return ret; 128 } 129 130 final public void casePhiExpr(PhiExpr e) { 131 Pair phiPair = new Pair( e, PointsToAnalysis.PHI_NODE ); 132 Node phiNode = pag.makeLocalVarNode( phiPair, e.getType(), method ); 133 for(Iterator opsIt = e.getValues().iterator(); opsIt.hasNext();){ 134 Value op = (Value) opsIt.next(); 135 op.apply( MethodNodeFactory.this ); 136 Node opNode = getNode(); 137 mpag.addInternalEdge( opNode, phiNode ); 138 } 139 setResult( phiNode ); 140 } 141 142 final public Node caseRet() { 143 VarNode ret = pag.makeLocalVarNode( 144 Parm.v( method, PointsToAnalysis.RETURN_NODE ), 145 method.getReturnType(), method ); 146 ret.setInterProcSource(); 147 return ret; 148 } 149 final public Node caseArray( VarNode base ) { 150 return pag.makeFieldRefNode( base, ArrayElement.v() ); 151 } 152 153 154 155 final public void caseArrayRef( ArrayRef ar ) { 159 caseLocal( (Local) ar.getBase() ); 160 setResult( caseArray( (VarNode) getNode() ) ); 161 } 162 final public void caseCastExpr( CastExpr ce ) { 163 Pair castPair = new Pair( ce, PointsToAnalysis.CAST_NODE ); 164 ce.getOp().apply( this ); 165 Node opNode = getNode(); 166 Node castNode = pag.makeLocalVarNode( castPair, ce.getCastType(), method ); 167 mpag.addInternalEdge( opNode, castNode ); 168 setResult( castNode ); 169 } 170 final public void caseCaughtExceptionRef( CaughtExceptionRef cer ) { 171 setResult( pag.nodeFactory().caseThrow() ); 172 } 173 final public void caseInstanceFieldRef( InstanceFieldRef ifr ) { 174 if( pag.getOpts().field_based() || pag.getOpts().vta() ) { 175 setResult( pag.makeGlobalVarNode( 176 ifr.getField(), 177 ifr.getField().getType() ) ); 178 } else { 179 setResult( pag.makeLocalFieldRefNode( 180 ifr.getBase(), 181 ifr.getBase().getType(), 182 ifr.getField(), 183 method ) ); 184 } 185 } 186 final public void caseLocal( Local l ) { 187 setResult( pag.makeLocalVarNode( l, l.getType(), method ) ); 188 } 189 final public void caseNewArrayExpr( NewArrayExpr nae ) { 190 setResult( pag.makeAllocNode( nae, nae.getType(), method ) ); 191 } 192 final public void caseNewExpr( NewExpr ne ) { 193 if( pag.getOpts().merge_stringbuffer() 194 && ne.getType().equals( RefType.v("java.lang.StringBuffer" ) ) ) { 195 setResult( pag.makeAllocNode( ne.getType(), ne.getType(), null ) ); 196 } else { 197 setResult( pag.makeAllocNode( ne, ne.getType(), method ) ); 198 } 199 } 200 final public void caseNewMultiArrayExpr( NewMultiArrayExpr nmae ) { 201 ArrayType type = (ArrayType) nmae.getType(); 202 AllocNode prevAn = pag.makeAllocNode( 203 new Pair( nmae, new Integer ( type.numDimensions ) ), type, method ); 204 VarNode prevVn = pag.makeLocalVarNode( prevAn, prevAn.getType(), null ); 205 mpag.addInternalEdge( prevAn, prevVn ); 206 setResult( prevAn ); 207 while( true ) { 208 Type t = type.getElementType(); 209 if( !( t instanceof ArrayType ) ) break; 210 type = (ArrayType) t; 211 AllocNode an = pag.makeAllocNode( 212 new Pair( nmae, new Integer ( type.numDimensions ) ), type, method ); 213 VarNode vn = pag.makeLocalVarNode( an, an.getType(), null ); 214 mpag.addInternalEdge( an, vn ); 215 mpag.addInternalEdge( vn, pag.makeFieldRefNode( prevVn, ArrayElement.v() ) ); 216 prevAn = an; 217 prevVn = vn; 218 } 219 } 220 final public void caseParameterRef( ParameterRef pr ) { 221 setResult( caseParm( pr.getIndex() ) ); 222 } 223 final public void caseStaticFieldRef( StaticFieldRef sfr ) { 224 setResult( pag.makeGlobalVarNode( 225 sfr.getField(), 226 sfr.getField().getType() ) ); 227 } 228 final public void caseStringConstant( StringConstant sc ) { 229 AllocNode stringConstant; 230 if( pag.getOpts().string_constants() 231 || Scene.v().containsClass(sc.value) 232 || ( sc.value.length() > 0 && sc.value.charAt(0) == '[' ) ) { 233 stringConstant = pag.makeStringConstantNode( sc.value ); 234 } else { 235 stringConstant = pag.makeAllocNode( 236 PointsToAnalysis.STRING_NODE, 237 RefType.v( "java.lang.String" ), null ); 238 } 239 VarNode stringConstantLocal = pag.makeGlobalVarNode( 240 stringConstant, 241 RefType.v( "java.lang.String" ) ); 242 pag.addEdge( stringConstant, stringConstantLocal ); 243 setResult( stringConstantLocal ); 244 } 245 final public void caseThisRef( ThisRef tr ) { 246 setResult( caseThis() ); 247 } 248 final public void caseNullConstant( NullConstant nr ) { 249 setResult( null ); 250 } 251 final public void caseClassConstant( ClassConstant cc ) { 252 AllocNode classConstant = pag.makeClassConstantNode(cc); 253 VarNode classConstantLocal = pag.makeGlobalVarNode( 254 classConstant, 255 RefType.v( "java.lang.Class" ) ); 256 pag.addEdge(classConstant, classConstantLocal); 257 setResult(classConstantLocal); 258 } 259 final public void defaultCase( Object v ) { 260 throw new RuntimeException ( "failed to handle "+v ); 261 } 262 protected PAG pag; 263 protected MethodPAG mpag; 264 protected SootMethod method; 265 } 266 267 | Popular Tags |