KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > toolkits > base > AST > transformations > PushLabeledBlockIn


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2005 Nomair A. Naeem
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.dava.toolkits.base.AST.transformations;
21
22 import soot.*;
23 import java.util.*;
24 import soot.jimple.*;
25 import soot.dava.internal.SET.*;
26 import soot.dava.internal.AST.*;
27 import soot.dava.internal.asg.*;
28 import soot.dava.internal.javaRep.*;
29 import soot.dava.toolkits.base.AST.analysis.*;
30
31
32 /*
33   Nomair A. Naeem 18-FEB-2005
34
35   The class is responsible to do the following transformation on the AST
36
37         label_1:{
38               ___________________ ____________________
39              | | | |
40              | no break label_1 | | no break label_1 |
41              |___________________| |____________________|
42              | | | |
43              |ASTLabeledNode | | label_1: |
44              |while(cond){ | ----> | while(cond){ |
45              | use of label_1 | | use of label_1 |
46              | | | } |
47              |} | |____________________|
48              |___________________|
49              | |
50              | Nothing here |
51              |___________________|
52          }//end of label_1
53
54
55 The important thing to note in this case is that the node which uses breaks
56 extends ASTLabeledNode so that we can move the label down. Obviously there shouldnt be
57 an already existing label on this node. Once the node containing the break is detected
58 there should be no node following this in the body of the labeled block. This is so because
59 if the break is moved down that code will get executed and thats a wrong transformation.
60
61
62         label_1:{
63               ___________________ _____________________
64              | | | |
65              |label_2 | | label_2: |
66              |while(cond){ | ----> | while(cond){ |
67              | use of label_1 | | label_1 replaced|
68              | | | by label_2 |
69              |} | |___}_________________|
70              |___________________|
71              | |
72              | Nothing here |
73              |___________________|
74          }//end of label_1
75
76 If the previous pattern did not match because the node on which we wanted to push the label
77 inwards already had a label we can try to use the label on the inner node. This is only possible
78 if there is only a single node in the labeledBlocks subBody, to make sure that we break and jump
79 to exactly the same point as we were jumping before.
80
81
82   TO MAKE CODE EFFECIENT BLOCK THE ANALYSIS TO GOING INTO STATEMENTS
83   this is done by overriding the caseASTStatementSequenceNode
84 */

