1 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 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 if (!(body instanceof BlockStmt)) { 60 body.showError("block {} required"); 61 } 62 63 } 64 65 68 public void walkFlow(FlowCheckerPass w) { 69 w.process(getExpr()); 70 w.process(getBody()); 71 } 72 73 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 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); cb.emitDUP(); cb.emitASTORE(lockLoc); cb.emitMONITORENTER(); 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); cb.emitMONITOREXIT(); cb.emitJump(end); } 110 111 cb.emitLabel(startExn); 112 cb.pushStack(1); cb.emitASTORE(retValLoc); cb.emitJSR(startFinally); cb.emitALOAD(retValLoc); cb.emitATHROW(); 118 cb.emitLabel(startFinally); 119 cb.pushStack(1); cb.emitASTORE(retPtrLoc); cb.emitALOAD(lockLoc); cb.emitMONITOREXIT(); cb.emitRET(retPtrLoc); 125 cb.emitLabel(end); 126 cb.addHandler(startBody, endBody, startExn, null); } 128 130 133 135 142 private int lockLoc; 143 private int retValLoc; 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 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 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 getDefaultDisplayName() { 219 return "SynchronizedStmt()"; 220 } 221 222 } 224 225 226 | Popular Tags |