nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java
author attila
Wed, 28 Jan 2015 17:58:08 +0100
changeset 28690 78317797ab62
parent 27976 ef54dfb4fc7d
child 28784 a79ac84f2ea4
permissions -rw-r--r--
8067139: Finally blocks inlined incorrectly Reviewed-by: hannesw, lagergren
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.codegen;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    29
import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
    30
import static jdk.nashorn.internal.ir.Expression.isAlwaysTrue;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import java.util.ArrayList;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import java.util.Arrays;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
    34
import java.util.Collections;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
import java.util.List;
18848
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
    36
import java.util.ListIterator;
27976
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
    37
import java.util.regex.Pattern;
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
    38
import jdk.nashorn.internal.ir.AccessNode;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
    39
import jdk.nashorn.internal.ir.BaseNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import jdk.nashorn.internal.ir.BinaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import jdk.nashorn.internal.ir.Block;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    42
import jdk.nashorn.internal.ir.BlockLexicalContext;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
    43
import jdk.nashorn.internal.ir.BlockStatement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import jdk.nashorn.internal.ir.BreakNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
import jdk.nashorn.internal.ir.CallNode;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
    46
import jdk.nashorn.internal.ir.CaseNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    47
import jdk.nashorn.internal.ir.CatchNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    48
import jdk.nashorn.internal.ir.ContinueNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    49
import jdk.nashorn.internal.ir.EmptyNode;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
    50
import jdk.nashorn.internal.ir.Expression;
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
    51
import jdk.nashorn.internal.ir.ExpressionStatement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import jdk.nashorn.internal.ir.ForNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
import jdk.nashorn.internal.ir.FunctionNode;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
    54
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
import jdk.nashorn.internal.ir.IdentNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
import jdk.nashorn.internal.ir.IfNode;
27976
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
    57
import jdk.nashorn.internal.ir.IndexNode;
26889
dba314d7a634 8059371: Code duplication in handling of break and continue
attila
parents: 26504
diff changeset
    58
import jdk.nashorn.internal.ir.JumpStatement;
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
    59
import jdk.nashorn.internal.ir.JumpToInlinedFinally;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    60
import jdk.nashorn.internal.ir.LabelNode;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
    61
import jdk.nashorn.internal.ir.LexicalContext;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
import jdk.nashorn.internal.ir.LiteralNode;
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
    63
import jdk.nashorn.internal.ir.LiteralNode.PrimitiveLiteralNode;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    64
import jdk.nashorn.internal.ir.LoopNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
import jdk.nashorn.internal.ir.Node;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    66
import jdk.nashorn.internal.ir.ReturnNode;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
    67
import jdk.nashorn.internal.ir.RuntimeNode;
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
    68
import jdk.nashorn.internal.ir.Statement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
import jdk.nashorn.internal.ir.SwitchNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
import jdk.nashorn.internal.ir.Symbol;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
import jdk.nashorn.internal.ir.ThrowNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
import jdk.nashorn.internal.ir.TryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
import jdk.nashorn.internal.ir.VarNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
import jdk.nashorn.internal.ir.WhileNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
import jdk.nashorn.internal.ir.WithNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
import jdk.nashorn.internal.parser.Token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
import jdk.nashorn.internal.parser.TokenType;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    80
import jdk.nashorn.internal.runtime.Context;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
    81
import jdk.nashorn.internal.runtime.JSType;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
import jdk.nashorn.internal.runtime.Source;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
    83
import jdk.nashorn.internal.runtime.logging.DebugLogger;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
    84
import jdk.nashorn.internal.runtime.logging.Loggable;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
    85
import jdk.nashorn.internal.runtime.logging.Logger;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    86
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    87
/**
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
    88
 * Lower to more primitive operations. After lowering, an AST still has no symbols
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
    89
 * and types, but several nodes have been turned into more low level constructs
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
    90
 * and control flow termination criteria have been computed.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    91
 *
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
    92
 * We do things like code copying/inlining of finallies here, as it is much
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
    93
 * harder and context dependent to do any code copying after symbols have been
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
    94
 * finalized.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
 */
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
    96
@Logger(name="lower")
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
    97
