KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > grimp > toolkits > base > ConstructorFolder


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.grimp.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
42 public class ConstructorFolder extends BodyTransformer
43 {
44     public ConstructorFolder( Singletons.Global g ) {}
45     public static ConstructorFolder v() { return G.v().soot_grimp_toolkits_base_ConstructorFolder(); }
46
47     /** This method change all new Obj/<init>(args) pairs to new Obj(args) idioms. */
48     protected void internalTransform(Body b, String JavaDoc phaseName, Map options)
49     {
50         GrimpBody body = (GrimpBody)b;
51
52         if(Options.v().verbose())
53             G.v().out.println("[" + body.getMethod().getName() +
54                 "] Folding constructors...");
55
56       Chain units = body.getUnits();
57       List stmtList = new ArrayList();
58       stmtList.addAll(units);
59
60       Iterator it = stmtList.iterator();
61
62       ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body);
63               
64         
65       LocalDefs localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph));
66       LocalUses localUses = new SimpleLocalUses(graph, localDefs);
67
68       /* fold in NewExpr's with specialinvoke's */
69       while (it.hasNext())
70         {
71           Stmt s = (Stmt)it.next();
72             
73           if (!(s instanceof AssignStmt))
74             continue;
75             
76           /* this should be generalized to ArrayRefs */
77           Value lhs = ((AssignStmt)s).getLeftOp();
78           if (!(lhs instanceof Local))
79             continue;
80             
81           Value rhs = ((AssignStmt)s).getRightOp();
82           if (!(rhs instanceof NewExpr))
83             continue;
84
85           /* TO BE IMPLEMENTED LATER: move any copy of the object reference
86              for lhs down beyond the NewInvokeExpr, with the rationale
87              being that you can't modify the object before the constructor
88              call in any case.
89
90              Also, do note that any new's (object creation) without
91              corresponding constructors must be dead. */

92            
93           List lu = localUses.getUsesOf((DefinitionStmt)s);
94           Iterator luIter = lu.iterator();
95           boolean MadeNewInvokeExpr = false;
96            
97           while (luIter.hasNext())
98             {
99               Unit use = ((UnitValueBoxPair)(luIter.next())).unit;
100               if (!(use instanceof InvokeStmt))
101                 continue;
102               InvokeStmt is = (InvokeStmt)use;
103               if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr) ||
104                   lhs != ((SpecialInvokeExpr)is.getInvokeExpr()).getBase())
105                 continue;
106               
107               SpecialInvokeExpr oldInvoke =
108                 ((SpecialInvokeExpr)is.getInvokeExpr());
109               LinkedList invokeArgs = new LinkedList();
110               for (int i = 0; i < oldInvoke.getArgCount(); i++)
111                 invokeArgs.add(oldInvoke.getArg(i));
112               
113               AssignStmt constructStmt = Grimp.v().newAssignStmt
114                 ((AssignStmt)s);
115               constructStmt.setRightOp
116                 (Grimp.v().newNewInvokeExpr
117                  (((NewExpr)rhs).getBaseType(), oldInvoke.getMethodRef(), invokeArgs));
118               MadeNewInvokeExpr = true;
119               
120               use.redirectJumpsToThisTo(constructStmt);
121               units.insertBefore(constructStmt, use);
122               units.remove(use);
123             }
124           if (MadeNewInvokeExpr)
125             {
126               units.remove(s);
127             }
128         }
129     }
130 }
131
Popular Tags