nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/TryNode.java
author attila
Wed, 28 Jan 2015 17:58:08 +0100
changeset 28690 78317797ab62
parent 27204 06ec78f29a56
child 30701 1a25e71187ff
permissions -rw-r--r--
8067139: Finally blocks inlined incorrectly Reviewed-by: hannesw, lagergren
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.ir;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import java.util.ArrayList;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
import java.util.Collections;
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    30
import java.util.HashSet;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import java.util.List;
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    32
import java.util.Set;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    33
import jdk.nashorn.internal.ir.annotations.Immutable;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
 * IR representation of a TRY statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
 */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    39
@Immutable
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    40
public final class TryNode extends LexicalContextStatement implements JoinPredecessor {
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 25865
diff changeset
    41
    private static final long serialVersionUID = 1L;
06ec78f29a56 8059843: Make AST serializable
attila
parents: 25865
diff changeset
    42
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
    /** Try statements. */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    44
    private final Block body;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
    /** List of catch clauses. */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    47
    private final List<Block> catchBlocks;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    48
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    49
    /** Finally clause. */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    50
    private final Block finallyBody;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    52
    /**
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    53
     * List of inlined finally blocks. The structure of every inlined finally is:
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    54
     * Block(LabelNode(label, Block(finally-statements, (JumpStatement|ReturnNode)?))).
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    55
     * That is, the block has a single LabelNode statement with the label and a block containing the
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    56
     * statements of the inlined finally block with the jump or return statement appended (if the finally
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    57
     * block was not terminal; the original jump/return is simply ignored if the finally block itself
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    58
     * terminates). The reason for this somewhat strange arrangement is that we didn't want to create a
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    59
     * separate class for the (label, BlockStatement pair) but rather reused the already available LabelNode.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    60
     * However, if we simply used List<LabelNode> without wrapping the label nodes in an additional Block,
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    61
     * that would've thrown off visitors relying on BlockLexicalContext -- same reason why we never use
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    62
     * Statement as the type of bodies of e.g. IfNode, WhileNode etc. but rather blockify them even when they're
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    63
     * single statements.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    64
     */
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    65
    private final List<Block> inlinedFinallies;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    66
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    67
    /** Exception symbol. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
    private Symbol exception;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
    70
    private final LocalVariableConversion conversion;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
    71
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
     *
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
    75
     * @param lineNumber  lineNumber
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    76
     * @param token       token
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    77
     * @param finish      finish
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    78
     * @param body        try node body
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    79
     * @param catchBlocks list of catch blocks in order
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    80
     * @param finallyBody body of finally block or null if none
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
     */
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
    82
    public TryNode(final int lineNumber, final long token, final int finish, final Block body, final List<Block> catchBlocks, final Block finallyBody) {
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
    83
        super(lineNumber, token, finish);
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
    84
        this.body        = body;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    85
        this.catchBlocks = catchBlocks;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    86
        this.finallyBody = finallyBody;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
    87
        this.conversion  = null;
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    88
        this.inlinedFinallies = Collections.emptyList();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    91
    private TryNode(final TryNode tryNode, final Block body, final List<Block> catchBlocks, final Block finallyBody, final LocalVariableConversion conversion, final List<Block> inlinedFinallies) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    92
        super(tryNode);
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
    93
        this.body        = body;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    94
        this.catchBlocks = catchBlocks;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    95
        this.finallyBody = finallyBody;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
    96
        this.conversion  = conversion;
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
    97
        this.inlinedFinallies = inlinedFinallies;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
    98
        this.exception = tryNode.exception;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   102
    public Node ensureUniqueLabels(final LexicalContext lc) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   103
        //try nodes are never in lex context
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   104
        return new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   105
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   106
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   107
    @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   108
    public boolean isTerminal() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   109
        if (body.isTerminal()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   110
            for (final Block catchBlock : getCatchBlocks()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   111
                if (!catchBlock.isTerminal()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   112
                    return false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   113
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   114
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   115
            return true;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   116
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   117
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   119
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   121
     * Assist in IR navigation.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
     * @param visitor IR navigating visitor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
    @Override
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   125
    public Node accept(final LexicalContext lc, NodeVisitor<? extends LexicalContext> visitor) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   126
        if (visitor.enterTryNode(this)) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   127
            // Need to do finallybody first for termination analysis. TODO still necessary?
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   128
            final Block newFinallyBody = finallyBody == null ? null : (Block)finallyBody.accept(visitor);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   129
            final Block newBody        = (Block)body.accept(visitor);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   130
            return visitor.leaveTryNode(
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   131
                setBody(lc, newBody).
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   132
                setFinallyBody(lc, newFinallyBody).
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   133
                setCatchBlocks(lc, Node.accept(visitor, catchBlocks)).
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   134
                setInlinedFinallies(lc, Node.accept(visitor, inlinedFinallies)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   135
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   136
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   137
        return this;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   138
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   139
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   140
    @Override
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   141
    public void toString(final StringBuilder sb, final boolean printType) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   142
        sb.append("try ");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   143
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   144
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   145
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   146
     * Get the body for this try block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   147
     * @return body
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   148
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   149
    public Block getBody() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   150
        return body;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   151
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   152
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   153
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   154
     * Reset the body of this try block
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   155
     * @param lc current lexical context
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
     * @param body new body
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   157
     * @return new TryNode or same if unchanged
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
     */
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   159
    public TryNode setBody(final LexicalContext lc, final Block body) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   160
        if (this.body == body) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   161
            return this;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   162
        }
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   163
        return Node.replaceInLexicalContext(lc, this, new TryNode(this,  body, catchBlocks, finallyBody, conversion, inlinedFinallies));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   164
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   167
     * Get the catches for this try block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
     * @return a list of catch nodes
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   169
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   170
    public List<CatchNode> getCatches() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   171
        final List<CatchNode> catches = new ArrayList<>(catchBlocks.size());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   172
        for (final Block catchBlock : catchBlocks) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   173
            catches.add(getCatchNodeFromBlock(catchBlock));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   174
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   175
        return Collections.unmodifiableList(catches);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16240
diff changeset
   176
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16240
diff changeset
   177
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   178
    private static CatchNode getCatchNodeFromBlock(final Block catchBlock) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   179
        return (CatchNode)catchBlock.getStatements().get(0);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   180
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   181
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16240
diff changeset
   182
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
     * Get the catch blocks for this try block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
     * @return a list of blocks
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
    public List<Block> getCatchBlocks() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
        return Collections.unmodifiableList(catchBlocks);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   189
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   190
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   191
     * Set the catch blocks of this try
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   192
     * @param lc current lexical context
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
     * @param catchBlocks list of catch blocks
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   194
     * @return new TryNode or same if unchanged
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   195
     */
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   196
    public TryNode setCatchBlocks(final LexicalContext lc, final List<Block> catchBlocks) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   197
        if (this.catchBlocks == catchBlocks) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   198
            return this;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   199
        }
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   200
        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   201
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   202
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   203
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
     * Get the exception symbol for this try block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   205
     * @return a symbol for the compiler to store the exception in
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   207
    public Symbol getException() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   208
        return exception;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   209
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   210
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   211
     * Set the exception symbol for this try block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
     * @param exception a symbol for the compiler to store the exception in
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   213
     * @return new TryNode or same if unchanged
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   215
    public TryNode setException(final Symbol exception) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   216
        this.exception = exception;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   217
        return this;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   218
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
     * Get the body of the finally clause for this try
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   222
     * @return finally body, or null if no finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   224
    public Block getFinallyBody() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   225
        return finallyBody;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   226
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   227
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
    /**
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   229
     * Get the inlined finally block with the given label name. This returns the actual finally block in the
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   230
     * {@link LabelNode}, not the outer wrapper block for the {@link LabelNode}.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   231
     * @param labelName the name of the inlined finally's label
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   232
     * @return the requested finally block, or null if no finally block's label matches the name.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   233
     */
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   234
    public Block getInlinedFinally(final String labelName) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   235
        for(final Block inlinedFinally: inlinedFinallies) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   236
            final LabelNode labelNode = getInlinedFinallyLabelNode(inlinedFinally);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   237
            if (labelNode.getLabelName().equals(labelName)) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   238
                return labelNode.getBody();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   239
            }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   240
        }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   241
        return null;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   242
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   243
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   244
    private static LabelNode getInlinedFinallyLabelNode(final Block inlinedFinally) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   245
        return (LabelNode)inlinedFinally.getStatements().get(0);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   246
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   247
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   248
    /**
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   249
     * Given an outer wrapper block for the {@link LabelNode} as returned by {@link #getInlinedFinallies()},
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   250
     * returns its actual inlined finally block.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   251
     * @param inlinedFinally the outer block for inlined finally, as returned as an element of
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   252
     * {@link #getInlinedFinallies()}.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   253
     * @return the block contained in the {@link LabelNode} contained in the passed block.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   254
     */
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   255
    public static Block getLabelledInlinedFinallyBlock(final Block inlinedFinally) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   256
        return getInlinedFinallyLabelNode(inlinedFinally).getBody();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   257
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   258
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   259
    /**
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   260
     * Returns a list of inlined finally blocks. Note that this returns a list of {@link Block}s such that each one of
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   261
     * them has a single {@link LabelNode}, which in turn contains the label name for the finally block and the
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   262
     * actual finally block. To safely extract the actual finally block, use
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   263
     * {@link #getLabelledInlinedFinallyBlock(Block)}.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   264
     * @return a list of inlined finally blocks.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   265
     */
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   266
    public List<Block> getInlinedFinallies() {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   267
        return Collections.unmodifiableList(inlinedFinallies);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   268
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   269
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   270
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   271
     * Set the finally body of this try
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   272
     * @param lc current lexical context
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   273
     * @param finallyBody new finally body
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   274
     * @return new TryNode or same if unchanged
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   275
     */
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   276
    public TryNode setFinallyBody(final LexicalContext lc, final Block finallyBody) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   277
        if (this.finallyBody == finallyBody) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   278
            return this;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   279
        }
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   280
        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   281
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   282
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   283
    /**
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   284
     * Set the inlined finally blocks of this try. Each element should be a block with a single statement that is a
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   285
     * {@link LabelNode} with a unique label, and the block within the label node should contain the actual inlined
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   286
     * finally block.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   287
     * @param lc current lexical context
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   288
     * @param inlinedFinallies list of inlined finally blocks
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   289
     * @return new TryNode or same if unchanged
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   290
     */
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   291
    public TryNode setInlinedFinallies(final LexicalContext lc, final List<Block> inlinedFinallies) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   292
        if (this.inlinedFinallies == inlinedFinallies) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   293
            return this;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   294
        }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   295
        assert checkInlinedFinallies(inlinedFinallies);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   296
        return Node.replaceInLexicalContext(lc, this, new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   297
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   298
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   299
    private static boolean checkInlinedFinallies(final List<Block> inlinedFinallies) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   300
        if (!inlinedFinallies.isEmpty()) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   301
            final Set<String> labels = new HashSet<>();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   302
            for (final Block inlinedFinally : inlinedFinallies) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   303
                final List<Statement> stmts = inlinedFinally.getStatements();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   304
                assert stmts.size() == 1;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   305
                final LabelNode ln = getInlinedFinallyLabelNode(inlinedFinally);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   306
                assert labels.add(ln.getLabelName()); // unique label
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   307
            }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   308
        }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   309
        return true;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   310
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   311
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   312
    @Override
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   313
    public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   314
        if(this.conversion == conversion) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   315
            return this;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   316
        }
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27204
diff changeset
   317
        return new TryNode(this, body, catchBlocks, finallyBody, conversion, inlinedFinallies);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   318
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   319
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   320
    @Override
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   321
    public LocalVariableConversion getLocalVariableConversion() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 17769
diff changeset
   322
        return conversion;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   323
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   324
}