85
86 public class PushLabeledBlockIn extends DepthFirstAdapter{
87
88     public PushLabeledBlockIn(){
89     }
90     public PushLabeledBlockIn(boolean verbose){
91     super(verbose);
92     }
93
94     public void caseASTStatementSequenceNode(ASTStatementSequenceNode node){
95     }
96
97
98
99     public void outASTLabeledBlockNode(ASTLabeledBlockNode node){
100     String JavaDoc label = node.get_Label().toString();
101     List subBodies = (List)node.get_SubBodies();
102     if(subBodies.size()!=1){
103         return;
104     }
105     List subBody = (List)subBodies.get(0);
106     int nodeNumber=checkForBreak(subBody,label);
107     if(nodeNumber>-1){
108         //found some break for this label
109
//retrieve element at this nodeNumber
110
if(subBody.size()<nodeNumber){
111         //something is wrong
112
throw new RuntimeException JavaDoc("Please submit this benchmark as a bug");
113         }
114
115         //check that this is the last node in the list
116
//since otherwise we cant change anything
117
if(nodeNumber+1!=subBody.size()){
118         //it is not the last
119
return;
120         }
121
122         //safe to access the list
123
ASTNode temp = (ASTNode)subBody.get(nodeNumber);
124         if(!(temp instanceof ASTLabeledNode)){
125         //does not extend labeledNode hence cannot give it a label
126
return;
127         }
128         
129         ASTLabeledNode tempNode = (ASTLabeledNode)temp;
130         //shouldnt already have a label
131
String JavaDoc innerLabel = tempNode.get_Label().toString();
132         if (innerLabel!=null){
133         //already has a label
134
//we could still do something if this is the ONLY node in the body
135

136         if(subBody.size()==1){
137             //there is only one node
138
/*
139               The situation is that there is a labeled block whic has only one
140               node that also has a label on it.
141               
142               There is some statement deep down which breaks the outer label
143               
144               No reason why it cant break the inner label since there is nothing after that!!!
145               
146               label has the outer label whose break we found
147               innerLabel has the label of the inner node which contains the break
148             
149               replace all occurances of break of outer label
150               with that of break of inner label
151             */

152             
153             //we know that the breaks occur within the subtree rooted at temp
154
boolean done=replaceBreakLabels(temp,label,innerLabel);
155             if(done){
156             //System.out.println("REMOVED LABELED BLOCK-replaced label names");
157
node.set_Label(new SETNodeLabel());
158             G.v().ASTTransformations_modified = true;
159             }
160         }
161
162         return;
163         }
164         else{
165         //doesnt have a label
166
//System.out.println("PUSHED LABEL DOWN");
167
SETNodeLabel newLabel = new SETNodeLabel();
168         newLabel.set_Name(label);
169         tempNode.set_Label(newLabel);
170         node.set_Label(new SETNodeLabel());
171         G.v().ASTTransformations_modified = true;
172         }
173
174     }
175     }
176     private boolean replaceBreakLabels(ASTNode node,String JavaDoc toReplace, String JavaDoc replaceWith){
177     boolean toReturn=false;
178     List subBodies=node.get_SubBodies();
179     Iterator subIt = subBodies.iterator();
180     while(subIt.hasNext()){
181         List subBody=null;
182         if(node instanceof ASTTryNode){
183         ASTTryNode.container subBodyContainer = (ASTTryNode.container) subIt.next();
184         subBody=(List)subBodyContainer.o;
185         }
186         else
187         subBody=(List)subIt.next();
188
189         Iterator it = subBody.iterator();
190         while(it.hasNext()){
191         ASTNode temp = (ASTNode)it.next();
192         //check if this is ASTStatementSequenceNode
193
if(temp instanceof ASTStatementSequenceNode){
194             ASTStatementSequenceNode stmtSeq = (ASTStatementSequenceNode)temp;
195             List statements = stmtSeq.getStatements();
196             Iterator stmtIt = statements.iterator();
197             while(stmtIt.hasNext()){
198             AugmentedStmt as = (AugmentedStmt)stmtIt.next();
199             Stmt s = as.get_Stmt();
200             String JavaDoc labelBroken = isAbrupt(s);
201             if(labelBroken != null){//stmt breaks some label
202
if(labelBroken.compareTo(toReplace)==0){
203                 //we have found a break breaking this label
204
//replace the label with "replaceWith"
205
replaceLabel(s,replaceWith);
206                 toReturn=true;
207                 }
208             }
209             }
210         }//if it was a StmtSeq node
211
else{
212             //otherwise recursion
213
boolean returnVal=replaceBreakLabels(temp,toReplace,replaceWith);
214             if(returnVal)
215             toReturn=true;
216         }
217         }//end of while
218
}
219     return toReturn;
220     }
221
222
223
224     private int checkForBreak(List ASTNodeBody,String JavaDoc outerLabel){
225     Iterator it = ASTNodeBody.iterator();
226     int nodeNumber=0;
227     while(it.hasNext()){
228         ASTNode temp = (ASTNode)it.next();
229         //check if this is ASTStatementSequenceNode
230
if(temp instanceof ASTStatementSequenceNode){
231         ASTStatementSequenceNode stmtSeq = (ASTStatementSequenceNode)temp;
232         List statements = stmtSeq.getStatements();
233         Iterator stmtIt = statements.iterator();
234         while(stmtIt.hasNext()){
235             AugmentedStmt as = (AugmentedStmt)stmtIt.next();
236             Stmt s = as.get_Stmt();
237             String JavaDoc labelBroken = breaksLabel(s);
238             if(labelBroken != null && outerLabel!=null){//stmt breaks some label
239
if(labelBroken.compareTo(outerLabel)==0){
240                 //we have found a break breaking this label
241
return nodeNumber;
242             }
243             }
244         }
245         }//if it was a StmtSeq node
246
else{
247         //otherwise recursion
248
//getSubBodies
249
List subBodies=(List)temp.get_SubBodies();
250         Iterator subIt = subBodies.iterator();
251         while(subIt.hasNext()){
252
253
254             if(temp instanceof ASTTryNode){
255             ASTTryNode.container subBody = (ASTTryNode.container) subIt.next();
256             if(checkForBreak((List)subBody.o,outerLabel)> (-1) ){
257                 //if this is true there was a break found
258
return nodeNumber;
259             }
260             }
261             else{
262             if(checkForBreak((List)subIt.next(),outerLabel)> (-1) ){
263                 //if this is true there was a break found
264
return nodeNumber;
265             }
266             }
267         }
268         }
269         nodeNumber++;
270     }//end of while
271

272     return -1;
273     }
274
275
276     /*
277       If the stmt is a break stmt then this method
278       returns the labels name
279       else returns null
280     */

281     private String JavaDoc breaksLabel(Stmt stmt){
282     if(!(stmt instanceof DAbruptStmt)){
283         //this is not a break stmt
284
return null;
285     }
286     DAbruptStmt abStmt = (DAbruptStmt)stmt;
287     if(!abStmt.is_Break()){
288         //not a break stmt
289
return null;
290     }
291     SETNodeLabel label = abStmt.getLabel();
292     return label.toString();
293     }
294
295
296     /*
297       If the stmt is a abruptstmt either break or continue
298       returns the labels name
299       else returns null
300     */

301     private String JavaDoc isAbrupt(Stmt stmt){
302     if(!(stmt instanceof DAbruptStmt)){
303         //this is not a break stmt
304
return null;
305     }
306     DAbruptStmt abStmt = (DAbruptStmt)stmt;
307     if(abStmt.is_Break() || abStmt.is_Continue()){
308         SETNodeLabel label = abStmt.getLabel();
309         return label.toString();
310     }
311     else
312         return null;
313     }
314
315
316     private void replaceLabel(Stmt s, String JavaDoc replaceWith){
317     //we know its an AbruptStmt
318
DAbruptStmt abStmt = (DAbruptStmt)s;
319     SETNodeLabel label = abStmt.getLabel();
320     label.set_Name(replaceWith);
321     }
322 }
323
324
325
326
327
328
329
330
Popular Tags