KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > javaToJimple > AccessFieldJBB


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 java.util.*;
23
24
25 public class AccessFieldJBB extends AbstractJimpleBodyBuilder{
26
27     public AccessFieldJBB(){
28         //ext(null);
29
//base(this);
30
}
31
32     protected boolean needsAccessor(polyglot.ast.Expr expr){
33         if (expr instanceof soot.javaToJimple.jj.ast.JjAccessField_c){
34             return true;
35         }
36         else {
37             return ext().needsAccessor(expr);
38         }
39     }
40
41     protected soot.Local handlePrivateFieldUnarySet(polyglot.ast.Unary unary){
42         if (unary.expr() instanceof soot.javaToJimple.jj.ast.JjAccessField_c){
43             // not sure about strings here but...
44
soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)unary.expr();
45           
46             // create field target
47
soot.Local baseLocal = (soot.Local)base().getBaseLocal(accessField.field().target());
48             //soot.Value fieldGetLocal = getPrivateAccessFieldLocal(accessField, base);
49
soot.Local fieldGetLocal = handleCall(accessField.field(), accessField.getMeth(), null, baseLocal);
50
51             soot.Local tmp = base().generateLocal(accessField.field().type());
52             soot.jimple.AssignStmt stmt1 = soot.jimple.Jimple.v().newAssignStmt(tmp, fieldGetLocal);
53             ext().body.getUnits().add(stmt1);
54             Util.addLnPosTags(stmt1, unary.position());
55             soot.Value incVal = base().getConstant(Util.getSootType(accessField.field().type()), 1);
56             soot.jimple.BinopExpr binExpr;
57             if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.POST_INC){
58                 binExpr = soot.jimple.Jimple.v().newAddExpr(tmp, incVal);
59             }
60             else {
61                 binExpr = soot.jimple.Jimple.v().newSubExpr(tmp, incVal);
62             }
63             soot.Local tmp2 = generateLocal(accessField.field().type());
64             soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(tmp2, binExpr);
65             ext().body.getUnits().add(assign);
66             if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.PRE_DEC){
67                 return base().handlePrivateFieldSet(accessField, tmp2, baseLocal);
68             }
69             else {
70                 base().handlePrivateFieldSet(accessField, tmp2, baseLocal);
71                 return tmp;
72             }
73         }
74         else {
75             return ext().handlePrivateFieldUnarySet(unary);
76         }
77     
78     }
79     protected soot.Local handlePrivateFieldAssignSet(polyglot.ast.Assign assign){
80         if (assign.left() instanceof soot.javaToJimple.jj.ast.JjAccessField_c){
81             // not sure about strings here but...
82
soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)assign.left();
83           
84             // create field target
85
soot.Local baseLocal = (soot.Local)base().getBaseLocal(accessField.field().target());
86             if (assign.operator() == polyglot.ast.Assign.ASSIGN){
87                 soot.Value right = base().getSimpleAssignRightLocal(assign);
88                 return base().handlePrivateFieldSet(accessField, right, baseLocal);
89             }
90             else {
91
92                 // create field get using target
93
soot.Local leftLocal = handleCall(accessField.field(), accessField.getMeth(), null, baseLocal);
94                 // handle field set using same target
95
//soot.Local leftLocal = (soot.Local)base().createExpr(accessField);
96
soot.Value right = base().getAssignRightLocal(assign, leftLocal);
97                 return handleFieldSet(accessField, right, baseLocal);
98             }
99         }
100         else {
101             return ext().handlePrivateFieldAssignSet(assign);
102         }
103     }
104
105     private soot.Local handleCall(polyglot.ast.Field field, polyglot.ast.Call call, soot.Value param, soot.Local base){
106         
107         soot.Type sootRecType = Util.getSootType(call.target().type());
108         soot.SootClass receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object");
109         if (sootRecType instanceof soot.RefType){
110             receiverTypeClass = ((soot.RefType)sootRecType).getSootClass();
111         }
112         
113         soot.SootMethodRef methToCall = base().getSootMethodRef(call);
114         ArrayList params = new ArrayList();
115         /*if (!field.flags().isStatic()){
116             //params.add(base().getThis(Util.getSootType(field.target().type())));
117             params.add((soot.Local)ext().getBaseLocal(field.target()));
118         }*/

119         if (param != null){
120             params.add(param);
121         }
122         soot.jimple.InvokeExpr invoke;
123         
124         soot.Local baseLocal = base;
125         if (base == null){
126             baseLocal = (soot.Local)ext().getBaseLocal((polyglot.ast.Receiver)call.target());
127         }
128         if (methToCall.isStatic()){
129             invoke = soot.jimple.Jimple.v().newStaticInvokeExpr(methToCall, params);
130         }
131         else if (soot.Modifier.isInterface(receiverTypeClass.getModifiers()) &&
132 call.methodInstance().flags().isAbstract()){
133             invoke = soot.jimple.Jimple.v().newInterfaceInvokeExpr(baseLocal, methToCall, params);
134         }
135         else {
136             invoke = soot.jimple.Jimple.v().newVirtualInvokeExpr(baseLocal, methToCall, params);
137         }
138         soot.Local retLocal = base().generateLocal(field.type());
139         soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invoke);
140         ext().body.getUnits().add(assignStmt);
141         
142         return retLocal;
143     }
144     
145     protected soot.Local handlePrivateFieldSet(polyglot.ast.Expr expr, soot.Value right, soot.Value baseLocal){
146         if (expr instanceof soot.javaToJimple.jj.ast.JjAccessField_c){
147             soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)expr;
148             return handleCall(accessField.field(), accessField.setMeth(), right, null);
149         }
150         else {
151             return ext().handlePrivateFieldSet(expr, right, baseLocal);
152         }
153     }
154
155     private soot.Local handleFieldSet(soot.javaToJimple.jj.ast.JjAccessField_c accessField, soot.Value right, soot.Local base){
156         return handleCall(accessField.field(), accessField.setMeth(), right, base);
157     }
158     protected soot.Value createExpr(polyglot.ast.Expr expr){
159         if (expr instanceof soot.javaToJimple.jj.ast.JjAccessField_c){
160             soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)expr;
161          
162             
163             // here is where we need to return the field using get method
164
return handleCall(accessField.field(), accessField.getMeth(), null, null);
165             // return ext().createExpr(accessField.field());
166
}
167         else {
168             return ext().createExpr(expr);
169         }
170     }
171
172     protected soot.Value createLHS(polyglot.ast.Expr expr){
173         if (expr instanceof soot.javaToJimple.jj.ast.JjAccessField_c) {
174             soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)expr;
175         
176             return handleCall(accessField.field(), accessField.getMeth(), null, null);//base().getFieldRef(accessField.field());
177
}
178         else {
179             return ext().createLHS(expr);
180         }
181     }
182     
183 }
184
Popular Tags