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    }