KickJava   Java API By Example, From Geeks To Geeks.

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


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 JimpleConstructorFolder extends BodyTransformer
44 {
45     //public JimpleConstructorFolder( Singletons.Global g ) {}
46
//public static JimpleConstructorFolder v() { return G.v().JimpleConstructorFolder(); }
47

48     /** This method pushes all newExpr down to be the stmt directly before every
49      * invoke of the init */

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