KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > internal > JAssignStmt


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1999 Patrick Lam
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 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27
28
29
30
31 package soot.jimple.internal;
32
33 import soot.tagkit.*;
34 import soot.*;
35 import soot.jimple.*;
36 import soot.baf.*;
37 import soot.jimple.*;
38 import soot.util.*;
39 import java.util.*;
40
41 public class JAssignStmt extends AbstractDefinitionStmt
42     implements AssignStmt
43 {
44     private class LinkedVariableBox extends VariableBox
45     {
46         ValueBox otherBox = null;
47
48         private LinkedVariableBox(Value v)
49         {
50             super(v);
51         }
52
53         public void setOtherBox(ValueBox otherBox) { this.otherBox = otherBox; }
54
55         public boolean canContainValue(Value v)
56         {
57             if (otherBox == null) return super.canContainValue(v);
58             Value other = otherBox.getValue();
59             return super.canContainValue(v) &&
60                 ((v instanceof Local || v instanceof Constant) || (other instanceof Local || other instanceof Constant));
61         }
62     }
63
64     private class LinkedRValueBox extends RValueBox
65     {
66         ValueBox otherBox = null;
67
68         private LinkedRValueBox(Value v)
69         {
70             super(v);
71         }
72
73         public void setOtherBox(ValueBox otherBox) { this.otherBox = otherBox; }
74
75         public boolean canContainValue(Value v)
76         {
77             if (otherBox == null) return super.canContainValue(v);
78             Value other = otherBox.getValue();
79             return super.canContainValue(v) &&
80                 ((v instanceof Local || v instanceof Constant) || (other instanceof Local || other instanceof Constant));
81         }
82     }
83
84     public JAssignStmt(Value variable, Value rvalue)
85     {
86         leftBox = new LinkedVariableBox(variable);
87         rightBox = new LinkedRValueBox(rvalue);
88
89         ((LinkedVariableBox)leftBox).setOtherBox(rightBox);
90         ((LinkedRValueBox)rightBox).setOtherBox(leftBox);
91
92         if(!leftBox.canContainValue(variable) ||
93             !rightBox.canContainValue(rvalue))
94             throw new RuntimeException JavaDoc("Illegal assignment statement. Make sure that either left side or right hand side has a local or constant.");
95                     
96         
97         defBoxes = new SingletonList(leftBox);
98     }
99
100     protected JAssignStmt(ValueBox variableBox, ValueBox rvalueBox)
101     {
102         this.leftBox = variableBox;
103         this.rightBox = rvalueBox;
104
105         defBoxes = new SingletonList(leftBox);
106     }
107
108     public boolean containsInvokeExpr()
109     {
110         return rightBox.getValue() instanceof InvokeExpr;
111     }
112
113     public InvokeExpr getInvokeExpr()
114     {
115         if (!containsInvokeExpr())
116             throw new RuntimeException JavaDoc("getInvokeExpr() called with no invokeExpr present!");
117
118         return (InvokeExpr)rightBox.getValue();
119     }
120
121     public ValueBox getInvokeExprBox()
122     {
123         if (!containsInvokeExpr())
124             throw new RuntimeException JavaDoc("getInvokeExpr() called with no invokeExpr present!");
125
126         return rightBox;
127     }
128
129     /* added by Feng */
130     public boolean containsArrayRef()
131     {
132     return ((leftBox.getValue() instanceof ArrayRef) || (rightBox.getValue() instanceof ArrayRef));
133     }
134
135     public ArrayRef getArrayRef()
136     {
137     if (!containsArrayRef())
138         throw new RuntimeException JavaDoc("getArrayRef() called with no ArrayRef present!");
139
140     if (leftBox.getValue() instanceof ArrayRef)
141         return (ArrayRef) leftBox.getValue();
142     else
143         return (ArrayRef) rightBox.getValue();
144     }
145
146     public ValueBox getArrayRefBox()
147     {
148     if (!containsArrayRef())
149         throw new RuntimeException JavaDoc("getArrayRefBox() called with no ArrayRef present!");
150     
151     if (leftBox.getValue() instanceof ArrayRef)
152         return leftBox;
153     else
154         return rightBox;
155     }
156
157     public boolean containsFieldRef()
158     {
159     return ((leftBox.getValue() instanceof FieldRef) || (rightBox.getValue() instanceof FieldRef));
160     }
161
162     public FieldRef getFieldRef()
163     {
164     if (!containsFieldRef())
165         throw new RuntimeException JavaDoc("getFieldRef() called with no FieldRef present!");
166     
167     if (leftBox.getValue() instanceof FieldRef)
168         return (FieldRef) leftBox.getValue();
169     else
170         return (FieldRef) rightBox.getValue();
171     }
172
173     public ValueBox getFieldRefBox()
174     {
175     if (!containsFieldRef())
176         throw new RuntimeException JavaDoc("getFieldRefBox() called with no FieldRef present!");
177     
178     if (leftBox.getValue() instanceof FieldRef)
179         return leftBox;
180     else
181         return rightBox;
182     }
183
184     public List getUnitBoxes()
185     {
186         // handle possible PhiExpr's
187
Value rValue = rightBox.getValue();
188         if(rValue instanceof UnitBoxOwner)
189             return ((UnitBoxOwner)rValue).getUnitBoxes();
190
191         return super.getUnitBoxes();
192     }
193       
194     public String JavaDoc toString()
195     {
196         return leftBox.getValue().toString() + " = " + rightBox.getValue().toString();
197     }
198     
199     public void toString(UnitPrinter up) {
200         leftBox.toString(up);
201         up.literal(" = ");
202         rightBox.toString(up);
203     }
204
205     public Object JavaDoc clone()
206     {
207             return new JAssignStmt(Jimple.cloneIfNecessary(getLeftOp()), Jimple.cloneIfNecessary(getRightOp()));
208     }
209
210     public void setLeftOp(Value variable)
211     {
212         leftBox.setValue(variable);
213     }
214
215     public void setRightOp(Value rvalue)
216     {
217         rightBox.setValue(rvalue);
218     }
219
220     public void apply(Switch sw)
221     {
222         ((StmtSwitch) sw).caseAssignStmt(this);
223     }
224
225     public void convertToBaf(final JimpleToBafContext context, final List out)
226     {
227         final Value lvalue = this.getLeftOp();
228         final Value rvalue = this.getRightOp();
229
230         
231         // Handle simple subcase where you can use the efficient iinc bytecode
232
if(lvalue instanceof Local && (rvalue instanceof AddExpr || rvalue instanceof SubExpr))
233             {
234                 Local l = (Local) lvalue;
235                 BinopExpr expr = (BinopExpr) rvalue;
236                 Value op1 = expr.getOp1();
237                 Value op2 = expr.getOp2();
238                                 
239                 if(l.getType().equals(IntType.v()))
240                 {
241                     boolean isValidCase = false;
242                     int x = 0;
243                     
244                     if(op1 == l && op2 instanceof IntConstant)
245                     {
246                         x = ((IntConstant) op2).value;
247                         isValidCase = true;
248                     }
249                     else if(expr instanceof AddExpr &&
250                         op2 == l && op1 instanceof IntConstant)
251                     {
252                         // Note expr can't be a SubExpr because that would be x = 3 - x
253

254                         
255                         x = ((IntConstant) op1).value;
256                         isValidCase = true;
257                     }
258                     
259                     if(isValidCase && x >= Short.MIN_VALUE && x <= Short.MAX_VALUE)
260                     {
261             Unit u = Baf.v().newIncInst(context.getBafLocalOfJimpleLocal(l),
262                                                     IntConstant.v((expr instanceof AddExpr) ? x : -x));
263                         out.add(u);
264             Iterator it = getTags().iterator();
265             while(it.hasNext()) {
266                 u.addTag((Tag) it.next());
267             }
268             return;
269                     }
270                 }
271             }
272
273         context.setCurrentUnit(this);
274
275             lvalue.apply(new AbstractJimpleValueSwitch()
276             {
277                 public void caseArrayRef(ArrayRef v)
278                 {
279                     ((ConvertToBaf)(v.getBase())).convertToBaf(context, out);
280                     ((ConvertToBaf)(v.getIndex())).convertToBaf(context, out);
281                     ((ConvertToBaf) rvalue).convertToBaf(context, out);
282                     
283             Unit u = Baf.v().newArrayWriteInst(v.getType());
284             Iterator it = getTags().iterator();
285             while(it.hasNext()) {
286             u.addTag((Tag) it.next());
287             }
288             
289                     out.add(u);
290                 }
291                 
292                 public void defaultCase(Value v)
293                 {
294                     throw new RuntimeException JavaDoc("Can't store in value " + v);
295                 }
296                 
297                 public void caseInstanceFieldRef(InstanceFieldRef v)
298                 {
299                     ((ConvertToBaf)(v.getBase())).convertToBaf(context, out);
300                     ((ConvertToBaf) rvalue).convertToBaf(context, out);
301
302
303             
304             Unit u = Baf.v().newFieldPutInst(v.getFieldRef());
305             Iterator it = getTags().iterator();
306             while(it.hasNext()) {
307             u.addTag((Tag) it.next());
308             }
309
310                     out.add(u);
311                 }
312                 
313                 public void caseLocal(final Local v)
314                 {
315                     ((ConvertToBaf) rvalue).convertToBaf(context, out);
316
317                     /* Add the tags to the statement that COMPUTES the
318                      * value, NOT to the statement that stores it. */

319                     
320                     /* No: the convertToBaf on the rvalue already adds
321                      * them, so no need to add them here. However, with
322                      * the current semantics, we should add them to every
323                      * statement and let the aggregator sort them out.
324                      */

325
326                     Unit u = Baf.v().newStoreInst(v.getType(),
327                                         context.getBafLocalOfJimpleLocal(v));
328
329             Iterator it = getTags().iterator();
330             while(it.hasNext()) {
331             u.addTag((Tag) it.next());
332             }
333
334                     out.add(u);
335
336                 }
337                 
338                 public void caseStaticFieldRef(StaticFieldRef v)
339                 {
340                     ((ConvertToBaf) rvalue).convertToBaf(context, out);
341
342             Unit u = Baf.v().newStaticPutInst(v.getFieldRef());
343             Iterator it = getTags().iterator();
344             while(it.hasNext()) {
345             u.addTag((Tag) it.next());
346             }
347
348                     out.add(u);
349                 }
350             });
351     }
352 }
353
354
355
356
357
Popular Tags