KickJava   Java API By Example, From Geeks To Geeks.

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


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 /**
36  * @grammar synchronized (expr) {body}
37  * @child Expr expr
38  * @child Stmt body
39  */

40 public class SynchronizedStmt extends Stmt implements WindingStmt {
41
42     public void unparse(CodeWriter writer) {
43         writer.writeKeyword("synchronized");
44         writer.requiredSpace();
45         writer.parenExpr(expr);
46         writer.write(body);
47     }
48
49     public void checkSpec() {
50         if (!expr.getType().isReferenceType()) {
51             expr.showError("reference type required");
52         }
53
54         if (expr instanceof NullExpr) {
55             expr.showError("null not allowed");
56         }
57
58         // should probably be handled by parser
59
if (!(body instanceof BlockStmt)) {
60             body.showError("block {} required");
61         }
62
63     }
64
65     // ------------------------------
66
// INTRO from FlowCheckerPass
67

68     public void walkFlow(FlowCheckerPass w) {
69         w.process(getExpr());
70         w.process(getBody());
71     }
72
73     // ------------------------------
74
// Intro: ByteCodeCleanupPass
75

76     public ASTObject postCleanup(ByteCodeCleanupPass walker) {
77         if (getBody() instanceof EmptyStmt) {
78             return getAST().makeStmt(getExpr()).setSource(getExpr());
79         } else {
80             return this;
81         }
82     }
83
84     // ------------------------------
85
// bcg
86

87     protected void cgStmt(CodeBuilder cb) {
88         Label startBody = cb.genAnchor();
89         Label endBody = cb.genAnchor();
90         Label startExn = cb.genAnchor();
91         Label startFinally = cb.genAnchor();
92         Label end = cb.genLabel();
93
94         expr.cgValue(cb); // put the lock on the stack
95
cb.emitDUP(); // dup it
96
cb.emitASTORE(lockLoc); // store the duplicate
97
cb.emitMONITORENTER(); // and lock it.
98

99         cb.emitLabel(startBody);
100         cb.enterWindingContext(this, startFinally);
101         body.cgTop(cb);
102         cb.leaveContext();
103
104         cb.emitLabel(endBody);
105         if (body.completesNormally()) {
106             cb.emitALOAD(lockLoc); // load the lock onto the stack
107
cb.emitMONITOREXIT(); // unlock the lock
108
cb.emitJump(end); // and we're done
109
}
110
111         cb.emitLabel(startExn);
112         cb.pushStack(1); // there's an exn on the stack
113
cb.emitASTORE(retValLoc); // store exn
114
cb.emitJSR(startFinally); // exit the monitor
115
cb.emitALOAD(retValLoc); // reload the exn
116
cb.emitATHROW(); // rethrow
117

118         cb.emitLabel(startFinally);
119         cb.pushStack(1); // return addr on the stack
120
cb.emitASTORE(retPtrLoc); // store return addr, shouldn't be lockType
121
cb.emitALOAD(lockLoc); // retrieve lock object
122
cb.emitMONITOREXIT(); // unlock
123
cb.emitRET(retPtrLoc); // return
124

125         cb.emitLabel(end);
126         cb.addHandler(startBody, endBody, startExn, null); // add default handler
127
}
128     // end bcg
129

130     // ------------------------------
131
// Intro: FrameLocPass
132

133     // We allocate space for the lock, and enter the block.
134

135     // After analyzing the block, we need to remember to "pre-analyze"
136
// the jsr block we're going to have to use to make this work.
137
// This means allocating space for the retval or exn, costing 2
138
// slots (actually, only (max 1 retvalSlotSize), but we'll allow
139
// for 2), and the return pointer, costing one slot. We save the
140
// locations of each of these.
141

142     private int lockLoc;
143     private int retValLoc; // same as exn loc
144
private int retPtrLoc;
145
146     public int getRetValLoc() { return retValLoc; }
147
148     public void walkFrameLoc(FrameLocPass walker) {
149         boolean inTryFinally = walker.inTryFinally;
150         walker.inTryFinally = true;
151         int start = walker.getfs();
152         lockLoc = walker.allocate(1);
153         walker.process(getBody());
154         walker.setfs(start + 1);
155         retValLoc = walker.allocate(2);
156         retPtrLoc = walker.allocate(1);
157         walker.inTryFinally = inTryFinally;
158         walker.setfs(start);
159     }
160
161     //BEGIN: Generated from @child and @property
162
protected Expr expr;
163     public Expr getExpr() { return expr; }
164     public void setExpr(Expr _expr) {
165         if (_expr != null) _expr.setParent(this);
166         expr = _expr;
167     }
168
169     protected Stmt body;
170     public Stmt getBody() { return body; }
171     public void setBody(Stmt _body) {
172         if (_body != null) _body.setParent(this);
173         body = _body;
174     }
175
176     public SynchronizedStmt(SourceLocation location, Expr _expr, Stmt _body) {
177         super(location);
178         setExpr(_expr);
179         setBody(_body);
180     }
181     protected SynchronizedStmt(SourceLocation source) {
182         super(source);
183     }
184
185     public ASTObject copyWalk(CopyWalker walker) {
186         SynchronizedStmt ret = new SynchronizedStmt(getSourceLocation());
187         ret.preCopy(walker, this);
188         if (expr != null) ret.setExpr( (Expr)walker.process(expr) );
189         if (body != null) ret.setBody( (Stmt)walker.process(body) );
190         return ret;
191     }
192
193     public ASTObject getChildAt(int childIndex) {
194         switch(childIndex) {
195         case 0: return expr;
196         case 1: return body;
197         default: return super.getChildAt(childIndex);
198         }
199     }
200      public String JavaDoc getChildNameAt(int childIndex) {
201         switch(childIndex) {
202         case 0: return "expr";
203         case 1: return "body";
204         default: return super.getChildNameAt(childIndex);
205         }
206     }
207      public void setChildAt(int childIndex, ASTObject child) {
208         switch(childIndex) {
209         case 0: setExpr((Expr)child); return;
210         case 1: setBody((Stmt)child); return;
211         default: super.setChildAt(childIndex, child); return;
212         }
213     }
214      public int getChildCount() {
215         return 2;
216     }
217
218     public String JavaDoc getDefaultDisplayName() {
219         return "SynchronizedStmt()";
220     }
221
222     //END: Generated from @child and @property
223
}
224
225
226
Popular Tags