nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BlockLexicalContext.java
author attila
Wed, 28 Jan 2015 17:58:08 +0100
changeset 28690 78317797ab62
parent 27206 d4a707c9db5a
child 32534 b3ec7f3b3c2a
permissions -rw-r--r--
8067139: Finally blocks inlined incorrectly Reviewed-by: hannesw, lagergren
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     1
/*
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     4
 *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    10
 *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
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:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
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:
diff changeset
    15
 * accompanied this code).
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    16
 *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    20
 *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    23
 * questions.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    24
 */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    25
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    26
package jdk.nashorn.internal.ir;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    27
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    28
import java.util.ArrayDeque;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    29
import java.util.ArrayList;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    30
import java.util.Deque;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    31
import java.util.List;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    32
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    33
/**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    34
 * This is a subclass of lexical context used for filling
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    35
 * blocks (and function nodes) with statements. When popping
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    36
 * a block from the lexical context, any statements that have
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    37
 * been generated in it are commited to the block. This saves
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    38
 * unnecessary object mutations and lexical context replacement
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    39
 */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    40
public class BlockLexicalContext extends LexicalContext {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    41
    /** statement stack, each block on the lexical context maintains one of these, which is
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    42
     *  committed to the block on pop */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 18848
diff changeset
    43
    private final Deque<List<Statement>> sstack = new ArrayDeque<>();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    44
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    45
    /** Last non debug statement emitted in this context */
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
    46
    protected Statement lastStatement;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    47
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    48
    @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    49
    public <T extends LexicalContextNode> T push(final T node) {
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 18848
diff changeset
    50
        final T pushed = super.push(node);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    51
        if (node instanceof Block) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
    52
            sstack.push(new ArrayList<Statement>());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    53
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    54
        return pushed;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    55
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    56
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    57
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    58
     * Get the statement list from the stack, possibly filtered
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    59
     * @return statement list
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    60
     */
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
    61
    protected List<Statement> popStatements() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    62
        return sstack.pop();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    63
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    64
18848
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    65
    /**
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    66
     * Override this method to perform some additional processing on the block after its statements have been set. By
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    67
     * default does nothing and returns the original block.
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    68
     * @param block the block to operate on
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    69
     * @return a modified block.
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    70
     */
24778
2ff5d7041566 8044638: Tidy up Nashorn codebase for code standards
attila
parents: 18848
diff changeset
    71
    protected Block afterSetStatements(final Block block) {
18848
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    72
        return block;
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    73
    }
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    74
18317
2f5434c9c9fd 8015346: JSON parsing issues with escaped strings, octal, decimal numbers
sundar
parents: 17981
diff changeset
    75
    @SuppressWarnings("unchecked")
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    76
    @Override
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27206
diff changeset
    77
    public <T extends Node> T pop(final T node) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    78
        T expected = node;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    79
        if (node instanceof Block) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
    80
            final List<Statement> newStatements = popStatements();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    81
            expected = (T)((Block)node).setStatements(this, newStatements);
18848
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
    82
            expected = (T)afterSetStatements((Block)expected);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    83
            if (!sstack.isEmpty()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    84
                lastStatement = lastStatement(sstack.peek());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    85
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    86
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    87
        return super.pop(expected);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    88
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    89
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    90
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    91
     * Append a statement to the block being generated
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    92
     * @param statement statement to add
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    93
     */
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
    94
    public void appendStatement(final Statement statement) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    95
        assert statement != null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    96
        sstack.peek().add(statement);
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
    97
        lastStatement = statement;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    98
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
    99
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   100
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   101
     * Prepend a statement to the block being generated
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   102
     * @param statement statement to prepend
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   103
     * @return the prepended statement
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   104
     */
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
   105
    public Node prependStatement(final Statement statement) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   106
        assert statement != null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   107
        sstack.peek().add(0, statement);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   108
        return statement;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   109
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   110
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   111
    /**
27206
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   112
     * Prepend a list of statement to the block being generated
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   113
     * @param statements a list of statements to prepend
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   114
     */
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   115
    public void prependStatements(final List<Statement> statements) {
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   116
        assert statements != null;
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   117
        sstack.peek().addAll(0, statements);
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   118
    }
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   119
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   120
d4a707c9db5a 8059844: Implement optimistic splitter
attila
parents: 25865
diff changeset
   121
    /**
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
   122
     * Get the last statement that was emitted into a block
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   123
     * @return the last statement emitted
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   124
     */
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
   125
    public Statement getLastStatement() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   126
        return lastStatement;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   127
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   128
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17233
diff changeset
   129
    private static Statement lastStatement(final List<Statement> statements) {
18848
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
   130
        final int s = statements.size();
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 18317
diff changeset
   131
        return s == 0 ? null : statements.get(s - 1);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   132
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents:
diff changeset
   133
}