KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > ast > TryFinallyStmt


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base.ast;
26
27 import org.aspectj.compiler.base.*;
28
29 import org.aspectj.compiler.base.JavaCompiler;
30 import org.aspectj.compiler.base.CodeWriter;
31
32 import org.aspectj.compiler.base.bcg.CodeBuilder;
33 import org.aspectj.compiler.base.bcg.Label;
34
35 import java.util.Iterator JavaDoc;
36
37 /**
38  * @grammar try {body} finally {finally}
39  * @child Stmt body
40  * @child Stmt finally
41  */

42 public class TryFinallyStmt extends TryStmt implements WindingStmt {
43     
44     public void checkSpec() {
45         super.checkSpec();
46         if (_finally == null) {
47             showError("'try' without 'catch' or 'finally'");
48         }
49         
50         if (!includesDesugaredCatch()) {
51             body.requireBlockStmt();
52         }
53         _finally.requireBlockStmt();
54     }
55     
56     private boolean includesDesugaredCatch() {
57         return (body instanceof TryCatchStmt) && body.isSynthetic();
58     }
59
60     public void unparse(CodeWriter writer) {
61         if (includesDesugaredCatch()) {
62             TryCatchStmt tcb = (TryCatchStmt) body;
63             writer.writeKeyword("try");
64             writer.optionalSpace();
65             writer.write(tcb.getBody());
66             writer.writeChildren(tcb.getCatches());
67             writer.writeKeyword("finally");
68             writer.optionalSpace();
69             writer.write(_finally);
70         } else {
71             writer.writeKeyword("try");
72             writer.optionalSpace();
73             writer.write(body);
74             writer.writeKeyword("finally");
75             writer.optionalSpace();
76             writer.write(_finally);
77         }
78     }
79
80     // ------------------------------
81
// INTRO from ASTFixerPass
82

83     public ASTObject postFixAST(final ASTFixerPass fixer) {
84         if (! isOptional()) return super.postFixAST(fixer);
85         setIsOptional(false);
86         return this;
87     }
88
89     // ------------------------------
90
// INTRO from FlowCheckerPass
91

92     public void walkFlow(FlowCheckerPass w) {
93         FlowCheckerPass.Vars beforeV = w.getVars();
94         FlowCheckerPass.ESet beforeExns = w.popExns();
95         w.enterContext(this);
96         w.process(getBody());
97         w.leaveContext();
98         boolean bodyLive = w.isLive();
99         FlowCheckerPass.ESet bodyExns = w.popExns();
100
101         FlowCheckerPass.Vars cvExit = w.getVars();
102         FlowCheckerPass.Vars fv =
103             FlowCheckerPass.Vars.makeSets(beforeV.getDa(),
104                                           cvExit.getDua());
105         w.setLive(true);
106         w.setVars(fv);
107         w.process(getFinally());
108
109         if (w.isLive()) {
110             w.releasePendingTransfers(this);
111             w.setExns(bodyExns.union(w.getExns()).union(beforeExns));
112         } else {
113             if (! getOptions().strict) {
114                 w.setExns(bodyExns.union(w.getExns()).union(beforeExns));
115             } else {
116                 w.setExns(w.getExns().union(beforeExns));
117             }
118         }
119         boolean liveSoFar = bodyLive & w.isLive();
120         w.setVars(FlowCheckerPass.Vars.makeSets(cvExit.getDa().union(w.getVars().getDa()),
121                                                 w.getVars().getDua()));
122         w.setLive(liveSoFar);
123     }
124
125     // ------------------------------
126
// Intro: ByteCodeCleanupPass
127

128     public void walkCleanup(ByteCodeCleanupPass w) {
129         w.enterContext(this);
130         setBody((Stmt) w.process(getBody()));
131         w.leaveContext();
132         boolean bodyLive = w.isLive();
133         w.setLive(true);
134         setFinally((Stmt) w.process(getFinally()));
135         boolean liveSoFar = bodyLive & w.isLive();
136         w.setLive(liveSoFar);
137     }
138
139     public ASTObject postCleanup(ByteCodeCleanupPass walker) {
140         if (getBody() instanceof EmptyStmt) {
141             return getFinally();
142         } else {
143             return this;
144         }
145     }
146
147     // ------------------------------
148
// bcg
149

150     protected void cgStmt(CodeBuilder cb) {
151         Label startBody = cb.genAnchor();
152         Label endBody = cb.genAnchor();
153         Label startExn = cb.genAnchor();
154         Label startFinally = cb.genAnchor();
155         Label end = cb.genLabel();
156
157         cb.emitLabel(startBody);
158         cb.enterWindingContext(this, startFinally);
159         getBody().cgTop(cb);
160         cb.leaveContext();
161         cb.emitLabel(endBody);
162         if (body.completesNormally()) {
163             cb.emitJSR(startFinally);
164             if (getFinally().completesNormally()) {
165                 cb.emitJump(end);
166             }
167         }
168
169         cb.emitLabel(startExn); // where we go if an exn happens
170
cb.pushStack(1); // there's an exn on the stack
171
cb.emitASTORE(retValLoc); // so store it
172
cb.emitJSR(startFinally); // make the jump
173
cb.emitALOAD(retValLoc); // reload the exn
174
cb.emitATHROW(); // rethrow
175

176         cb.emitLabel(startFinally); // always target of JSR instruction
177
cb.pushStack(1); // stack holds JSR return address
178
cb.emitASTORE(retPtrLoc); // store it.
179
getFinally().cgTop(cb); // execute the body
180
if (getFinally().completesNormally()) {
181             cb.emitRET(retPtrLoc); // return from JSR
182
}
183         cb.addHandler(startBody, endBody, startExn, null); // add default handler
184

185         cb.emitLabel(end);
186     }
187
188     // ------------------------------
189
// Intro: FrameLocPass
190

191     // We need to allocate space for the entry to a finally block,
192
// which could be entered in two different ways.
193

194     // If it is entered abruptly, through an exception being thrown,
195
// we need space to squirrel away the exception, do the JSR, store
196
// the RET pointer, and go on.
197

198     // If it is entered normally, then it is possible that it was
199
// entered through "return". Which means that we need to
200
// "allocate" space for the return value. The return code will
201
// actually squirrel away in this point, but we need to allocate
202
// the space now. And on top of _that_, we need to save space to
203
// store the RET pointer.
204

205     // For now, we'll save _two_ spaces for the return value. Really,
206
// we should be allocating (max 1 retvalSlotSize).
207

208     // needless to say, this is weird enough that we're going to walk
209
// it ourselves.
210

211     private int retValLoc; // same as exn loc
212
private int retPtrLoc;
213
214     public int getRetValLoc() { return retValLoc; }
215
216     public void walkFrameLoc(FrameLocPass walker) {
217         boolean inTryFinally = walker.inTryFinally;
218         walker.inTryFinally = true;
219         int start = walker.getfs();
220         walker.process(getBody());
221         //if (walker.getfs() != start) throw new RuntimeException("inv. broken");
222
retValLoc = walker.allocate(2); // Math.max(1, retvalSlotSize)
223
retPtrLoc = walker.allocate(1);
224         walker.process(getFinally());
225         walker.inTryFinally = inTryFinally;
226         walker.setfs(start);
227     }
228     
229     //BEGIN: Generated from @child and @property
230
protected Stmt body;
231     public Stmt getBody() { return body; }
232     public void setBody(Stmt _body) {
233         if (_body != null) _body.setParent(this);
234         body = _body;
235     }
236     
237     protected Stmt _finally;
238     public Stmt getFinally() { return _finally; }
239     public void setFinally(Stmt __finally) {
240         if (__finally != null) __finally.setParent(this);
241         _finally = __finally;
242     }
243     
244     public TryFinallyStmt(SourceLocation location, Stmt _body, Stmt __finally) {
245         super(location);
246         setBody(_body);
247         setFinally(__finally);
248     }
249     protected TryFinallyStmt(SourceLocation source) {
250         super(source);
251     }
252     
253     public ASTObject copyWalk(CopyWalker walker) {
254         TryFinallyStmt ret = new TryFinallyStmt(getSourceLocation());
255         ret.preCopy(walker, this);
256         if (body != null) ret.setBody( (Stmt)walker.process(body) );
257         if (_finally != null) ret.setFinally( (Stmt)walker.process(_finally) );
258         return ret;
259     }
260     
261     public ASTObject getChildAt(int childIndex) {
262         switch(childIndex) {
263         case 0: return body;
264         case 1: return _finally;
265         default: return super.getChildAt(childIndex);
266         }
267     }
268      public String JavaDoc getChildNameAt(int childIndex) {
269         switch(childIndex) {
270         case 0: return "body";
271         case 1: return "finally";
272         default: return super.getChildNameAt(childIndex);
273         }
274     }
275      public void setChildAt(int childIndex, ASTObject child) {
276         switch(childIndex) {
277         case 0: setBody((Stmt)child); return;
278         case 1: setFinally((Stmt)child); return;
279         default: super.setChildAt(childIndex, child); return;
280         }
281     }
282      public int getChildCount() {
283         return 2;
284     }
285     
286     public String JavaDoc getDefaultDisplayName() {
287         return "TryFinallyStmt()";
288     }
289     
290     //END: Generated from @child and @property
291
}
292
293
294
Popular Tags