final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Loggable {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
    99
    private final DebugLogger log;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   100
27976
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   101
    // Conservative pattern to test if element names consist of characters valid for identifiers.
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   102
    // This matches any non-zero length alphanumeric string including _ and $ and not starting with a digit.
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   103
    private static Pattern SAFE_PROPERTY_NAME = Pattern.compile("[a-zA-Z_$][\\w$]*");
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   104
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   105
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   106
     * Constructor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
     */
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   108
    Lower(final Compiler compiler) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   109
        super(new BlockLexicalContext() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   110
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   111
            @Override
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   112
            public List<Statement> popStatements() {
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   113
                final List<Statement> newStatements = new ArrayList<>();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   114
                boolean terminated = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   115
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   116
                final List<Statement> statements = super.popStatements();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   117
                for (final Statement statement : statements) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   118
                    if (!terminated) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   119
                        newStatements.add(statement);
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   120
                        if (statement.isTerminal() || statement instanceof JumpStatement) { //TODO hasGoto? But some Loops are hasGoto too - why?
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   121
                            terminated = true;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   122
                        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   123
                    } else {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   124
                        statement.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   125
                            @Override
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   126
                            public boolean enterVarNode(final VarNode varNode) {
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   127
                                newStatements.add(varNode.setInit(null));
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   128
                                return false;
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   129
                            }
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   130
                        });
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   131
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   132
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   133
                return newStatements;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   134
            }
18848
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   135
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   136
            @Override
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   137
            protected Block afterSetStatements(final Block block) {
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   138
                final List<Statement> stmts = block.getStatements();
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   139
                for(final ListIterator<Statement> li = stmts.listIterator(stmts.size()); li.hasPrevious();) {
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   140
                    final Statement stmt = li.previous();
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   141
                    // popStatements() guarantees that the only thing after a terminal statement are uninitialized
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   142
                    // VarNodes. We skip past those, and set the terminal state of the block to the value of the
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   143
                    // terminal state of the first statement that is not an uninitialized VarNode.
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   144
                    if(!(stmt instanceof VarNode && ((VarNode)stmt).getInit() == null)) {
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   145
                        return block.setIsTerminal(this, stmt.isTerminal());
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   146
                    }
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   147
                }
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   148
                return block.setIsTerminal(this, false);
e64943db2b06 8019809: return after break incorrectly sets the block as terminal
attila
parents: 17982
diff changeset
   149
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   150
        });
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   151
27976
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   152
        this.log = initLogger(compiler.getContext());
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   153
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   154
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   155
    @Override
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   156
    public DebugLogger getLogger() {
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   157
        return log;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   158
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   159
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   160
    @Override
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   161
    public DebugLogger initLogger(final Context context) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   162
        return context.getLogger(this.getClass());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   163
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   164
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   165
    @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   166
    public boolean enterBreakNode(final BreakNode breakNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   167
        addStatement(breakNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   168
        return false;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   169
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   170
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   171
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   172
    public Node leaveCallNode(final CallNode callNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   173
        return checkEval(callNode.setFunction(markerFunction(callNode.getFunction())));
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   174
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   175
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   176
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   177
    public Node leaveCatchNode(final CatchNode catchNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   178
        return addStatement(catchNode);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   179
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   180
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   181
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   182
    public boolean enterContinueNode(final ContinueNode continueNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   183
        addStatement(continueNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   184
        return false;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   185
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   186
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   187
    @Override
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   188
    public boolean enterJumpToInlinedFinally(final JumpToInlinedFinally jumpToInlinedFinally) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   189
        addStatement(jumpToInlinedFinally);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   190
        return false;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   191
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   192
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   193
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   194
    public boolean enterEmptyNode(final EmptyNode emptyNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   195
        return false;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   196
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   197
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   198
    @Override
27976
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   199
    public Node leaveIndexNode(final IndexNode indexNode) {
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   200
        final String name = getConstantPropertyName(indexNode.getIndex());
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   201
        if (name != null) {
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   202
            // If index node is a constant property name convert index node to access node.
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   203
            assert Token.descType(indexNode.getToken()) == TokenType.LBRACKET;
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   204
            return new AccessNode(indexNode.getToken(), indexNode.getFinish(), indexNode.getBase(), name);
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   205
        }
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   206
        return super.leaveIndexNode(indexNode);
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   207
    }
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   208
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   209
    // If expression is a primitive literal that is not an array index and does return its string value. Else return null.
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   210
    private static String getConstantPropertyName(final Expression expression) {
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   211
        if (expression instanceof LiteralNode.PrimitiveLiteralNode) {
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   212
            final Object value = ((LiteralNode) expression).getValue();
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   213
            if (value instanceof String && SAFE_PROPERTY_NAME.matcher((String) value).matches()) {
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   214
                return (String) value;
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   215
            }
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   216
        }
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   217
        return null;
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   218
    }
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   219
ef54dfb4fc7d 8066669: dust.js performance regression caused by primitive field conversion
hannesw
parents: 27970
diff changeset
   220
    @Override
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   221
    public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   222
        final Expression expr = expressionStatement.getExpression();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   223
        ExpressionStatement node = expressionStatement;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   224
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   225
        final FunctionNode currentFunction = lc.getCurrentFunction();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   226
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   227
        if (currentFunction.isProgram()) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   228
            if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   229
                node = expressionStatement.setExpression(
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   230
                    new BinaryNode(
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   231
                        Token.recast(
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   232
                            expressionStatement.getToken(),
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   233
                            TokenType.ASSIGN),
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   234
                        compilerConstant(RETURN),
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   235
                    expr));
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   236
            }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   237
        }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   238
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   239
        return addStatement(node);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   240
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   241
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   242
    @Override
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   243
    public Node leaveBlockStatement(final BlockStatement blockStatement) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   244
        return addStatement(blockStatement);
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   245
    }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   246
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   247
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   248
    public Node leaveForNode(final ForNode forNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   249
        ForNode newForNode = forNode;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   250
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   251
        final Expression test = forNode.getTest();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   252
        if (!forNode.isForIn() && isAlwaysTrue(test)) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   253
            newForNode = forNode.setTest(lc, null);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   254
        }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   255
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   256
        newForNode = checkEscape(newForNode);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   257
        if(newForNode.isForIn()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   258
            // Wrap it in a block so its internally created iterator is restricted in scope
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   259
            addStatementEnclosedInBlock(newForNode);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   260
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   261
            addStatement(newForNode);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   262
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   263
        return newForNode;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   264
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   265
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   266
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   267
    public Node leaveFunctionNode(final FunctionNode functionNode) {
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   268
        log.info("END FunctionNode: ", functionNode.getName());
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   269
        return functionNode.setState(lc, CompilationState.LOWERED);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   270
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   271
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   272
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   273
    public Node leaveIfNode(final IfNode ifNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   274
        return addStatement(ifNode);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   275
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   276
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   277
    @Override
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   278
    public Node leaveIN(final BinaryNode binaryNode) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   279
        return new RuntimeNode(binaryNode);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   280
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   281
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   282
    @Override
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   283
    public Node leaveINSTANCEOF(final BinaryNode binaryNode) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   284
        return new RuntimeNode(binaryNode);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   285
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   286
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   287
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   288
    public Node leaveLabelNode(final LabelNode labelNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   289
        return addStatement(labelNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   290
    }
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   291
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   292
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   293
    public Node leaveReturnNode(final ReturnNode returnNode) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   294
        addStatement(returnNode); //ReturnNodes are always terminal, marked as such in constructor
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   295
        return returnNode;
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   296
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   297
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   298
    @Override
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   299
    public Node leaveCaseNode(final CaseNode caseNode) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   300
        // Try to represent the case test as an integer
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   301
        final Node test = caseNode.getTest();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   302
        if (test instanceof LiteralNode) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   303
            final LiteralNode<?> lit = (LiteralNode<?>)test;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   304
            if (lit.isNumeric() && !(lit.getValue() instanceof Integer)) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   305
                if (JSType.isRepresentableAsInt(lit.getNumber())) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   306
                    return caseNode.setTest((Expression)LiteralNode.newInstance(lit, lit.getInt32()).accept(this));
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   307
                }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   308
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   309
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   310
        return caseNode;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   311
    }
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   312
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   313
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   314
    public Node leaveSwitchNode(final SwitchNode switchNode) {
27970
7b0048b90967 8066225: NPE in MethodEmitter with duplicate integer switch cases
attila
parents: 27817
diff changeset
   315
        if(!switchNode.isUniqueInteger()) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   316
            // Wrap it in a block so its internally created tag is restricted in scope
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   317
            addStatementEnclosedInBlock(switchNode);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   318
        } else {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   319
            addStatement(switchNode);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   320
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   321
        return switchNode;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   322
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   323
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   324
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   325
    public Node leaveThrowNode(final ThrowNode throwNode) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   326
        return addStatement(throwNode); //ThrowNodes are always terminal, marked as such in constructor
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   327
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   328
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   329
    private static <T extends Node> T ensureUniqueNamesIn(final T node) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   330
        return (T)node.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
17752
9d2d0e74a833 8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17745
diff changeset
   331
            @Override
9d2d0e74a833 8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17745
diff changeset
   332
            public Node leaveFunctionNode(final FunctionNode functionNode) {
9d2d0e74a833 8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17745
diff changeset
   333
                final String name = functionNode.getName();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   334
                return functionNode.setName(lc, lc.getCurrentFunction().uniqueName(name));
17752
9d2d0e74a833 8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17745
diff changeset
   335
            }
9d2d0e74a833 8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17745
diff changeset
   336
9d2d0e74a833 8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17745
diff changeset
   337
            @Override
9d2d0e74a833 8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17745
diff changeset
   338
            public Node leaveDefault(final Node labelledNode) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   339
                return labelledNode.ensureUniqueLabels(lc);
17752
9d2d0e74a833 8013919: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17745
diff changeset
   340
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   341
        });
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   342
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   343
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   344
    private static Block createFinallyBlock(final Block finallyBody) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   345
        final List<Statement> newStatements = new ArrayList<>();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   346
        for (final Statement statement : finallyBody.getStatements()) {
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   347
            newStatements.add(statement);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   348
            if (statement.hasTerminalFlags()) {
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   349
                break;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   350
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   351
        }
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   352
        return finallyBody.setStatements(null, newStatements);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   353
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   354
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   355
    private Block catchAllBlock(final TryNode tryNode) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   356
        final int  lineNumber = tryNode.getLineNumber();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   357
        final long token      = tryNode.getToken();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   358
        final int  finish     = tryNode.getFinish();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   359
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   360
        final IdentNode exception = new IdentNode(token, finish, lc.getCurrentFunction().uniqueName(CompilerConstants.EXCEPTION_PREFIX.symbolName()));
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   361
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   362
        final Block catchBody = new Block(token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), true));
19100
62d400be5b44 8021244: Inconsistent stackmap with splitter threshold set very low
hannesw
parents: 18867
diff changeset
   363
        assert catchBody.isTerminal(); //ends with throw, so terminal
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   364
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   365
        final CatchNode catchAllNode  = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody, true);
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   366
        final Block     catchAllBlock = new Block(token, finish, catchAllNode);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   367
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   368
        //catchallblock -> catchallnode (catchnode) -> exception -> throw
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   369
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   370
        return (Block)catchAllBlock.accept(this); //not accepted. has to be accepted by lower
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   371
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   372
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   373
    private IdentNode compilerConstant(final CompilerConstants cc) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   374
        final FunctionNode functionNode = lc.getCurrentFunction();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17233
diff changeset
   375
        return new IdentNode(functionNode.getToken(), functionNode.getFinish(), cc.symbolName());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   376
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   377
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   378
    private static boolean isTerminalFinally(final Block finallyBlock) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   379
        return finallyBlock.getLastStatement().hasTerminalFlags();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   380
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   381
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   382
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   383
     * Splice finally code into all endpoints of a trynode
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   384
     * @param tryNode the try node
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   385
     * @param rethrow the rethrowing throw nodes from the synthetic catch block
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   386
     * @param finallyBody the code in the original finally block
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   387
     * @return new try node after splicing finally code (same if nop)
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   388
     */
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   389
    private TryNode spliceFinally(final TryNode tryNode, final ThrowNode rethrow, final Block finallyBody) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   390
        assert tryNode.getFinallyBody() == null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   391
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   392
        final Block finallyBlock = createFinallyBlock(finallyBody);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   393
        final ArrayList<Block> inlinedFinallies = new ArrayList<>();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   394
        final FunctionNode fn = lc.getCurrentFunction();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   395
        final TryNode newTryNode = (TryNode)tryNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   396
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   397
            @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   398
            public boolean enterFunctionNode(final FunctionNode functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   399
                // do not enter function nodes - finally code should not be inlined into them
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   400
                return false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   401
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   402
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   403
            @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   404
            public Node leaveThrowNode(final ThrowNode throwNode) {
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   405
                if (rethrow == throwNode) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   406
                    return new BlockStatement(prependFinally(finallyBlock, throwNode));
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   407
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   408
                return throwNode;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   409
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   410
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   411
            @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   412
            public Node leaveBreakNode(final BreakNode breakNode) {
26889
dba314d7a634 8059371: Code duplication in handling of break and continue
attila
parents: 26504
diff changeset
   413
                return leaveJumpStatement(breakNode);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   414
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   415
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   416
            @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   417
            public Node leaveContinueNode(final ContinueNode continueNode) {
26889
dba314d7a634 8059371: Code duplication in handling of break and continue
attila
parents: 26504
diff changeset
   418
                return leaveJumpStatement(continueNode);
dba314d7a634 8059371: Code duplication in handling of break and continue
attila
parents: 26504
diff changeset
   419
            }
dba314d7a634 8059371: Code duplication in handling of break and continue
attila
parents: 26504
diff changeset
   420
dba314d7a634 8059371: Code duplication in handling of break and continue
attila
parents: 26504
diff changeset
   421
            private Node leaveJumpStatement(final JumpStatement jump) {
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   422
                // NOTE: leaveJumpToInlinedFinally deliberately does not delegate to this method, only break and
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   423
                // continue are edited. JTIF nodes should not be changed, rather the surroundings of
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   424
                // break/continue/return that were moved into the inlined finally block itself will be changed.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   425
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   426
                // If this visitor's lc doesn't find the target of the jump, it means it's external to the try block.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   427
                if (jump.getTarget(lc) == null) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   428
                    return createJumpToInlinedFinally(fn, inlinedFinallies, prependFinally(finallyBlock, jump));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   429
                }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   430
                return jump;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   431
            }
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   432
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   433
            @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   434
            public Node leaveReturnNode(final ReturnNode returnNode) {
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   435
                final Expression expr = returnNode.getExpression();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   436
                if (isTerminalFinally(finallyBlock)) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   437
                    if (expr == null) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   438
                        // Terminal finally; no return expression.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   439
                        return createJumpToInlinedFinally(fn, inlinedFinallies, ensureUniqueNamesIn(finallyBlock));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   440
                    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   441
                    // Terminal finally; has a return expression.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   442
                    final List<Statement> newStatements = new ArrayList<>(2);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   443
                    final int retLineNumber = returnNode.getLineNumber();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   444
                    final long retToken = returnNode.getToken();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   445
                    // Expression is evaluated for side effects.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   446
                    newStatements.add(new ExpressionStatement(retLineNumber, retToken, returnNode.getFinish(), expr));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   447
                    newStatements.add(createJumpToInlinedFinally(fn, inlinedFinallies, ensureUniqueNamesIn(finallyBlock)));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   448
                    return new BlockStatement(retLineNumber, new Block(retToken, finallyBlock.getFinish(), newStatements));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   449
                } else if (expr == null || expr instanceof PrimitiveLiteralNode<?> || (expr instanceof IdentNode && RETURN.symbolName().equals(((IdentNode)expr).getName()))) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   450
                    // Nonterminal finally; no return expression, or returns a primitive literal, or returns :return.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   451
                    // Just move the return expression into the finally block.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   452
                    return createJumpToInlinedFinally(fn, inlinedFinallies, prependFinally(finallyBlock, returnNode));
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   453
                } else {
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   454
                    // We need to evaluate the result of the return in case it is complex while still in the try block,
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   455
                    // store it in :return, and return it afterwards.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   456
                    final List<Statement> newStatements = new ArrayList<>();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   457
                    final int retLineNumber = returnNode.getLineNumber();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   458
                    final long retToken = returnNode.getToken();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   459
                    final int retFinish = returnNode.getFinish();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   460
                    final Expression resultNode = new IdentNode(expr.getToken(), expr.getFinish(), RETURN.symbolName());
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   461
                    // ":return = <expr>;"
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   462
                    newStatements.add(new ExpressionStatement(retLineNumber, retToken, retFinish, new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr)));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   463
                    // inline finally and end it with "return :return;"
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   464
                    newStatements.add(createJumpToInlinedFinally(fn, inlinedFinallies, prependFinally(finallyBlock, returnNode.setExpression(resultNode))));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   465
                    return new BlockStatement(retLineNumber, new Block(retToken, retFinish, newStatements));
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   466
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   467
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   468
        });
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   469
        addStatement(inlinedFinallies.isEmpty() ? newTryNode : newTryNode.setInlinedFinallies(lc, inlinedFinallies));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   470
        // TODO: if finallyStatement is terminal, we could just have sites of inlined finallies jump here.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   471
        addStatement(new BlockStatement(finallyBlock));
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   472
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   473
        return newTryNode;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   474
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   475
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   476
    private static JumpToInlinedFinally createJumpToInlinedFinally(final FunctionNode fn, final List<Block> inlinedFinallies, final Block finallyBlock) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   477
        final String labelName = fn.uniqueName(":finally");
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   478
        final long token = finallyBlock.getToken();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   479
        final int finish = finallyBlock.getFinish();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   480
        inlinedFinallies.add(new Block(token, finish, new LabelNode(finallyBlock.getFirstStatementLineNumber(),
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   481
                token, finish, labelName, finallyBlock)));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   482
        return new JumpToInlinedFinally(labelName);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   483
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   484
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   485
    private static Block prependFinally(final Block finallyBlock, final Statement statement) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   486
        final Block inlinedFinally = ensureUniqueNamesIn(finallyBlock);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   487
        if (isTerminalFinally(finallyBlock)) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   488
            return inlinedFinally;
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   489
        }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   490
        final List<Statement> stmts = inlinedFinally.getStatements();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   491
        final List<Statement> newStmts = new ArrayList<>(stmts.size() + 1);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   492
        newStmts.addAll(stmts);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   493
        newStmts.add(statement);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   494
        return new Block(inlinedFinally.getToken(), statement.getFinish(), newStmts);
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   495
    }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   496
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   497
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   498
    public Node leaveTryNode(final TryNode tryNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   499
        final Block finallyBody = tryNode.getFinallyBody();
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   500
        TryNode newTryNode = tryNode.setFinallyBody(lc, null);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   501
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   502
        // No finally or empty finally
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   503
        if (finallyBody == null || finallyBody.getStatementCount() == 0) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   504
            final List<CatchNode> catches = newTryNode.getCatches();
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   505
            if (catches == null || catches.isEmpty()) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   506
                // A completely degenerate try block: empty finally, no catches. Replace it with try body.
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   507
                return addStatement(new BlockStatement(tryNode.getBody()));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   508
            }
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   509
            return addStatement(ensureUnconditionalCatch(newTryNode));
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   510
        }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   511
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   512
        /*
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   513
         * create a new trynode
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   514
         *    if we have catches:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   515
         *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   516
         *    try            try
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   517
         *       x              try
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   518
         *    catch               x
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   519
         *       y              catch
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   520
         *    finally z           y
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   521
         *                   catchall
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   522
         *                        rethrow
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   523
         *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   524
         *   otheriwse
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   525
         *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   526
         *   try              try
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   527
         *      x               x
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   528
         *   finally          catchall
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   529
         *      y               rethrow
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   530
         *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   531
         *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   532
         *   now splice in finally code wherever needed
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   533
         *
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   534
         */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   535
        final Block catchAll = catchAllBlock(tryNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   536
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   537
        final List<ThrowNode> rethrows = new ArrayList<>(1);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   538
        catchAll.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   539
            @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   540
            public boolean enterThrowNode(final ThrowNode throwNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   541
                rethrows.add(throwNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   542
                return true;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   543
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   544
        });
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   545
        assert rethrows.size() == 1;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   546
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   547
        if (!tryNode.getCatchBlocks().isEmpty()) {
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   548
            final Block outerBody = new Block(newTryNode.getToken(), newTryNode.getFinish(), ensureUnconditionalCatch(newTryNode));
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   549
            newTryNode = newTryNode.setBody(lc, outerBody).setCatchBlocks(lc, null);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   550
        }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   551
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   552
        newTryNode = newTryNode.setCatchBlocks(lc, Arrays.asList(catchAll));
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   553
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   554
        /*
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   555
         * Now that the transform is done, we have to go into the try and splice
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   556
         * the finally block in front of any statement that is outside the try
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   557
         */
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   558
        return (TryNode)lc.replace(tryNode, spliceFinally(newTryNode, rethrows.get(0), finallyBody));
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   559
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   560
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   561
    private TryNode ensureUnconditionalCatch(final TryNode tryNode) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   562
        final List<CatchNode> catches = tryNode.getCatches();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   563
        if(catches == null || catches.isEmpty() || catches.get(catches.size() - 1).getExceptionCondition() == null) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   564
            return tryNode;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   565
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   566
        // If the last catch block is conditional, add an unconditional rethrow block
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   567
        final List<Block> newCatchBlocks = new ArrayList<>(tryNode.getCatchBlocks());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   568
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   569
        newCatchBlocks.add(catchAllBlock(tryNode));
28690
78317797ab62 8067139: Finally blocks inlined incorrectly
attila
parents: 27976
diff changeset
   570
        return tryNode.setCatchBlocks(lc, newCatchBlocks);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   571
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   572
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   573
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   574
    public Node leaveVarNode(final VarNode varNode) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   575
        addStatement(varNode);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   576
        if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && lc.getCurrentFunction().isProgram()) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   577
            new ExpressionStatement(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   578
        }
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   579
        return varNode;
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   580
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   581
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   582
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   583
    public Node leaveWhileNode(final WhileNode whileNode) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   584
        final Expression test = whileNode.getTest();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   585
        final Block body = whileNode.getBody();
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   586
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   587
        if (isAlwaysTrue(test)) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   588
            //turn it into a for node without a test.
