KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > spark > pag > MethodPAG


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2003 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.pag;
21 import java.util.*;
22
23 import soot.*;
24 import soot.jimple.*;
25 import soot.jimple.spark.*;
26 import soot.jimple.spark.builder.*;
27 import soot.jimple.spark.internal.*;
28 import soot.util.*;
29 import soot.util.queue.*;
30 import soot.toolkits.scalar.Pair;
31 import soot.jimple.toolkits.pointer.util.NativeMethodDriver;
32
33
34 /** Part of a pointer assignment graph for a single method.
35  * @author Ondrej Lhotak
36  */

37 public final class MethodPAG {
38     private PAG pag;
39     public PAG pag() { return pag; }
40
41     protected MethodPAG( PAG pag, SootMethod m ) {
42         this.pag = pag;
43         this.method = m;
44         this.nodeFactory = new MethodNodeFactory( pag, this );
45     }
46
47     private Set addedContexts;
48
49     /** Adds this method to the main PAG, with all VarNodes parameterized by
50      * varNodeParameter. */

51     public void addToPAG( Context varNodeParameter ) {
52         if( !hasBeenBuilt ) throw new RuntimeException JavaDoc();
53         if( varNodeParameter == null ) {
54             if( hasBeenAdded ) return;
55             hasBeenAdded = true;
56         } else {
57             if( addedContexts == null ) addedContexts = new HashSet();
58             if( !addedContexts.add( varNodeParameter ) ) return;
59         }
60         QueueReader reader = (QueueReader) internalReader.clone();
61         while(reader.hasNext()) {
62             Node src = (Node) reader.next();
63             src = parameterize( src, varNodeParameter );
64             Node dst = (Node) reader.next();
65             dst = parameterize( dst, varNodeParameter );
66             pag.addEdge( src, dst );
67         }
68         reader = (QueueReader) inReader.clone();
69         while(reader.hasNext()) {
70             Node src = (Node) reader.next();
71             Node dst = (Node) reader.next();
72             dst = parameterize( dst, varNodeParameter );
73             pag.addEdge( src, dst );
74         }
75         reader = (QueueReader) outReader.clone();
76         while(reader.hasNext()) {
77             Node src = (Node) reader.next();
78             src = parameterize( src, varNodeParameter );
79             Node dst = (Node) reader.next();
80             pag.addEdge( src, dst );
81         }
82     }
83     public void addInternalEdge( Node src, Node dst ) {
84         if( src == null ) return;
85         internalEdges.add( src );
86         internalEdges.add( dst );
87     }
88     public void addInEdge( Node src, Node dst ) {
89         if( src == null ) return;
90         inEdges.add( src );
91         inEdges.add( dst );
92     }
93     public void addOutEdge( Node src, Node dst ) {
94         if( src == null ) return;
95         outEdges.add( src );
96         outEdges.add( dst );
97     }
98     private ChunkedQueue internalEdges = new ChunkedQueue();
99     private ChunkedQueue inEdges = new ChunkedQueue();
100     private ChunkedQueue outEdges = new ChunkedQueue();
101     private QueueReader internalReader = internalEdges.reader();
102     private QueueReader inReader = inEdges.reader();
103     private QueueReader outReader = outEdges.reader();
104
105     SootMethod method;
106     public SootMethod getMethod() { return method; }
107     protected MethodNodeFactory nodeFactory;
108     public MethodNodeFactory nodeFactory() { return nodeFactory; }
109
110     public static MethodPAG v( PAG pag, SootMethod m ) {
111         MethodPAG ret = (MethodPAG) G.v().MethodPAG_methodToPag.get( m );
112         if( ret == null ) {
113             ret = new MethodPAG( pag, m );
114             G.v().MethodPAG_methodToPag.put( m, ret );
115         }
116         return ret;
117     }
118
119     public void build() {
120         if( hasBeenBuilt ) return;
121         hasBeenBuilt = true;
122         if( method.isNative() ) {
123             if( pag().getOpts().simulate_natives() ) {
124                 buildNative();
125             }
126         } else {
127             if( method.isConcrete() && !method.isPhantom() ) {
128                 buildNormal();
129             }
130         }
131         addMiscEdges();
132     }
133
134     protected VarNode parameterize( LocalVarNode vn, Context varNodeParameter ) {
135         SootMethod m = vn.getMethod();
136         if( m != method && m != null ) throw new RuntimeException JavaDoc( "VarNode "+vn+" with method "+m+" parameterized in method "+method );
137         //System.out.println( "parameterizing "+vn+" with "+varNodeParameter );
138
return pag().makeContextVarNode( vn, varNodeParameter );
139     }
140     protected FieldRefNode parameterize( FieldRefNode frn, Context varNodeParameter ) {
141         return pag().makeFieldRefNode(
142                 (VarNode) parameterize( frn.getBase(), varNodeParameter ),
143                 frn.getField() );
144     }
145     public Node parameterize( Node n, Context varNodeParameter ) {
146         if( varNodeParameter == null ) return n;
147         if( n instanceof LocalVarNode )
148             return parameterize( (LocalVarNode) n, varNodeParameter);
149         if( n instanceof FieldRefNode )
150             return parameterize( (FieldRefNode) n, varNodeParameter);
151         return n;
152     }
153     protected boolean hasBeenAdded = false;
154     protected boolean hasBeenBuilt = false;
155
156     protected void buildNormal() {
157         Body b = method.retrieveActiveBody();
158         Iterator unitsIt = b.getUnits().iterator();
159         while( unitsIt.hasNext() )
160         {
161             Stmt s = (Stmt) unitsIt.next();
162             nodeFactory.handleStmt( s );
163         }
164     }
165     protected void buildNative() {
166         ValNode thisNode = null;
167         ValNode retNode = null;
168         if( !method.isStatic() ) {
169         thisNode = (ValNode) nodeFactory.caseThis();
170         }
171         if( method.getReturnType() instanceof RefLikeType ) {
172         retNode = (ValNode) nodeFactory.caseRet();
173     }
174         ValNode[] args = new ValNode[ method.getParameterCount() ];
175         for( int i = 0; i < method.getParameterCount(); i++ ) {
176             if( !( method.getParameterType(i) instanceof RefLikeType ) ) continue;
177         args[i] = (ValNode) nodeFactory.caseParm(i);
178         }
179         pag.nativeMethodDriver.process( method, thisNode, retNode, args );
180     }
181
182     protected void addMiscEdges() {
183         // Add node for parameter (String[]) in main method
184
if( method.getSubSignature().equals( SootMethod.getSubSignature( "main", new SingletonList( ArrayType.v(RefType.v("java.lang.String"), 1) ), VoidType.v() ) ) ) {
185             addInEdge( pag().nodeFactory().caseArgv(), nodeFactory.caseParm(0) );
186         }
187
188         if( method.getSignature().equals(
189                     "<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.String)>" ) ) {
190             addInEdge( pag().nodeFactory().caseMainThread(), nodeFactory.caseThis() );
191             addInEdge( pag().nodeFactory().caseMainThreadGroup(), nodeFactory.caseParm( 0 ) );
192         }
193
194         if( method.getSubSignature().equals(
195             "java.lang.Class loadClass(java.lang.String)" ) ) {
196             SootClass c = method.getDeclaringClass();
197 outer: do {
198                 while( !c.getName().equals( "java.lang.ClassLoader" ) ) {
199                     if( !c.hasSuperclass() ) {
200                         break outer;
201                     }
202                     c = c.getSuperclass();
203                 }
204                 addInEdge( pag().nodeFactory().caseDefaultClassLoader(),
205                         nodeFactory.caseThis() );
206                 addInEdge( pag().nodeFactory().caseMainClassNameString(),
207                         nodeFactory.caseParm(0) );
208             } while( false );
209         }
210     }
211 }
212
213
Popular Tags