KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > spark > builder > MethodNodeFactory


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2002 Ondrej Lhotak
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

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 /** Class implementing builder parameters (this decides
33  * what kinds of nodes should be built for each kind of Soot value).
34  * @author Ondrej Lhotak
35  */

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     /** Sets the method for which a graph is currently being built. */
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 JavaDoc( "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     /** Adds the edges required for this statement to the graph. */
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 JavaDoc( 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     /* End of public methods. */
153     /* End of package methods. */
154
155     // OK, these ones are public, but they really shouldn't be; it's just
156
// that Java requires them to be, because they override those other
157
// public methods.
158
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 JavaDoc( 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 JavaDoc( 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 JavaDoc v ) {
260     throw new RuntimeException JavaDoc( "failed to handle "+v );
261     }
262     protected PAG pag;
263     protected MethodPAG mpag;
264     protected SootMethod method;
265 }
266
267
Popular Tags