27817
56f6161c3e55 8057980: let & const: remaining issues with lexical scoping
hannesw
parents: 27206
diff changeset
   589
            final ForNode forNode = (ForNode)new ForNode(whileNode.getLineNumber(), whileNode.getToken(), whileNode.getFinish(), body, 0).accept(this);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   590
            lc.replace(whileNode, forNode);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   591
            return forNode;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   592
        }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   593
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   594
         return addStatement(checkEscape(whileNode));
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   595
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   596
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   597
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   598
    public Node leaveWithNode(final WithNode withNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   599
        return addStatement(withNode);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   600
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   601
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   602
    /**
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   603
     * Given a function node that is a callee in a CallNode, replace it with
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   604
     * the appropriate marker function. This is used by {@link CodeGenerator}
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   605
     * for fast scope calls
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   606
     *
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   607
     * @param function function called by a CallNode
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   608
     * @return transformed node to marker function or identity if not ident/access/indexnode
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   609
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   610
    private static Expression markerFunction(final Expression function) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   611
        if (function instanceof IdentNode) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   612
            return ((IdentNode)function).setIsFunction();
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   613
        } else if (function instanceof BaseNode) {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   614
            return ((BaseNode)function).setIsFunction();
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   615
        }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   616
        return function;
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   617
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   618
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   619
    /**
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   620
     * Calculate a synthetic eval location for a node for the stacktrace, for example src#17<eval>
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   621
     * @param node a node
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   622
     * @return eval location
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   623
     */
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17233
diff changeset
   624
    private String evalLocation(final IdentNode node) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   625
        final Source source = lc.getCurrentFunction().getSource();
20929
f2bd18181940 8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents: 19100
diff changeset
   626
        final int pos = node.position();
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   627
        return new StringBuilder().
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17233
diff changeset
   628
            append(source.getName()).
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   629
            append('#').
20929
f2bd18181940 8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents: 19100
diff changeset
   630
            append(source.getLine(pos)).
f2bd18181940 8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents: 19100
diff changeset
   631
            append(':').
f2bd18181940 8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents: 19100
diff changeset
   632
            append(source.getColumn(pos)).
26504
ed05e2f4c2db 8057930: remove eval ID
attila
parents: 26068
diff changeset
   633
            append("<eval>").
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   634
            toString();
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   635
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   636
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   637
    /**
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   638
     * Check whether a call node may be a call to eval. In that case we
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   639
     * clone the args in order to create the following construct in
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   640
     * {@link CodeGenerator}
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   641
     *
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   642
     * <pre>
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   643
     * if (calledFuntion == buildInEval) {
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   644
     *    eval(cloned arg);
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   645
     * } else {
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   646
     *    cloned arg;
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   647
     * }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   648
     * </pre>
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   649
     *
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   650
     * @param callNode call node to check if it's an eval
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   651
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   652
    private CallNode checkEval(final CallNode callNode) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   653
        if (callNode.getFunction() instanceof IdentNode) {
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   654
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   655
            final List<Expression> args = callNode.getArgs();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   656
            final IdentNode callee = (IdentNode)callNode.getFunction();
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   657
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   658
            // 'eval' call with at least one argument
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   659
            if (args.size() >= 1 && EVAL.symbolName().equals(callee.getName())) {
25423
ca63828cf996 8047067: all eval arguments need to be copied in Lower
attila
parents: 25244
diff changeset
   660
                final List<Expression> evalArgs = new ArrayList<>(args.size());
ca63828cf996 8047067: all eval arguments need to be copied in Lower
attila
parents: 25244
diff changeset
   661
                for(final Expression arg: args) {
ca63828cf996 8047067: all eval arguments need to be copied in Lower
attila
parents: 25244
diff changeset
   662
                    evalArgs.add((Expression)ensureUniqueNamesIn(arg).accept(this));
ca63828cf996 8047067: all eval arguments need to be copied in Lower
attila
parents: 25244
diff changeset
   663
                }
ca63828cf996 8047067: all eval arguments need to be copied in Lower
attila
parents: 25244
diff changeset
   664
                return callNode.setEvalArgs(new CallNode.EvalArgs(evalArgs, evalLocation(callee)));
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   665
            }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   666
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   667
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   668
        return callNode;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   669
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   670
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   671
    /**
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   672
     * Helper that given a loop body makes sure that it is not terminal if it
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   673
     * has a continue that leads to the loop header or to outer loops' loop
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   674
     * headers. This means that, even if the body ends with a terminal
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   675
     * statement, we cannot tag it as terminal
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   676
     *
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   677
     * @param loopBody the loop body to check
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   678
     * @return true if control flow may escape the loop
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   679
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   680
    private static boolean controlFlowEscapes(final LexicalContext lex, final Block loopBody) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   681
        final List<Node> escapes = new ArrayList<>();
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   682
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   683
        loopBody.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   684
            @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   685
            public Node leaveBreakNode(final BreakNode node) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   686
                escapes.add(node);
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   687
                return node;
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   688
            }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   689
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   690
            @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16524
diff changeset
   691
            public Node leaveContinueNode(final ContinueNode node) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   692
                // all inner loops have been popped.
26889
dba314d7a634 8059371: Code duplication in handling of break and continue
attila
parents: 26504
diff changeset
   693
                if (lex.contains(node.getTarget(lex))) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   694
                    escapes.add(node);
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   695
                }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   696
                return node;
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   697
            }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   698
        });
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   699
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   700
        return !escapes.isEmpty();
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   701
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   702
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   703
    @SuppressWarnings("unchecked")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   704
    private <T extends LoopNode> T checkEscape(final T loopNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   705
        final boolean escapes = controlFlowEscapes(lc, loopNode.getBody());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   706
        if (escapes) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21441
diff changeset
   707
            return (T)loopNode.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   708
                setBody(lc, loopNode.getBody().setIsTerminal(lc, false)).
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   709
                setControlFlowEscapes(lc, escapes);
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   710
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   711
        return loopNode;
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   712
    }
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   713
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   714
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
   715
    private Node addStatement(final Statement statement) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17752
diff changeset
   716
        lc.appendStatement(statement);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   717
        return statement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   718
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   720
    private void addStatementEnclosedInBlock(final Statement stmt) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   721
        BlockStatement b = BlockStatement.createReplacement(stmt, Collections.<Statement>singletonList(stmt));
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   722
        if(stmt.isTerminal()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   723
            b = b.setBlock(b.getBlock().setIsTerminal(null, true));
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   724
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   725
        addStatement(b);
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   726
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   727
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   728
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
     * An internal expression has a symbol that is tagged internal. Check if
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
     * this is such a node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   731
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   732
     * @param expression expression to check for internal symbol
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   733
     * @return true if internal, false otherwise
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18848
diff changeset
   735
    private static boolean isInternalExpression(final Expression expression) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   736
        if (!(expression instanceof IdentNode)) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   737
            return false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   738
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   739
        final Symbol symbol = ((IdentNode)expression).getSymbol();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   740
        return symbol != null && symbol.isInternal();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   741
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   742
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   743
    /**
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   744
     * Is this an assignment to the special variable that hosts scripting eval
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   745
     * results, i.e. __return__?
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   746
     *
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   747
     * @param expression expression to check whether it is $evalresult = X
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   748
     * @return true if an assignment to eval result, false otherwise
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   749
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   750
    private static boolean isEvalResultAssignment(final Node expression) {
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24719
diff changeset
   751
        final Node e = expression;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   752
        if (e instanceof BinaryNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   753
            final Node lhs = ((BinaryNode)e).lhs();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   754
            if (lhs instanceof IdentNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   755
                return ((IdentNode)lhs).getName().equals(RETURN.symbolName());
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   756
            }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   757
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   758
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   759
    }
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16188
diff changeset
   760
}