KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > base > PartialConstructorFolder


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 /*
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.toolkits.base;
32 import soot.options.*;
33
34 import soot.*;
35 import soot.toolkits.scalar.*;
36 import soot.jimple.*;
37 import soot.toolkits.graph.*;
38 import soot.grimp.*;
39 import soot.util.*;
40 import java.util.*;
41 import soot.tagkit.*;
42
43 public class PartialConstructorFolder extends BodyTransformer
44 {
45     //public JimpleConstructorFolder( Singletons.Global g ) {}
46
//public static JimpleConstructorFolder v() { return G.v().JimpleConstructorFolder(); }
47

48     private List types;
49
50     public void setTypes(List t){
51         types = t;
52     }
53
54     public List getTypes(){
55         return types;
56     }
57     
58     /** This method pushes all newExpr down to be the stmt directly before every
59      * invoke of the init only if they are in the types list*/

60     
61     public void internalTransform(Body b, String JavaDoc phaseName, Map options)
62     {
63         JimpleBody body = (JimpleBody)b;
64
65         if(Options.v().verbose())
66             G.v().out.println("[" + body.getMethod().getName() +
67                 "] Folding Jimple constructors...");
68
69         Chain units = body.getUnits();
70         List stmtList = new ArrayList();
71         stmtList.addAll(units);
72
73         Iterator it = stmtList.iterator();
74         Iterator nextStmtIt = stmtList.iterator();
75         // start ahead one
76
nextStmtIt.next();
77         
78         ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body);
79         
80         LocalDefs localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph));
81         LocalUses localUses = new SimpleLocalUses(graph, localDefs);
82
83         /* fold in NewExpr's with specialinvoke's */
84         while (it.hasNext())
85         {
86             Stmt s = (Stmt)it.next();
87             
88             
89             if (!(s instanceof AssignStmt))
90                 continue;
91             
92             /* this should be generalized to ArrayRefs */
93             // only deal with stmts that are an local = newExpr
94
Value lhs = ((AssignStmt)s).getLeftOp();
95             if (!(lhs instanceof Local))
96                 continue;
97             
98             Value rhs = ((AssignStmt)s).getRightOp();
99             if (!(rhs instanceof NewExpr))
100                 continue;
101
102             
103             //check if very next statement is invoke -->
104
//this indicates there is no control flow between
105
//new and invoke and should do nothing
106
if (nextStmtIt.hasNext()){
107                 Stmt next = (Stmt)nextStmtIt.next();
108                 if (next instanceof InvokeStmt){
109                     InvokeStmt invoke = (InvokeStmt)next;
110                 
111                     if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) {
112                         SpecialInvokeExpr invokeExpr = (SpecialInvokeExpr)invoke.getInvokeExpr();
113                         if (invokeExpr.getBase() == lhs){
114                             break;
115                         }
116                     }
117                 }
118             }
119             
120
121             // check if new is in the types list - only process these
122
if (!types.contains(((NewExpr)rhs).getType())) continue;
123             
124             List lu = localUses.getUsesOf((DefinitionStmt)s);
125             Iterator luIter = lu.iterator();
126             boolean MadeNewInvokeExpr = false;
127           
128             while (luIter.hasNext())
129             {
130                 Unit use = ((UnitValueBoxPair)(luIter.next())).unit;
131                 if (!(use instanceof InvokeStmt))
132                     continue;
133                 InvokeStmt is = (InvokeStmt)use;
134                 if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr) ||
135                   lhs != ((SpecialInvokeExpr)is.getInvokeExpr()).getBase())
136                     continue;
137               
138              //make a new one here
139
AssignStmt constructStmt = Jimple.v().newAssignStmt
140                 (((DefinitionStmt)s).getLeftOp(), ((DefinitionStmt)s).getRightOp());
141               constructStmt.setRightOp
142                 (Jimple.v().newNewExpr
143                  (((NewExpr)rhs).getBaseType()));
144               MadeNewInvokeExpr = true;
145               
146               // redirect jumps
147
use.redirectJumpsToThisTo(constructStmt);
148               // insert new one here
149
units.insertBefore(constructStmt, use);
150               
151               constructStmt.addTag((SourceLnPosTag)s.getTag("SourceLnPosTag"));
152             }
153           if (MadeNewInvokeExpr)
154             {
155               units.remove(s);
156             }
157         }
158     }
159 }
160
Popular Tags