KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > javaToJimple > AnonInitBodyBuilder


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2004 Jennifer 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.javaToJimple;
21
22 import soot.*;
23 import java.util.*;
24
25 public class AnonInitBodyBuilder extends JimpleBodyBuilder {
26
27     public soot.jimple.JimpleBody createBody(soot.SootMethod sootMethod){
28         
29         body = soot.jimple.Jimple.v().newBody(sootMethod);
30        
31         lg = new LocalGenerator(body);
32
33         AnonClassInitMethodSource acims = (AnonClassInitMethodSource) body.getMethod().getSource();
34         ArrayList fields = acims.getFinalsList();
35         boolean inStaticMethod = acims.inStaticMethod();
36         boolean isSubType = acims.isSubType();
37         soot.Type superOuterType = acims.superOuterType();
38         soot.Type thisOuterType = acims.thisOuterType();
39         ArrayList fieldInits = acims.getFieldInits();
40         soot.Type outerClassType = acims.outerClassType();
41         polyglot.types.ClassType polyglotType = acims.polyglotType();
42         polyglot.types.ClassType anonType = acims.anonType();
43         
44         boolean hasOuterRef = ((AnonClassInitMethodSource)body.getMethod().getSource()).hasOuterRef();
45         boolean hasQualifier = ((AnonClassInitMethodSource)body.getMethod().getSource()).hasQualifier();
46         
47         // this formal needed
48
soot.RefType type = sootMethod.getDeclaringClass().getType();
49         specialThisLocal = soot.jimple.Jimple.v().newLocal("this", type);
50         body.getLocals().add(specialThisLocal);
51
52         soot.jimple.ThisRef thisRef = soot.jimple.Jimple.v().newThisRef(type);
53
54         soot.jimple.Stmt thisStmt = soot.jimple.Jimple.v().newIdentityStmt(specialThisLocal, thisRef);
55         body.getUnits().add(thisStmt);
56        
57         ArrayList invokeList = new ArrayList();
58         ArrayList invokeTypeList = new ArrayList();
59         
60         int numParams = sootMethod.getParameterCount();
61         int numFinals = 0;
62         
63         if (fields != null){
64             numFinals = fields.size();
65         }
66         
67         int startFinals = numParams - numFinals;
68         ArrayList paramsForFinals = new ArrayList();
69
70         soot.Local outerLocal = null;
71         soot.Local qualifierLocal = null;
72        
73         // param
74
Iterator fIt = sootMethod.getParameterTypes().iterator();
75         int counter = 0;
76         while (fIt.hasNext()){
77             soot.Type fType = (soot.Type)fIt.next();
78             soot.Local local = soot.jimple.Jimple.v().newLocal("r"+counter, fType);
79             body.getLocals().add(local);
80             soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(fType, counter);
81             
82             soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(local, paramRef);
83
84             
85             int realArgs = 0;
86             if ((hasOuterRef) && (counter == 0)){
87                 // in a non static method the first param is the outer ref
88
outerLocal = local;
89                 realArgs = 1;
90                 stmt.addTag(new soot.tagkit.EnclosingTag());
91             }
92             if ((hasOuterRef) && (hasQualifier) && (counter == 1)){
93                 // here second param is qualifier if there is one
94
qualifierLocal = local;
95                 realArgs = 2;
96                 invokeList.add(qualifierLocal);
97                 stmt.addTag(new soot.tagkit.QualifyingTag());
98             }
99             else if ((!hasOuterRef) && (hasQualifier) && (counter == 0)){
100                 qualifierLocal = local;
101                 realArgs = 1;
102                 invokeList.add(qualifierLocal);
103                 stmt.addTag(new soot.tagkit.QualifyingTag());
104             }
105             
106             if ((counter >= realArgs) && (counter < startFinals)){
107                 invokeTypeList.add(fType);
108                 invokeList.add(local);
109             }
110             else if (counter >= startFinals) {
111                 paramsForFinals.add(local);
112             }
113             body.getUnits().add(stmt);
114             counter++;
115         }
116         SootClass superClass = sootMethod.getDeclaringClass().getSuperclass();
117
118         //ArrayList needsRef = needsOuterClassRef(polyglotOuterType);//soot.javaToJimple.InitialResolver.v().getHasOuterRefInInit();
119
if (needsOuterClassRef(polyglotType)){
120         //if ((needsRef != null) && (needsRef.contains(superClass.getType())) ){
121
invokeTypeList.add(0, superOuterType);
122         }
123         SootMethodRef callMethod = Scene.v().makeMethodRef( sootMethod.getDeclaringClass().getSuperclass(), "<init>", invokeTypeList, VoidType.v(), false);
124         if ((!hasQualifier) && (needsOuterClassRef(polyglotType))){// && (needsRef.contains(superClass.getType()))){
125
if (isSubType){
126                 invokeList.add(0, outerLocal);
127             }
128             else {
129                 invokeList.add(0, Util.getThisGivenOuter(superOuterType, new HashMap(), body, new LocalGenerator(body), outerLocal));
130             }
131         }
132         soot.jimple.InvokeExpr invoke = soot.jimple.Jimple.v().newSpecialInvokeExpr(specialThisLocal, callMethod, invokeList);
133
134         soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(invoke);
135         body.getUnits().add(invokeStmt);
136        
137         //System.out.println("polyglotType: "+polyglotType+" needs ref: "+needsOuterClassRef(polyglotType));
138

139         // field assign
140
if (!inStaticMethod && needsOuterClassRef(anonType)){
141             soot.SootFieldRef field = Scene.v().makeFieldRef( sootMethod.getDeclaringClass(), "this$0", outerClassType, false);
142             soot.jimple.InstanceFieldRef ref = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, field);
143             soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(ref, outerLocal);
144             body.getUnits().add(assign);
145         }
146         if (fields != null){
147             Iterator finalsIt = paramsForFinals.iterator();
148             Iterator fieldsIt = fields.iterator();
149             while (finalsIt.hasNext() && fieldsIt.hasNext()){
150             
151                 soot.Local pLocal = (soot.Local)finalsIt.next();
152                 soot.SootField pField = (soot.SootField)fieldsIt.next();
153             
154                 soot.jimple.FieldRef pRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, pField.makeRef());
155             
156                 soot.jimple.AssignStmt pAssign = soot.jimple.Jimple.v().newAssignStmt(pRef, pLocal);
157                 body.getUnits().add(pAssign);
158  
159             }
160         }
161
162         // need to be able to handle any kind of field inits -> make this class
163
// extend JimpleBodyBuilder to have access to everything
164

165         if (fieldInits != null) {
166             handleFieldInits(fieldInits);
167         }
168    
169         ArrayList staticBlocks = ((AnonClassInitMethodSource)body.getMethod().getSource()).getInitializerBlocks();
170         if (staticBlocks != null){
171             handleStaticBlocks(staticBlocks);
172         }
173         
174         // return
175
soot.jimple.ReturnVoidStmt retStmt = soot.jimple.Jimple.v().newReturnVoidStmt();
176         body.getUnits().add(retStmt);
177         
178     
179         return body;
180     }
181 }
182
Popular Tags