001 /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.13-12-g880e696 */ 002 package org.extendj.ast; 003 004 import java.util.HashSet; 005 import java.io.File; 006 import java.util.Set; 007 import java.util.Collections; 008 import java.util.Collection; 009 import java.util.ArrayList; 010 import beaver.*; 011 import java.util.*; 012 import java.io.ByteArrayOutputStream; 013 import java.io.PrintStream; 014 import java.lang.reflect.InvocationTargetException; 015 import java.lang.reflect.Method; 016 import org.jastadd.util.*; 017 import java.util.zip.*; 018 import java.io.*; 019 import org.jastadd.util.PrettyPrintable; 020 import org.jastadd.util.PrettyPrinter; 021 import java.io.FileNotFoundException; 022 import java.io.BufferedInputStream; 023 import java.io.DataInputStream; 024 /** 025 * Used in code generation to represent the implicit monitor exit 026 * call at the end of a synchronized block. 027 * @ast node 028 * @declaredat /home/jesper/git/extendj/java4/grammar/Java.ast:219 029 * @production MonitorExit : {@link Block}; 030 031 */ 032 public class MonitorExit extends Block implements Cloneable { 033 /** 034 * @aspect MonitorExit 035 * @declaredat /home/jesper/git/extendj/java4/frontend/MonitorExit.jrag:34 036 */ 037 protected SynchronizedStmt monitor = null; 038 /** 039 * @aspect MonitorExit 040 * @declaredat /home/jesper/git/extendj/java4/frontend/MonitorExit.jrag:36 041 */ 042 public MonitorExit(SynchronizedStmt sync) { 043 monitor = sync; 044 } 045 /** 046 * Generate bytecode for the monitor exit call. 047 * @aspect CreateBCode 048 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1904 049 */ 050 public void createBCode(CodeGeneration gen) { 051 gen.monitorRangeEnd(monitor.monitorId, 052 hostType().constantPool().newLabel()); 053 } 054 /** 055 * Generate exception handler for monitor closing. 056 * @param gen 057 * @aspect CreateBCode 058 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1913 059 */ 060 public void emitMonitorExitHandler(CodeGeneration gen) { 061 int handler_lbl = handler_label(); 062 int end_lbl = handler_end_label(); 063 064 gen.changeStackDepth(1); 065 int num = localNum() + 1; 066 067 // handler start 068 gen.addLabel(handler_lbl); 069 070 gen.emitStoreReference(num); 071 072 gen.emitLoadReference(monitor.localNum()); 073 gen.emit(Bytecode.MONITOREXIT); 074 075 // handler end 076 gen.addLabel(end_lbl); 077 078 gen.emitLoadReference(num); 079 gen.emit(Bytecode.ATHROW); 080 081 // add exception handler for the monitor closing 082 // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4414101 083 gen.addException(handler_lbl, end_lbl, handler_lbl, 084 CodeGeneration.ExceptionEntry.CATCH_ALL); 085 086 } 087 /** 088 * @declaredat ASTNode:1 089 */ 090 public MonitorExit() { 091 super(); 092 } 093 /** 094 * Initializes the child array to the correct size. 095 * Initializes List and Opt nta children. 096 * @apilevel internal 097 * @ast method 098 * @declaredat ASTNode:10 099 */ 100 public void init$Children() { 101 children = new ASTNode[1]; 102 setChild(new List(), 0); 103 } 104 /** 105 * @declaredat ASTNode:14 106 */ 107 public MonitorExit(List<Stmt> p0) { 108 setChild(p0, 0); 109 } 110 /** 111 * @apilevel low-level 112 * @declaredat ASTNode:20 113 */ 114 protected int numChildren() { 115 return 1; 116 } 117 /** 118 * @apilevel internal 119 * @declaredat ASTNode:26 120 */ 121 public boolean mayHaveRewrite() { 122 return false; 123 } 124 /** 125 * @apilevel internal 126 * @declaredat ASTNode:32 127 */ 128 public void flushAttrCache() { 129 super.flushAttrCache(); 130 handler_label_reset(); 131 handler_end_label_reset(); 132 end_label_reset(); 133 } 134 /** 135 * @apilevel internal 136 * @declaredat ASTNode:41 137 */ 138 public void flushCollectionCache() { 139 super.flushCollectionCache(); 140 } 141 /** 142 * @apilevel internal 143 * @declaredat ASTNode:47 144 */ 145 public void flushRewriteCache() { 146 super.flushRewriteCache(); 147 } 148 /** 149 * @apilevel internal 150 * @declaredat ASTNode:53 151 */ 152 public MonitorExit clone() throws CloneNotSupportedException { 153 MonitorExit node = (MonitorExit) super.clone(); 154 return node; 155 } 156 /** 157 * @apilevel internal 158 * @declaredat ASTNode:60 159 */ 160 public MonitorExit copy() { 161 try { 162 MonitorExit node = (MonitorExit) clone(); 163 node.parent = null; 164 if (children != null) { 165 node.children = (ASTNode[]) children.clone(); 166 } 167 return node; 168 } catch (CloneNotSupportedException e) { 169 throw new Error("Error: clone not supported for " + getClass().getName()); 170 } 171 } 172 /** 173 * Create a deep copy of the AST subtree at this node. 174 * The copy is dangling, i.e. has no parent. 175 * @return dangling copy of the subtree at this node 176 * @apilevel low-level 177 * @deprecated Please use treeCopy or treeCopyNoTransform instead 178 * @declaredat ASTNode:79 179 */ 180 @Deprecated 181 public MonitorExit fullCopy() { 182 return treeCopyNoTransform(); 183 } 184 /** 185 * Create a deep copy of the AST subtree at this node. 186 * The copy is dangling, i.e. has no parent. 187 * @return dangling copy of the subtree at this node 188 * @apilevel low-level 189 * @declaredat ASTNode:89 190 */ 191 public MonitorExit treeCopyNoTransform() { 192 MonitorExit tree = (MonitorExit) copy(); 193 if (children != null) { 194 for (int i = 0; i < children.length; ++i) { 195 ASTNode child = (ASTNode) children[i]; 196 if (child != null) { 197 child = child.treeCopyNoTransform(); 198 tree.setChild(child, i); 199 } 200 } 201 } 202 return tree; 203 } 204 /** 205 * Create a deep copy of the AST subtree at this node. 206 * The subtree of this node is traversed to trigger rewrites before copy. 207 * The copy is dangling, i.e. has no parent. 208 * @return dangling copy of the subtree at this node 209 * @apilevel low-level 210 * @declaredat ASTNode:109 211 */ 212 public MonitorExit treeCopy() { 213 doFullTraversal(); 214 return treeCopyNoTransform(); 215 } 216 /** 217 * @apilevel internal 218 * @declaredat ASTNode:116 219 */ 220 protected boolean is$Equal(ASTNode node) { 221 return super.is$Equal(node); 222 } 223 /** 224 * Replaces the Stmt list. 225 * @param list The new list node to be used as the Stmt list. 226 * @apilevel high-level 227 */ 228 public void setStmtList(List<Stmt> list) { 229 setChild(list, 0); 230 } 231 /** 232 * Retrieves the number of children in the Stmt list. 233 * @return Number of children in the Stmt list. 234 * @apilevel high-level 235 */ 236 public int getNumStmt() { 237 return getStmtList().getNumChild(); 238 } 239 /** 240 * Retrieves the number of children in the Stmt list. 241 * Calling this method will not trigger rewrites. 242 * @return Number of children in the Stmt list. 243 * @apilevel low-level 244 */ 245 public int getNumStmtNoTransform() { 246 return getStmtListNoTransform().getNumChildNoTransform(); 247 } 248 /** 249 * Retrieves the element at index {@code i} in the Stmt list. 250 * @param i Index of the element to return. 251 * @return The element at position {@code i} in the Stmt list. 252 * @apilevel high-level 253 */ 254 public Stmt getStmt(int i) { 255 return (Stmt) getStmtList().getChild(i); 256 } 257 /** 258 * Check whether the Stmt list has any children. 259 * @return {@code true} if it has at least one child, {@code false} otherwise. 260 * @apilevel high-level 261 */ 262 public boolean hasStmt() { 263 return getStmtList().getNumChild() != 0; 264 } 265 /** 266 * Append an element to the Stmt list. 267 * @param node The element to append to the Stmt list. 268 * @apilevel high-level 269 */ 270 public void addStmt(Stmt node) { 271 List<Stmt> list = (parent == null) ? getStmtListNoTransform() : getStmtList(); 272 list.addChild(node); 273 } 274 /** 275 * @apilevel low-level 276 */ 277 public void addStmtNoTransform(Stmt node) { 278 List<Stmt> list = getStmtListNoTransform(); 279 list.addChild(node); 280 } 281 /** 282 * Replaces the Stmt list element at index {@code i} with the new node {@code node}. 283 * @param node The new node to replace the old list element. 284 * @param i The list index of the node to be replaced. 285 * @apilevel high-level 286 */ 287 public void setStmt(Stmt node, int i) { 288 List<Stmt> list = getStmtList(); 289 list.setChild(node, i); 290 } 291 /** 292 * Retrieves the Stmt list. 293 * @return The node representing the Stmt list. 294 * @apilevel high-level 295 */ 296 @ASTNodeAnnotation.ListChild(name="Stmt") 297 public List<Stmt> getStmtList() { 298 List<Stmt> list = (List<Stmt>) getChild(0); 299 return list; 300 } 301 /** 302 * Retrieves the Stmt list. 303 * <p><em>This method does not invoke AST transformations.</em></p> 304 * @return The node representing the Stmt list. 305 * @apilevel low-level 306 */ 307 public List<Stmt> getStmtListNoTransform() { 308 return (List<Stmt>) getChildNoTransform(0); 309 } 310 /** 311 * Retrieves the Stmt list. 312 * @return The node representing the Stmt list. 313 * @apilevel high-level 314 */ 315 public List<Stmt> getStmts() { 316 return getStmtList(); 317 } 318 /** 319 * Retrieves the Stmt list. 320 * <p><em>This method does not invoke AST transformations.</em></p> 321 * @return The node representing the Stmt list. 322 * @apilevel low-level 323 */ 324 public List<Stmt> getStmtsNoTransform() { 325 return getStmtListNoTransform(); 326 } 327 /** 328 * @apilevel internal 329 */ 330 protected boolean handler_label_computed = false; 331 /** 332 * @apilevel internal 333 */ 334 protected int handler_label_value; 335 /** 336 * @apilevel internal 337 */ 338 private void handler_label_reset() { 339 handler_label_computed = false; 340 } 341 /** 342 * @attribute syn 343 * @aspect MonitorExit 344 * @declaredat /home/jesper/git/extendj/java4/backend/MonitorExit.jrag:32 345 */ 346 @ASTNodeAnnotation.Attribute 347 public int handler_label() { 348 ASTNode$State state = state(); 349 if (handler_label_computed) { 350 return handler_label_value; 351 } 352 boolean intermediate = state.INTERMEDIATE_VALUE; 353 state.INTERMEDIATE_VALUE = false; 354 int num = state.boundariesCrossed; 355 boolean isFinal = this.is$Final(); 356 handler_label_value = hostType().constantPool().newLabel(); 357 if (isFinal && num == state().boundariesCrossed) { 358 handler_label_computed = true; 359 } else { 360 } 361 state.INTERMEDIATE_VALUE |= intermediate; 362 363 return handler_label_value; 364 } 365 /** 366 * @apilevel internal 367 */ 368 protected boolean handler_end_label_computed = false; 369 /** 370 * @apilevel internal 371 */ 372 protected int handler_end_label_value; 373 /** 374 * @apilevel internal 375 */ 376 private void handler_end_label_reset() { 377 handler_end_label_computed = false; 378 } 379 /** 380 * @attribute syn 381 * @aspect MonitorExit 382 * @declaredat /home/jesper/git/extendj/java4/backend/MonitorExit.jrag:34 383 */ 384 @ASTNodeAnnotation.Attribute 385 public int handler_end_label() { 386 ASTNode$State state = state(); 387 if (handler_end_label_computed) { 388 return handler_end_label_value; 389 } 390 boolean intermediate = state.INTERMEDIATE_VALUE; 391 state.INTERMEDIATE_VALUE = false; 392 int num = state.boundariesCrossed; 393 boolean isFinal = this.is$Final(); 394 handler_end_label_value = hostType().constantPool().newLabel(); 395 if (isFinal && num == state().boundariesCrossed) { 396 handler_end_label_computed = true; 397 } else { 398 } 399 state.INTERMEDIATE_VALUE |= intermediate; 400 401 return handler_end_label_value; 402 } 403 /** 404 * @apilevel internal 405 */ 406 protected boolean end_label_computed = false; 407 /** 408 * @apilevel internal 409 */ 410 protected int end_label_value; 411 /** 412 * @apilevel internal 413 */ 414 private void end_label_reset() { 415 end_label_computed = false; 416 } 417 /** 418 * @attribute syn 419 * @aspect MonitorExit 420 * @declaredat /home/jesper/git/extendj/java4/backend/MonitorExit.jrag:36 421 */ 422 @ASTNodeAnnotation.Attribute 423 public int end_label() { 424 ASTNode$State state = state(); 425 if (end_label_computed) { 426 return end_label_value; 427 } 428 boolean intermediate = state.INTERMEDIATE_VALUE; 429 state.INTERMEDIATE_VALUE = false; 430 int num = state.boundariesCrossed; 431 boolean isFinal = this.is$Final(); 432 end_label_value = hostType().constantPool().newLabel(); 433 if (isFinal && num == state().boundariesCrossed) { 434 end_label_computed = true; 435 } else { 436 } 437 state.INTERMEDIATE_VALUE |= intermediate; 438 439 return end_label_value; 440 } 441 /** 442 * @apilevel internal 443 */ 444 public ASTNode rewriteTo() { 445 return super.rewriteTo(); 446 } 447 }