KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > grimp > GrimpBody


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 package soot.grimp;
28 import soot.options.*;
29
30 import soot.*;
31 import soot.jimple.*;
32 import soot.jimple.internal.*;
33 import soot.jimple.toolkits.base.*;
34 import soot.grimp.toolkits.base.*;
35 import soot.toolkits.scalar.*;
36 import soot.util.*;
37 import java.util.*;
38 import soot.baf.*;
39 import java.io.*;
40
41 /** Implementation of the Body class for the Grimp IR. */
42 public class GrimpBody extends StmtBody
43 {
44     /**
45         Construct an empty GrimpBody
46      **/

47      
48     GrimpBody(SootMethod m)
49     {
50         super(m);
51     }
52
53     public Object JavaDoc clone()
54     {
55         Body b = Grimp.v().newBody(getMethod());
56         b.importBodyContentsFrom(this);
57         return b;
58     }
59
60     /**
61         Constructs a GrimpBody from the given Body.
62      */

63
64     GrimpBody(Body body)
65     {
66         super(body.getMethod());
67
68         if(Options.v().verbose())
69             G.v().out.println("[" + getMethod().getName() + "] Constructing GrimpBody...");
70         
71         JimpleBody jBody = null;
72
73         if (body instanceof JimpleBody)
74             jBody = (JimpleBody)body;
75         else
76             throw new RuntimeException JavaDoc("Can only construct GrimpBody's from JimpleBody's (for now)");
77
78         Iterator it = jBody.getLocals().iterator();
79         while (it.hasNext())
80             getLocals().add(((Local)(it.next())));
81             // getLocals().add(((Local)(it.next())).clone());
82

83         it = jBody.getUnits().iterator();
84
85         final HashMap oldToNew = new HashMap(getUnits().size() * 2 + 1, 0.7f);
86         LinkedList updates = new LinkedList();
87
88         /* we should Grimpify the Stmt's here... */
89         while (it.hasNext())
90         {
91             Stmt oldStmt = (Stmt)(it.next());
92             final StmtBox newStmtBox = (StmtBox) Grimp.v().newStmtBox(null);
93             final StmtBox updateStmtBox = (StmtBox) Grimp.v().newStmtBox(null);
94
95             /* we can't have a general StmtSwapper on Grimp.v() */
96             /* because we need to collect a list of updates */
97             oldStmt.apply(new AbstractStmtSwitch()
98             {
99                 public void caseAssignStmt(AssignStmt s)
100                 {
101                     newStmtBox.setUnit(Grimp.v().newAssignStmt(s));
102                 }
103                 public void caseIdentityStmt(IdentityStmt s)
104                   {
105                     newStmtBox.setUnit(Grimp.v().newIdentityStmt(s));
106                 }
107                 public void caseBreakpointStmt(BreakpointStmt s)
108                 {
109                     newStmtBox.setUnit(Grimp.v().newBreakpointStmt(s));
110                 }
111                 public void caseInvokeStmt(InvokeStmt s)
112                 {
113                     newStmtBox.setUnit(Grimp.v().newInvokeStmt(s));
114                 }
115                 public void defaultCase(Stmt s)
116                   {
117                     throw new RuntimeException JavaDoc("invalid jimple stmt: "+s);
118                 }
119                 public void caseEnterMonitorStmt(EnterMonitorStmt s)
120                 {
121                     newStmtBox.setUnit(Grimp.v().newEnterMonitorStmt(s));
122                 }
123                 public void caseExitMonitorStmt(ExitMonitorStmt s)
124                 {
125                     newStmtBox.setUnit(Grimp.v().newExitMonitorStmt(s));
126                 }
127                 public void caseGotoStmt(GotoStmt s)
128                 {
129                     newStmtBox.setUnit(Grimp.v().newGotoStmt(s));
130                     updateStmtBox.setUnit(s);
131                 }
132                 public void caseIfStmt(IfStmt s)
133                 {
134                     newStmtBox.setUnit(Grimp.v().newIfStmt(s));
135                     updateStmtBox.setUnit(s);
136                 }
137                 public void caseLookupSwitchStmt(LookupSwitchStmt s)
138                 {
139                     newStmtBox.setUnit(Grimp.v().newLookupSwitchStmt(s));
140                     updateStmtBox.setUnit(s);
141                 }
142                 public void caseNopStmt(NopStmt s)
143                 {
144                     newStmtBox.setUnit(Grimp.v().newNopStmt(s));
145                 }
146
147                 public void caseReturnStmt(ReturnStmt s)
148                 {
149                     newStmtBox.setUnit(Grimp.v().newReturnStmt(s));
150                 }
151                 public void caseReturnVoidStmt(ReturnVoidStmt s)
152                 {
153                     newStmtBox.setUnit(Grimp.v().newReturnVoidStmt(s));
154                 }
155                 public void caseTableSwitchStmt(TableSwitchStmt s)
156                 {
157                     newStmtBox.setUnit(Grimp.v().newTableSwitchStmt(s));
158                     updateStmtBox.setUnit(s);
159                 }
160                 public void caseThrowStmt(ThrowStmt s)
161                 {
162                     newStmtBox.setUnit(Grimp.v().newThrowStmt(s));
163                 }
164             });
165
166             /* map old Expr's to new Expr's. */
167             Stmt newStmt = (Stmt)(newStmtBox.getUnit());
168             Iterator useBoxesIt;
169             useBoxesIt = newStmt.getUseBoxes().iterator();
170             while(useBoxesIt.hasNext())
171                 {
172                     ValueBox b = (ValueBox) (useBoxesIt.next());
173                     b.setValue(Grimp.v().newExpr(b.getValue()));
174                 }
175             useBoxesIt = newStmt.getDefBoxes().iterator();
176             while(useBoxesIt.hasNext())
177                 {
178                     ValueBox b = (ValueBox) (useBoxesIt.next());
179                     b.setValue(Grimp.v().newExpr(b.getValue()));
180                 }
181
182             getUnits().add(newStmt);
183             oldToNew.put(oldStmt, newStmt);
184             if (updateStmtBox.getUnit() != null)
185                 updates.add(updateStmtBox.getUnit());
186         }
187
188         /* fixup stmt's which have had moved targets */
189         it = updates.iterator();
190         while (it.hasNext())
191         {
192             Stmt stmt = (Stmt)(it.next());
193
194             stmt.apply(new AbstractStmtSwitch()
195             {
196                 public void defaultCase(Stmt s)
197                   {
198                     throw new RuntimeException JavaDoc("Internal error: "+s);
199                 }
200                 public void caseGotoStmt(GotoStmt s)
201                 {
202                     GotoStmt newStmt = (GotoStmt)(oldToNew.get(s));
203                     newStmt.setTarget((Stmt)oldToNew.get(newStmt.getTarget()));
204                 }
205                 public void caseIfStmt(IfStmt s)
206                 {
207                     IfStmt newStmt = (IfStmt)(oldToNew.get(s));
208                     newStmt.setTarget((Stmt)oldToNew.get(newStmt.getTarget()));
209                 }
210                 public void caseLookupSwitchStmt(LookupSwitchStmt s)
211                 {
212                     LookupSwitchStmt newStmt =
213                         (LookupSwitchStmt)(oldToNew.get(s));
214                     newStmt.setDefaultTarget
215                         ((Unit)(oldToNew.get(newStmt.getDefaultTarget())));
216                     Unit[] newTargList = new Unit[newStmt.getTargetCount()];
217                     for (int i = 0; i < newStmt.getTargetCount(); i++)
218                         newTargList[i] = (Unit)(oldToNew.get
219                                                 (newStmt.getTarget(i)));
220                     newStmt.setTargets(newTargList);
221                 }
222                 public void caseTableSwitchStmt(TableSwitchStmt s)
223                 {
224                     TableSwitchStmt newStmt =
225                         (TableSwitchStmt)(oldToNew.get(s));
226                     newStmt.setDefaultTarget
227                         ((Unit)(oldToNew.get(newStmt.getDefaultTarget())));
228                     int tc = newStmt.getHighIndex() - newStmt.getLowIndex()+1;
229                     LinkedList newTargList = new LinkedList();
230                     for (int i = 0; i < tc; i++)
231                         newTargList.add(oldToNew.get
232                                         (newStmt.getTarget(i)));
233                     newStmt.setTargets(newTargList);
234                 }
235             });
236         }
237
238         it = jBody.getTraps().iterator();
239         while (it.hasNext())
240         {
241             Trap oldTrap = (Trap)(it.next());
242             getTraps().add(Grimp.v().newTrap
243                            (oldTrap.getException(),
244                             (Unit)(oldToNew.get(oldTrap.getBeginUnit())),
245                             (Unit)(oldToNew.get(oldTrap.getEndUnit())),
246                             (Unit)(oldToNew.get(oldTrap.getHandlerUnit()))));
247         }
248
249         PackManager.v().getPack( "gb" ).apply( this );
250     }
251 }
252
Popular Tags