KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > flow > CreateAssignExpression


1 /* CreateAssignExpression Copyright (C) 1998-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; see the file COPYING.LESSER. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: CreateAssignExpression.java,v 1.20.2.2 2002/05/28 17:34:08 hoenicke Exp $
18  */

19
20 package jode.flow;
21 import jode.expr.*;
22 import jode.type.Type;
23
24 public class CreateAssignExpression {
25
26     public static boolean transform(InstructionContainer ic,
27                              StructuredBlock last) {
28         if (!(last.outer instanceof SequentialBlock)
29             || !(ic.getInstruction() instanceof StoreInstruction)
30             || !(ic.getInstruction().isVoid()))
31             return false;
32         
33         return (createAssignOp(ic, last) || createAssignExpression(ic, last));
34     }
35
36     public static boolean createAssignOp(InstructionContainer ic,
37                                          StructuredBlock last) {
38
39         /* Situation:
40          *
41          * (push loadstoreOps) <- not checked
42          * sequBlock:
43          * dup (may be missing for static / local variables)
44          * opBlock:
45          * PUSH (optional narrow)((optional wide) load(stack) * RHS)
46          * (optional dup_x)
47          * store(POP)
48          *
49          * We transform it to:
50          * (push loadstoreOps)
51          * rightHandSide
52      * (optional dup_x)
53          * store(stack) *= (stack)
54          *
55          * If the optional dup is present the store*= becomes non void. */

56
57         SequentialBlock opBlock = (SequentialBlock) last.outer;
58         StoreInstruction store = (StoreInstruction) ic.getInstruction();
59     if (!store.isFreeOperator() || store.isOpAssign())
60         return false;
61     Expression lvalue = store.getSubExpressions()[0];
62     int lvalueCount = lvalue.getFreeOperandCount();
63
64         boolean isAssignOp = false;
65         if (opBlock.subBlocks[0] instanceof SpecialBlock) {
66             SpecialBlock dup = (SpecialBlock) opBlock.subBlocks[0];
67             if (dup.type != SpecialBlock.DUP
68                 || dup.depth != lvalueCount
69                 || dup.count != lvalue.getType().stackSize()
70                 || !(opBlock.outer instanceof SequentialBlock))
71                 return false;
72             opBlock = (SequentialBlock) opBlock.outer;
73             isAssignOp = true;
74         }
75
76         if (!(opBlock.subBlocks[0] instanceof InstructionBlock))
77             return false;
78
79         InstructionBlock ib = (InstructionBlock) opBlock.subBlocks[0];
80     if (!(ib.getInstruction() instanceof Operator))
81         return false;
82     Operator expr = (Operator) ib.getInstruction();
83     if (expr.getFreeOperandCount() != lvalueCount)
84         return false;
85     Type rvalueType = expr.getType();
86     
87     SpecialBlock dup = null;
88         
89     if (lvalueCount > 0) {
90         if (!(opBlock.outer instanceof SequentialBlock)
91         || !(opBlock.outer.getSubBlocks()[0] instanceof SpecialBlock))
92         return false;
93         
94         SequentialBlock sequBlock = (SequentialBlock) opBlock.outer;
95         dup = (SpecialBlock) sequBlock.subBlocks[0];
96         
97         if (dup.type != SpecialBlock.DUP
98         || dup.depth != 0 || dup.count != lvalueCount)
99         return false;
100     }
101         int opIndex;
102         Expression rightHandSide;
103
104         if (expr instanceof ConvertOperator
105             && expr.getSubExpressions()[0] instanceof Operator
106             && expr.getType().isOfType(lvalue.getType())) {
107
108         /* This gets tricky. We need to allow something like
109          * s = (short) (int) ((double) s / 0.1);
110          */

111             expr = (Operator) expr.getSubExpressions()[0];
112         while (expr instanceof ConvertOperator
113            && expr.getSubExpressions()[0] instanceof Operator)
114         expr = (Operator) expr.getSubExpressions()[0];
115         }
116         if (expr instanceof BinaryOperator) {
117             opIndex = expr.getOperatorIndex();
118             if (opIndex < expr.ADD_OP || opIndex >= expr.ASSIGN_OP)
119         return false;
120
121         if (!(expr.getSubExpressions()[0] instanceof Operator))
122         return false;
123
124         Operator loadExpr = (Operator) expr.getSubExpressions()[0];
125         while (loadExpr instanceof ConvertOperator
126            && loadExpr.getSubExpressions()[0] instanceof Operator)
127         loadExpr = (Operator) loadExpr.getSubExpressions()[0];
128
129         if (!store.lvalueMatches((Operator) loadExpr)
130         || !(loadExpr.isFreeOperator(lvalueCount)))
131                 return false;
132
133         if (lvalue instanceof LocalStoreOperator)
134         ((LocalLoadOperator)loadExpr).getLocalInfo().combineWith
135             (((LocalStoreOperator)lvalue).getLocalInfo());
136         
137             rightHandSide = expr.getSubExpressions()[1];
138         } else {
139         /* For String += the situation is more complex.
140          * what is marked as load(stack) * rightHandSide above is
141          * really (after simplification):
142          *
143          * PUSH ((load(stack) + right) + Hand) + Side
144          */

145             Expression simple = expr.simplifyString();
146             rightHandSide = simple;
147             /* Now search for the leftmost operand ... */
148             Operator lastExpr = null;
149         Operator parent = null;
150             while (simple instanceof StringAddOperator) {
151         parent = lastExpr;
152                 lastExpr = (Operator) simple;
153                 simple = lastExpr.getSubExpressions()[0];
154             }
155
156             /* ... check it ... */
157             if (lastExpr == null
158         || !(simple instanceof Operator)
159                 || !store.lvalueMatches((Operator) simple)
160         || !(((Operator) simple).isFreeOperator(lvalueCount)))
161                 return false;
162
163         if (lvalue instanceof LocalStoreOperator)
164         ((LocalLoadOperator)simple).getLocalInfo().combineWith
165             (((LocalStoreOperator)lvalue).getLocalInfo());
166         
167             /* ... and remove it. */
168             if (parent != null) {
169         parent.setSubExpressions(0, lastExpr.getSubExpressions()[1]);
170             } else {
171                 rightHandSide = lastExpr.getSubExpressions()[1];
172         }
173
174             opIndex = Operator.ADD_OP;
175         }
176
177     if (dup != null)
178         dup.removeBlock();
179         ib.setInstruction(rightHandSide);
180         
181     lvalue.setType(rvalueType);
182         store.makeOpAssign(store.OPASSIGN_OP + opIndex);
183
184         if (isAssignOp)
185             store.makeNonVoid();
186         last.replace(opBlock.subBlocks[1]);
187         return true;
188     }
189
190     public static boolean createAssignExpression(InstructionContainer ic,
191                                           StructuredBlock last) {
192         /* Situation:
193          * sequBlock:
194          * dup_X(lvalue_count)
195          * store(POP) = POP
196          */

197         SequentialBlock sequBlock = (SequentialBlock) last.outer;
198         StoreInstruction store = (StoreInstruction) ic.getInstruction();
199
200         if (sequBlock.subBlocks[0] instanceof SpecialBlock
201         && store.isFreeOperator()) {
202
203         Expression lvalue = store.getSubExpressions()[0];
204             SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0];
205             if (dup.type != SpecialBlock.DUP
206                 || dup.depth != lvalue.getFreeOperandCount()
207                 || dup.count != lvalue.getType().stackSize())
208                 return false;
209             
210             dup.removeBlock();
211             store.makeNonVoid();
212             return true;
213         }
214         return false;
215     }
216 }
217
Popular Tags