src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LexicalContext.java
author hannesw
Tue, 10 Sep 2019 15:35:35 +0200
changeset 58072 336687518f92
parent 47216 71c04702a3d5
permissions -rw-r--r--
8230709: Array index out of bounds in ES6 mode Reviewed-by: attila
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
     1
/*
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
     2
 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
     4
 *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    10
 *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    15
 * accompanied this code).
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    16
 *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    20
 *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    23
 * questions.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    24
 */
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    25
package jdk.nashorn.internal.ir;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    26
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    27
import java.io.File;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    28
import java.util.Iterator;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    29
import java.util.NoSuchElementException;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    30
import jdk.nashorn.internal.runtime.Debug;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    31
import jdk.nashorn.internal.runtime.Source;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    32
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    33
/**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
    34
 * A class that tracks the current lexical context of node visitation as a stack
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
    35
 * of {@link Block} nodes. Has special methods to retrieve useful subsets of the
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
    36
 * context.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    37
 *
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
    38
 * This is implemented with a primitive array and a stack pointer, because it
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
    39
 * really makes a difference performance-wise. None of the collection classes
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
    40
 * were optimal.
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    41
 */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    42
public class LexicalContext {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    43
    private LexicalContextNode[] stack;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    44
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    45
    private int[] flags;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    46
    private int sp;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    47
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    48
    /**
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    49
     * Creates a new empty lexical context.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    50
     */
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    51
    public LexicalContext() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    52
        stack = new LexicalContextNode[16];
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    53
        flags = new int[16];
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    54
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    55
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    56
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    57
     * Set the flags for a lexical context node on the stack. Does not
18853
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    58
     * replace the flags, but rather adds to them.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    59
     *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    60
     * @param node  node
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    61
     * @param flag  new flag to set
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    62
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    63
    public void setFlag(final LexicalContextNode node, final int flag) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    64
        if (flag != 0) {
18853
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    65
            // Use setBlockNeedsScope() instead
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    66
            assert !(flag == Block.NEEDS_SCOPE && node instanceof Block);
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    67
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    68
            for (int i = sp - 1; i >= 0; i--) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    69
                if (stack[i] == node) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    70
                    flags[i] |= flag;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    71
                    return;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    72
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    73
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    74
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    75
        assert false;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    76
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    77
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
    78
    /**
18853
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    79
     * Marks the block as one that creates a scope. Note that this method must
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    80
     * be used instead of {@link #setFlag(LexicalContextNode, int)} with
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    81
     * {@link Block#NEEDS_SCOPE} because it atomically also sets the
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    82
     * {@link FunctionNode#HAS_SCOPE_BLOCK} flag on the block's containing
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    83
     * function.
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
    84
     *
18853
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    85
     * @param block the block that needs to be marked as creating a scope.
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    86
     */
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    87
    public void setBlockNeedsScope(final Block block) {
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    88
        for (int i = sp - 1; i >= 0; i--) {
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    89
            if (stack[i] == block) {
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    90
                flags[i] |= Block.NEEDS_SCOPE;
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    91
                for(int j = i - 1; j >=0; j --) {
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    92
                    if(stack[j] instanceof FunctionNode) {
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    93
                        flags[j] |= FunctionNode.HAS_SCOPE_BLOCK;
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    94
                        return;
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    95
                    }
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    96
                }
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    97
            }
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    98
        }
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
    99
        assert false;
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
   100
    }
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
   101
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 17756
diff changeset
   102
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   103
     * Get the flags for a lexical context node on the stack.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   104
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   105
     * @param node node
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   106
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   107
     * @return the flags for the node
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   108
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   109
    public int getFlags(final LexicalContextNode node) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   110
        for (int i = sp - 1; i >= 0; i--) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   111
            if (stack[i] == node) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   112
                return flags[i];
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
        throw new AssertionError("flag node not on context stack");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   116
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   117
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   118
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   119
     * Get the function body of a function node on the lexical context
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   120
     * stack. This will trigger an assertion if node isn't present.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   121
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   122
     * @param functionNode function node
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   123
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   124
     * @return body of function node
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   125
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   126
    public Block getFunctionBody(final FunctionNode functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   127
        for (int i = sp - 1; i >= 0 ; i--) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   128
            if (stack[i] == functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   129
                return (Block)stack[i + 1];
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   130
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   131
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   132
        throw new AssertionError(functionNode.getName() + " not on context stack");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   133
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   134
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   135
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   136
     * @return all nodes in the LexicalContext.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   137
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   138
    public Iterator<LexicalContextNode> getAllNodes() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   139
        return new NodeIterator<>(LexicalContextNode.class);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   140
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   141
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   142
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   143
     * Returns the outermost function in this context. It is either the program,
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   144
     * or a lazily compiled function.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   145
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   146
     * @return the outermost function in this context.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   147
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   148
    public FunctionNode getOutermostFunction() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   149
        return (FunctionNode)stack[0];
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   150
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   151
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   152
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   153
     * Pushes a new block on top of the context, making it the innermost open
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   154
     * block.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   155
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   156
     * @param <T> the type of the new node
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   157
     * @param node the new node
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   158
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   159
     * @return the node that was pushed
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   160
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   161
    public <T extends LexicalContextNode> T push(final T node) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   162
        assert !contains(node);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   163
        if (sp == stack.length) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   164
            final LexicalContextNode[] newStack = new LexicalContextNode[sp * 2];
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   165
            System.arraycopy(stack, 0, newStack, 0, sp);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   166
            stack = newStack;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   167
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   168
            final int[] newFlags = new int[sp * 2];
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   169
            System.arraycopy(flags, 0, newFlags, 0, sp);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   170
            flags = newFlags;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   171
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   172
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   173
        stack[sp] = node;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   174
        flags[sp] = 0;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   175
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   176
        sp++;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   177
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   178
        return node;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   179
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   180
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   181
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   182
     * Is the context empty?
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   183
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   184
     * @return {@code true} if empty
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   185
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   186
    public boolean isEmpty() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   187
        return sp == 0;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   188
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   189
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   190
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   191
     * @return the depth of the lexical context.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   192
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   193
    public int size() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   194
        return sp;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   195
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   196
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   197
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   198
     * Pops the innermost block off the context and all nodes that has been
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   199
     * contributed since it was put there.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   200
     *
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   201
     * @param <T> the type of the node to be popped
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   202
     * @param node the node expected to be popped, used to detect unbalanced
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   203
     *        pushes/pops
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   204
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   205
     * @return the node that was popped
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   206
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   207
    @SuppressWarnings("unchecked")
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   208
    public <T extends Node> T pop(final T node) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   209
        --sp;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   210
        final LexicalContextNode popped = stack[sp];
17249
a2014831ae7a 8013325: function named 'arguments' should set DEFINES_ARGUMENTS flag in its parent, not itself
attila
parents: 17233
diff changeset
   211
        stack[sp] = null;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   212
        if (popped instanceof Flags) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   213
            return (T)((Flags<?>)popped).setFlag(this, flags[sp]);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   214
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   215
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   216
        return (T)popped;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   217
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   218
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   219
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   220
     * Explicitly apply flags to the topmost element on the stack. This is only
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   221
     * valid to use from a {@code NodeVisitor.leaveXxx()} method and only on the
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   222
     * node being exited at the time. It is not mandatory to use, as
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   223
     * {@link #pop(Node)} will apply the flags automatically, but this method
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   224
     * can be used to apply them during the {@code leaveXxx()} method in case
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   225
     * its logic depends on the value of the flags.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   226
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   227
     * @param <T> the type of the node to apply the flags to.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   228
     * @param node the node to apply the flags to. Must be the topmost node on
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   229
     *        the stack.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   230
     *
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   231
     * @return the passed in node, or a modified node (if any flags were modified)
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   232
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   233
    public <T extends LexicalContextNode & Flags<T>> T applyTopFlags(final T node) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   234
        assert node == peek();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   235
        return node.setFlag(this, flags[sp - 1]);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   236
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   237
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   238
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   239
     * Return the top element in the context.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   240
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   241
     * @return the node that was pushed last
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   242
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   243
    public LexicalContextNode peek() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   244
        return stack[sp - 1];
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   245
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   246
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   247
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   248
     * Check if a node is in the lexical context.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   249
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   250
     * @param node node to check for
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   251
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   252
     * @return {@code true} if in the context
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   253
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   254
    public boolean contains(final LexicalContextNode node) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   255
        for (int i = 0; i < sp; i++) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   256
            if (stack[i] == node) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   257
                return true;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   258
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   259
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   260
        return false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   261
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   262
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   263
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   264
     * Replace a node on the lexical context with a new one. Normally
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   265
     * you should try to engineer IR traversals so this isn't needed
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   266
     *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   267
     * @param oldNode old node
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   268
     * @param newNode new node
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   269
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   270
     * @return the new node
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   271
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   272
    public LexicalContextNode replace(final LexicalContextNode oldNode, final LexicalContextNode newNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   273
        for (int i = sp - 1; i >= 0; i--) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   274
            if (stack[i] == oldNode) {
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   275
                assert i == sp - 1 : "violation of contract - we always expect to find the replacement node on top of the lexical context stack: " + newNode + " has " + stack[i + 1].getClass() + " above it";
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   276
                stack[i] = newNode;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   277
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   278
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   279
         }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   280
        return newNode;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   281
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   282
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   283
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   284
     * Returns an iterator over all blocks in the context, with the top block
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   285
     * (innermost lexical context) first.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   286
     *
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   287
     * @return an iterator over all blocks in the context.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   288
     */
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   289
    public Iterator<Block> getBlocks() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   290
        return new NodeIterator<>(Block.class);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   291
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   292
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   293
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   294
     * Returns an iterator over all functions in the context, with the top
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   295
     * (innermost open) function first.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   296
     *
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   297
     * @return an iterator over all functions in the context.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   298
     */
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   299
    public Iterator<FunctionNode> getFunctions() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   300
        return new NodeIterator<>(FunctionNode.class);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   301
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   302
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   303
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   304
     * Get the parent block for the current lexical context block
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   305
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   306
     * @return parent block
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   307
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   308
    public Block getParentBlock() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   309
        final Iterator<Block> iter = new NodeIterator<>(Block.class, getCurrentFunction());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   310
        iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   311
        return iter.hasNext() ? iter.next() : null;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   312
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   313
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   314
    /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   315
     * Gets the label node of the current block.
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   316
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   317
     * @return the label node of the current block, if it is labeled. Otherwise
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   318
     *         returns {@code null}.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   319
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   320
    public LabelNode getCurrentBlockLabelNode() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   321
        assert stack[sp - 1] instanceof Block;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   322
        if(sp < 2) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   323
            return null;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   324
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   325
        final LexicalContextNode parent = stack[sp - 2];
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   326
        return parent instanceof LabelNode ? (LabelNode)parent : null;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   327
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   328
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   329
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   330
     * Returns an iterator over all ancestors block of the given block, with its
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   331
     * parent block first.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   332
     *
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   333
     * @param block the block whose ancestors are returned
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   334
     *
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   335
     * @return an iterator over all ancestors block of the given block.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   336
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   337
    public Iterator<Block> getAncestorBlocks(final Block block) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   338
        final Iterator<Block> iter = getBlocks();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   339
        while (iter.hasNext()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   340
            final Block b = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   341
            if (block == b) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   342
                return iter;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   343
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   344
        }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   345
        throw new AssertionError("Block is not on the current lexical context stack");
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   346
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   347
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   348
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   349
     * Returns an iterator over a block and all its ancestors blocks, with the
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   350
     * block first.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   351
     *
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   352
     * @param block the block that is the starting point of the iteration.
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   353
     *
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   354
     * @return an iterator over a block and all its ancestors.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   355
     */
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   356
    public Iterator<Block> getBlocks(final Block block) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   357
        final Iterator<Block> iter = getAncestorBlocks(block);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   358
        return new Iterator<Block>() {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   359
            boolean blockReturned = false;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   360
            @Override
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   361
            public boolean hasNext() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   362
                return iter.hasNext() || !blockReturned;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   363
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   364
            @Override
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   365
            public Block next() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   366
                if (blockReturned) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   367
                    return iter.next();
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   368
                }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   369
                blockReturned = true;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   370
                return block;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   371
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   372
            @Override
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   373
            public void remove() {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   374
                throw new UnsupportedOperationException();
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   375
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   376
        };
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   377
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   378
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   379
    /**
26503
3ed48a01100c 8057148: Skip nested functions on reparse
attila
parents: 26068
diff changeset
   380
     * Get the function for this block.
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   381
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   382
     * @param block block for which to get function
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   383
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   384
     * @return function for block
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   385
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   386
    public FunctionNode getFunction(final Block block) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   387
        final Iterator<LexicalContextNode> iter = new NodeIterator<>(LexicalContextNode.class);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   388
        while (iter.hasNext()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   389
            final LexicalContextNode next = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   390
            if (next == block) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   391
                while (iter.hasNext()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   392
                    final LexicalContextNode next2 = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   393
                    if (next2 instanceof FunctionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   394
                        return (FunctionNode)next2;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   395
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   396
                }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   397
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   398
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   399
        assert false;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   400
        return null;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   401
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   402
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   403
    /**
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   404
     * @return the innermost block in the context.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   405
     */
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   406
    public Block getCurrentBlock() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   407
        return getBlocks().next();
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   408
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   409
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   410
    /**
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   411
     * @return the innermost function in the context.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   412
     */
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   413
    public FunctionNode getCurrentFunction() {
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   414
        for (int i = sp - 1; i >= 0; i--) {
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   415
            if (stack[i] instanceof FunctionNode) {
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   416
                return (FunctionNode) stack[i];
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   417
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   418
        }
19084
daddbeee0058 8020356: ClassCastException Undefined->Scope on spiltter class generated for a large switch statement
hannesw
parents: 18867
diff changeset
   419
        return null;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   420
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   421
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   422
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   423
     * Get the block in which a symbol is defined.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   424
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   425
     * @param symbol symbol
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   426
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   427
     * @return block in which the symbol is defined, assert if no such block in
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   428
     *         context.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   429
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   430
    public Block getDefiningBlock(final Symbol symbol) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   431
        final String name = symbol.getName();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   432
        for (final Iterator<Block> it = getBlocks(); it.hasNext();) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   433
            final Block next = it.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   434
            if (next.getExistingSymbol(name) == symbol) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   435
                return next;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   436
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   437
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   438
        throw new AssertionError("Couldn't find symbol " + name + " in the context");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   439
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   440
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   441
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   442
     * Get the function in which a symbol is defined.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   443
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   444
     * @param symbol symbol
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   445
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   446
     * @return function node in which this symbol is defined, assert if no such
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   447
     *         symbol exists in context.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   448
     */
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   449
    public FunctionNode getDefiningFunction(final Symbol symbol) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   450
        final String name = symbol.getName();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   451
        for (final Iterator<LexicalContextNode> iter = new NodeIterator<>(LexicalContextNode.class); iter.hasNext();) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   452
            final LexicalContextNode next = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   453
            if (next instanceof Block && ((Block)next).getExistingSymbol(name) == symbol) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   454
                while (iter.hasNext()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   455
                    final LexicalContextNode next2 = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   456
                    if (next2 instanceof FunctionNode) {
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   457
                        return (FunctionNode)next2;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   458
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   459
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   460
                throw new AssertionError("Defining block for symbol " + name + " has no function in the context");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   461
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   462
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   463
        throw new AssertionError("Couldn't find symbol " + name + " in the context");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   464
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   465
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   466
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   467
     * Is the topmost lexical context element a function body?
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   468
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   469
     * @return {@code true} if function body.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   470
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   471
    public boolean isFunctionBody() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   472
        return getParentBlock() == null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   473
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   474
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   475
    /**
27206
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 26503
diff changeset
   476
     * Is the topmost lexical context element body of a SplitNode?
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   477
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   478
     * @return {@code true} if it's the body of a split node.
27206
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 26503
diff changeset
   479
     */
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 26503
diff changeset
   480
    public boolean isSplitBody() {
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 26503
diff changeset
   481
        return sp >= 2 && stack[sp - 1] instanceof Block && stack[sp - 2] instanceof SplitNode;
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 26503
diff changeset
   482
    }
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 26503
diff changeset
   483
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 26503
diff changeset
   484
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   485
     * Get the parent function for a function in the lexical context.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   486
     *
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   487
     * @param functionNode function for which to get parent
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   488
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   489
     * @return parent function of functionNode or {@code null} if none (e.g., if
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   490
     *         functionNode is the program).
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   491
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   492
    public FunctionNode getParentFunction(final FunctionNode functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   493
        final Iterator<FunctionNode> iter = new NodeIterator<>(FunctionNode.class);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   494
        while (iter.hasNext()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   495
            final FunctionNode next = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   496
            if (next == functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   497
                return iter.hasNext() ? iter.next() : null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   498
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   499
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   500
        assert false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   501
        return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   502
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   503
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   504
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   505
     * Count the number of scopes until a given node. Note that this method is
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   506
     * solely used to figure out the number of scopes that need to be explicitly
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   507
     * popped in order to perform a break or continue jump within the current
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   508
     * bytecode method. For this reason, the method returns 0 if it encounters a
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   509
     * {@code SplitNode} between the current location and the break/continue
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   510
     * target.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   511
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   512
     * @param until node to stop counting at. Must be within the current function.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   513
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   514
     * @return number of with scopes encountered in the context.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   515
     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   516
    public int getScopeNestingLevelTo(final LexicalContextNode until) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   517
        assert until != null;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   518
        //count the number of with nodes until "until" is hit
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   519
        int n = 0;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   520
        for (final Iterator<LexicalContextNode> iter = getAllNodes(); iter.hasNext();) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   521
            final LexicalContextNode node = iter.next();
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   522
            if (node == until) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   523
                break;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   524
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   525
            assert !(node instanceof FunctionNode); // Can't go outside current function
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   526
            if (node instanceof WithNode || node instanceof Block && ((Block)node).needsScope()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   527
                n++;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20559
diff changeset
   528
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   529
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   530
        return n;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   531
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   532
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   533
    private BreakableNode getBreakable() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   534
        for (final NodeIterator<BreakableNode> iter = new NodeIterator<>(BreakableNode.class, getCurrentFunction()); iter.hasNext(); ) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   535
            final BreakableNode next = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   536
            if (next.isBreakableWithoutLabel()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   537
                return next;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   538
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   539
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   540
        return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   541
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   542
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   543
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   544
     * Check whether the lexical context is currently inside a loop.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   545
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   546
     * @return {@code true} if inside a loop
17756
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   547
     */
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   548
    public boolean inLoop() {
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   549
        return getCurrentLoop() != null;
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   550
    }
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   551
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   552
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   553
     * @return the loop header of the current loop, or {@code null} if not
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   554
     *         inside a loop.
17756
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   555
     */
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   556
    public LoopNode getCurrentLoop() {
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   557
        final Iterator<LoopNode> iter = new NodeIterator<>(LoopNode.class, getCurrentFunction());
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   558
        return iter.hasNext() ? iter.next() : null;
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   559
    }
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   560
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   561
    /**
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   562
     * Find the breakable node corresponding to this label.
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   563
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   564
     * @param labelName name of the label to search for. If {@code null}, the
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   565
     *        closest breakable node will be returned unconditionally, e.g., a
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   566
     *        while loop with no label.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   567
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   568
     * @return closest breakable node.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   569
     */
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   570
    public BreakableNode getBreakable(final String labelName) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   571
        if (labelName != null) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   572
            final LabelNode foundLabel = findLabel(labelName);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   573
            if (foundLabel != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   574
                // iterate to the nearest breakable to the foundLabel
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   575
                BreakableNode breakable = null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   576
                for (final NodeIterator<BreakableNode> iter = new NodeIterator<>(BreakableNode.class, foundLabel); iter.hasNext(); ) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   577
                    breakable = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   578
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   579
                return breakable;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   580
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   581
            return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   582
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   583
        return getBreakable();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   584
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   585
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   586
    private LoopNode getContinueTo() {
17756
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   587
        return getCurrentLoop();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   588
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   589
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   590
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   591
     * Find the continue target node corresponding to this label.
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   592
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   593
     * @param labelName label name to search for. If {@code null} the closest
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   594
     *        loop node will be returned unconditionally, e.g., a while loop
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   595
     *        with no label.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   596
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   597
     * @return closest continue target node.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   598
     */
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   599
    public LoopNode getContinueTo(final String labelName) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   600
        if (labelName != null) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   601
            final LabelNode foundLabel = findLabel(labelName);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   602
            if (foundLabel != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   603
                // iterate to the nearest loop to the foundLabel
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   604
                LoopNode loop = null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   605
                for (final NodeIterator<LoopNode> iter = new NodeIterator<>(LoopNode.class, foundLabel); iter.hasNext(); ) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   606
                    loop = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   607
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   608
                return loop;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   609
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   610
            return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   611
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   612
        return getContinueTo();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   613
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   614
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   615
    /**
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   616
     * Find the inlined finally block node corresponding to this label.
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   617
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   618
     * @param labelName label name to search for. Must not be {@code null}.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   619
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   620
     * @return closest inlined finally block with the given label.
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   621
     */
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   622
    public Block getInlinedFinally(final String labelName) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   623
        for (final NodeIterator<TryNode> iter = new NodeIterator<>(TryNode.class); iter.hasNext(); ) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   624
            final Block inlinedFinally = iter.next().getInlinedFinally(labelName);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   625
            if (inlinedFinally != null) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   626
                return inlinedFinally;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   627
            }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   628
        }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   629
        return null;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   630
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   631
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   632
    /**
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   633
     * Find the try node for an inlined finally block corresponding to this label.
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   634
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   635
     * @param labelName label name to search for. Must not be {@code null}.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   636
     *
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   637
     * @return the try node to which the labelled inlined finally block belongs.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   638
     */
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   639
    public TryNode getTryNodeForInlinedFinally(final String labelName) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   640
        for (final NodeIterator<TryNode> iter = new NodeIterator<>(TryNode.class); iter.hasNext(); ) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   641
            final TryNode tryNode = iter.next();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   642
            if (tryNode.getInlinedFinally(labelName) != null) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   643
                return tryNode;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   644
            }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   645
        }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   646
        return null;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   647
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   648
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   649
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   650
     * Check the lexical context for a given label node by name.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   651
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   652
     * @param name name of the label.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   653
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   654
     * @return LabelNode if found, {@code null} otherwise.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   655
     */
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   656
    private LabelNode findLabel(final String name) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   657
        for (final Iterator<LabelNode> iter = new NodeIterator<>(LabelNode.class, getCurrentFunction()); iter.hasNext(); ) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   658
            final LabelNode next = iter.next();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   659
            if (next.getLabelName().equals(name)) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   660
                return next;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   661
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   662
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   663
        return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   664
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   665
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   666
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   667
     * Checks whether a given target is a jump destination that lies outside a
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   668
     * given split node.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   669
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   670
     * @param splitNode the split node.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   671
     * @param target the target node.
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   672
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   673
     * @return {@code true} if target resides outside the split node.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   674
     */
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   675
    public boolean isExternalTarget(final SplitNode splitNode, final BreakableNode target) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   676
        for (int i = sp; i-- > 0;) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   677
            final LexicalContextNode next = stack[i];
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   678
            if (next == splitNode) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   679
                return true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   680
            } else if (next == target) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   681
                return false;
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   682
            } else if (next instanceof TryNode) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   683
                for(final Block inlinedFinally: ((TryNode)next).getInlinedFinallies()) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   684
                    if (TryNode.getLabelledInlinedFinallyBlock(inlinedFinally) == target) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   685
                        return false;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   686
                    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27817
diff changeset
   687
                }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   688
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   689
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24725
diff changeset
   690
        throw new AssertionError(target + " was expected in lexical context " + LexicalContext.this + " but wasn't");
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   691
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   692
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   693
    /**
31097
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   694
     * Checks whether the current context is inside a switch statement without
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   695
     * explicit blocks (curly braces).
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   696
     *
996397e0a35c 8085885: address Javadoc warnings in Nashorn source code
mhaupt
parents: 30701
diff changeset
   697
     * @return {@code true} if in unprotected switch statement.
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   698
     */
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   699
    public boolean inUnprotectedSwitchContext() {
58072
336687518f92 8230709: Array index out of bounds in ES6 mode
hannesw
parents: 47216
diff changeset
   700
        for (int i = sp - 1; i > 0; i--) {
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   701
            final LexicalContextNode next = stack[i];
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   702
            if (next instanceof Block) {
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   703
                return stack[i - 1] instanceof SwitchNode;
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   704
            }
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   705
        }
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   706
        return false;
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   707
    }
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   708
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   709
    @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   710
    public String toString() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   711
        final StringBuffer sb = new StringBuffer();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   712
        sb.append("[ ");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   713
        for (int i = 0; i < sp; i++) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   714
            final Object node = stack[i];
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   715
            sb.append(node.getClass().getSimpleName());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   716
            sb.append('@');
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   717
            sb.append(Debug.id(node));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   718
            sb.append(':');
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   719
            if (node instanceof FunctionNode) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   720
                final FunctionNode fn = (FunctionNode)node;
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   721
                final Source source = fn.getSource();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   722
                String src = source.toString();
20559
9244eb6d195b 8025515: Performance issues with Source.getLine()
hannesw
parents: 19084
diff changeset
   723
                if (src.contains(File.pathSeparator)) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   724
                    src = src.substring(src.lastIndexOf(File.pathSeparator));
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   725
                }
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   726
                src += ' ';
20559
9244eb6d195b 8025515: Performance issues with Source.getLine()
hannesw
parents: 19084
diff changeset
   727
                src += fn.getLineNumber();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   728
                sb.append(src);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   729
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   730
            sb.append(' ');
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   731
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   732
        sb.append(" ==> ]");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   733
        return sb.toString();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   734
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   735
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   736
    private class NodeIterator <T extends LexicalContextNode> implements Iterator<T> {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   737
        private int index;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   738
        private T next;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   739
        private final Class<T> clazz;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   740
        private LexicalContextNode until;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   741
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   742
        NodeIterator(final Class<T> clazz) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   743
            this(clazz, null);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   744
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   745
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   746
        NodeIterator(final Class<T> clazz, final LexicalContextNode until) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   747
            this.index = sp - 1;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   748
            this.clazz = clazz;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   749
            this.until = until;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   750
            this.next  = findNext();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   751
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   752
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   753
        @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   754
        public boolean hasNext() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   755
            return next != null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   756
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   757
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   758
        @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   759
        public T next() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   760
            if (next == null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   761
                throw new NoSuchElementException();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   762
            }
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   763
            final T lnext = next;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   764
            next = findNext();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   765
            return lnext;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   766
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   767
25821
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 24751
diff changeset
   768
        @SuppressWarnings("unchecked")
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   769
        private T findNext() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   770
            for (int i = index; i >= 0; i--) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   771
                final Object node = stack[i];
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   772
                if (node == until) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   773
                    return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   774
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   775
                if (clazz.isAssignableFrom(node.getClass())) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   776
                    index = i - 1;
25821
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 24751
diff changeset
   777
                    return (T)node;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   778
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   779
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   780
            return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   781
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   782
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   783
        @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   784
        public void remove() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   785
            throw new UnsupportedOperationException();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   786
        }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   787
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents:
diff changeset
   788
}