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 import java.util.Iterator ; 36 37 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 83 public ASTObject postFixAST(final ASTFixerPass fixer) { 84 if (! isOptional()) return super.postFixAST(fixer); 85 setIsOptional(false); 86 return this; 87 } 88 89 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 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 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); cb.pushStack(1); cb.emitASTORE(retValLoc); cb.emitJSR(startFinally); cb.emitALOAD(retValLoc); cb.emitATHROW(); 176 cb.emitLabel(startFinally); cb.pushStack(1); cb.emitASTORE(retPtrLoc); getFinally().cgTop(cb); if (getFinally().completesNormally()) { 181 cb.emitRET(retPtrLoc); } 183 cb.addHandler(startBody, endBody, startExn, null); 185 cb.emitLabel(end); 186 } 187 188 191 194 198 205 208 211 private int retValLoc; 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 retValLoc = walker.allocate(2); retPtrLoc = walker.allocate(1); 224 walker.process(getFinally()); 225 walker.inTryFinally = inTryFinally; 226 walker.setfs(start); 227 } 228 229 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 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 getDefaultDisplayName() { 287 return "TryFinallyStmt()"; 288 } 289 290 } 292 293 294 | Popular Tags |