nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
author hannesw
Thu, 04 Sep 2014 15:37:14 +0200
changeset 26377 028dad61662f
parent 26246 66c7c54fe70c
child 26503 3ed48a01100c
permissions -rw-r--r--
8051889: Implement block scoping in symbol assignment and scope computation Reviewed-by: attila, 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.parser;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    28
import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    30
import static jdk.nashorn.internal.codegen.CompilerConstants.PROGRAM;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import static jdk.nashorn.internal.parser.TokenType.CASE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import static jdk.nashorn.internal.parser.TokenType.CATCH;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import static jdk.nashorn.internal.parser.TokenType.COLON;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
import static jdk.nashorn.internal.parser.TokenType.COMMARIGHT;
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
    36
import static jdk.nashorn.internal.parser.TokenType.CONST;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import static jdk.nashorn.internal.parser.TokenType.DECPREFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    39
import static jdk.nashorn.internal.parser.TokenType.ELSE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import static jdk.nashorn.internal.parser.TokenType.EOF;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import static jdk.nashorn.internal.parser.TokenType.EOL;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
import static jdk.nashorn.internal.parser.TokenType.FINALLY;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import static jdk.nashorn.internal.parser.TokenType.IDENT;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
import static jdk.nashorn.internal.parser.TokenType.IF;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    47
import static jdk.nashorn.internal.parser.TokenType.LBRACE;
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
    48
import static jdk.nashorn.internal.parser.TokenType.LET;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    49
import static jdk.nashorn.internal.parser.TokenType.LPAREN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
import static jdk.nashorn.internal.parser.TokenType.RBRACE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import static jdk.nashorn.internal.parser.TokenType.RPAREN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
import static jdk.nashorn.internal.parser.TokenType.TERNARY;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
import static jdk.nashorn.internal.parser.TokenType.WHILE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    57
import java.util.ArrayDeque;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
import java.util.ArrayList;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
    59
import java.util.Collections;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
    60
import java.util.Deque;
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
    61
import java.util.HashMap;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
import java.util.HashSet;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
    63
import java.util.Iterator;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    64
import java.util.List;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
import java.util.Map;
20213
414e257bb93e 8025080: Object literal getter, setter function with number format property name results in ClassFormatError
sundar
parents: 19898
diff changeset
    66
import jdk.internal.dynalink.support.NameCodec;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
    67
import jdk.nashorn.internal.codegen.CompilerConstants;
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
    68
import jdk.nashorn.internal.codegen.Namespace;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
import jdk.nashorn.internal.ir.AccessNode;
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
    70
import jdk.nashorn.internal.ir.BaseNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
import jdk.nashorn.internal.ir.BinaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
import jdk.nashorn.internal.ir.Block;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    73
import jdk.nashorn.internal.ir.BlockLexicalContext;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
    74
import jdk.nashorn.internal.ir.BlockStatement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
import jdk.nashorn.internal.ir.BreakNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
import jdk.nashorn.internal.ir.BreakableNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
import jdk.nashorn.internal.ir.CallNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
import jdk.nashorn.internal.ir.CaseNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
import jdk.nashorn.internal.ir.CatchNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
import jdk.nashorn.internal.ir.ContinueNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
import jdk.nashorn.internal.ir.EmptyNode;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
    82
import jdk.nashorn.internal.ir.Expression;
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
    83
import jdk.nashorn.internal.ir.ExpressionStatement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    84
import jdk.nashorn.internal.ir.ForNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    85
import jdk.nashorn.internal.ir.FunctionNode;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
    86
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    87
import jdk.nashorn.internal.ir.IdentNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    88
import jdk.nashorn.internal.ir.IfNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
import jdk.nashorn.internal.ir.IndexNode;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
    90
import jdk.nashorn.internal.ir.JoinPredecessorExpression;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    91
import jdk.nashorn.internal.ir.LabelNode;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
    92
import jdk.nashorn.internal.ir.LexicalContext;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
import jdk.nashorn.internal.ir.LiteralNode;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    94
import jdk.nashorn.internal.ir.LoopNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
import jdk.nashorn.internal.ir.Node;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
import jdk.nashorn.internal.ir.ObjectNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
import jdk.nashorn.internal.ir.PropertyKey;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
import jdk.nashorn.internal.ir.PropertyNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
import jdk.nashorn.internal.ir.ReturnNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
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
   101
import jdk.nashorn.internal.ir.Statement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
import jdk.nashorn.internal.ir.SwitchNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   103
import jdk.nashorn.internal.ir.TernaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   104
import jdk.nashorn.internal.ir.ThrowNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   105
import jdk.nashorn.internal.ir.TryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   106
import jdk.nashorn.internal.ir.UnaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
import jdk.nashorn.internal.ir.VarNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
import jdk.nashorn.internal.ir.WhileNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
import jdk.nashorn.internal.ir.WithNode;
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   110
import jdk.nashorn.internal.ir.debug.ASTWriter;
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   111
import jdk.nashorn.internal.ir.debug.PrintVisitor;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   112
import jdk.nashorn.internal.runtime.Context;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   113
import jdk.nashorn.internal.runtime.ErrorManager;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   114
import jdk.nashorn.internal.runtime.JSErrorType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
import jdk.nashorn.internal.runtime.ParserException;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   116
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   117
import jdk.nashorn.internal.runtime.ScriptEnvironment;
16245
6a1c6c8bc113 8008371: Fix Dynalink compiler warnings and whitespace
attila
parents: 16239
diff changeset
   118
import jdk.nashorn.internal.runtime.ScriptingFunctions;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   119
import jdk.nashorn.internal.runtime.Source;
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   120
import jdk.nashorn.internal.runtime.Timing;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   121
import jdk.nashorn.internal.runtime.logging.DebugLogger;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   122
import jdk.nashorn.internal.runtime.logging.Loggable;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   123
import jdk.nashorn.internal.runtime.logging.Logger;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   125
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   126
 * Builds the IR.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   127
 */
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   128
@Logger(name="parser")
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   129
public class Parser extends AbstractParser implements Loggable {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   130
    private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName();
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   131
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   132
    /** Current env. */
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   133
    private final ScriptEnvironment env;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   134
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   135
    /** Is scripting mode. */
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   136
    private final boolean scripting;
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
   137
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
   138
    private List<Statement> functionDeclarations;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   139
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   140
    private final BlockLexicalContext lc = new BlockLexicalContext();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   141
    private final Deque<Object> defaultNames = new ArrayDeque<>();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   142
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   143
    /** Namespace for function names where not explicitly given */
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   144
    private final Namespace namespace;
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   145
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   146
    private final DebugLogger log;
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
   147
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   148
    /** to receive line information from Lexer when scanning multine literals. */
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   149
    protected final Lexer.LineInfoReceiver lineInfoReceiver;
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   150
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   151
    private int nextFunctionId;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   152
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   153
    /**
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   154
     * Constructor
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   155
     *
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   156
     * @param env     script environment
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   157
     * @param source  source to parse
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   158
     * @param errors  error manager
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
     */
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   160
    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   161
        this(env, source, errors, env._strict, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   163
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   164
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   165
     * Constructor
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   166
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   167
     * @param env     script environment
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   168
     * @param source  source to parse
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   169
     * @param errors  error manager
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   170
     * @param strict  strict
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   171
     * @param log debug logger if one is needed
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   172
     */
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   173
    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final DebugLogger log) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   174
        this(env, source, errors, strict, FunctionNode.FIRST_FUNCTION_ID, 0, log);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   175
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   176
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   177
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   178
     * Construct a parser.
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   179
     *
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   180
     * @param env     script environment
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   181
     * @param source  source to parse
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   182
     * @param errors  error manager
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   183
     * @param strict  parser created with strict mode enabled.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   184
     * @param nextFunctionId  starting value for assigning new unique ids to function nodes
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   185
     * @param lineOffset line offset to start counting lines from
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   186
     * @param log debug logger if one is needed
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
     */
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   188
    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int nextFunctionId, final int lineOffset, final DebugLogger log) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   189
        super(source, errors, strict, lineOffset);
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   190
        this.env = env;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   191
        this.namespace = new Namespace(env.getNamespace());
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   192
        this.nextFunctionId    = nextFunctionId;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   193
        this.scripting = env._scripting;
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   194
        if (this.scripting) {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   195
            this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   196
                @Override
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   197
                public void lineInfo(final int receiverLine, final int receiverLinePosition) {
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   198
                    // update the parser maintained line information
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   199
                    Parser.this.line = receiverLine;
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18877
diff changeset
   200
                    Parser.this.linePosition = receiverLinePosition;
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   201
                }
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   202
            };
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   203
        } else {
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   204
            // non-scripting mode script can't have multi-line literals
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   205
            this.lineInfoReceiver = null;
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
   206
        }
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   207
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   208
        this.log = log == null ? DebugLogger.DISABLED_LOGGER : log;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   209
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   210
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   211
    @Override
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   212
    public DebugLogger getLogger() {
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   213
        return log;
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   214
    }
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   215
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   216
    @Override
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   217
    public DebugLogger initLogger(final Context context) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   218
        return context.getLogger(this.getClass());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   222
     * Sets the name for the first function. This is only used when reparsing anonymous functions to ensure they can
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   223
     * preserve their already assigned name, as that name doesn't appear in their source text.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   224
     * @param name the name for the first parsed function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   225
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   226
    public void setFunctionName(final String name) {
26243
438aba09d465 8055911: Don't use String.intern for IdentNode
attila
parents: 26068
diff changeset
   227
        defaultNames.push(createIdentNode(0, 0, name));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   229
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   230
    /**
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   231
     * Execute parse and return the resulting function node.
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   232
     * Errors will be thrown and the error manager will contain information
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   233
     * if parsing should fail
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   234
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   235
     * This is the default parse call, which will name the function node
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   236
     * {code :program} {@link CompilerConstants#PROGRAM}
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   237
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   238
     * @return function node resulting from successful parse
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   239
     */
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   240
    public FunctionNode parse() {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   241
        return parse(PROGRAM.symbolName(), 0, source.getLength(), false);
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   242
    }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   243
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   244
    /**
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   245
     * Execute parse and return the resulting function node.
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   246
     * Errors will be thrown and the error manager will contain information
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   247
     * if parsing should fail
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   248
     *
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   249
     * This should be used to create one and only one function node
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   250
     *
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   251
     * @param scriptName name for the script, given to the parsed FunctionNode
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   252
     * @param startPos start position in source
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   253
     * @param len length of parse
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   254
     * @param allowPropertyFunction if true, "get" and "set" are allowed as first tokens of the program, followed by
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   255
     * a property getter or setter function. This is used when reparsing a function that can potentially be defined as a
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   256
     * property getter or setter in an object literal.
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   257
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   258
     * @return function node resulting from successful parse
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   260
    public FunctionNode parse(final String scriptName, final int startPos, final int len, final boolean allowPropertyFunction) {
24764
722a9603b237 8043633: In order to remove global state outside of contexts, make sure Timing class is an instance and not a static global collection of data. Move into Context. Move -Dnashorn.timing to an official logging option.
lagergren
parents: 24759
diff changeset
   261
        final boolean isTimingEnabled = env.isTimingEnabled();
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   262
        final long t0 = isTimingEnabled ? System.nanoTime() : 0L;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   263
        log.info(this, " begin for '", scriptName, "'");
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
   264
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   265
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
            stream = new TokenStream();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   267
            lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   268
            lexer.line = lexer.pendingLine = lineOffset + 1;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   269
            line = lineOffset;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   270
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   271
            // Set up first token (skips opening EOL.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   272
            k = -1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   273
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   274
            // Begin parse.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   275
            return program(scriptName, allowPropertyFunction);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   276
        } catch (final Exception e) {
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   277
            handleParseException(e);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   278
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   279
            return null;
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   280
        } finally {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   281
            final String end = this + " end '" + scriptName + "'";
24764
722a9603b237 8043633: In order to remove global state outside of contexts, make sure Timing class is an instance and not a static global collection of data. Move into Context. Move -Dnashorn.timing to an official logging option.
lagergren
parents: 24759
diff changeset
   282
            if (isTimingEnabled) {
26246
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   283
                env._timing.accumulateTime(toString(), System.nanoTime() - t0);
66c7c54fe70c 8055923: collect timings using System.nanoTime
attila
parents: 26243
diff changeset
   284
                log.info(end, "' in ", Timing.toMillisPrint(System.nanoTime() - t0), " ms");
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   285
            } else {
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
   286
                log.info(end);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   287
            }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   288
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   289
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   290
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   291
    /**
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   292
     * Parse and return the list of function parameter list. A comma
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   293
     * separated list of function parameter identifiers is expected to be parsed.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   294
     * Errors will be thrown and the error manager will contain information
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   295
     * if parsing should fail. This method is used to check if parameter Strings
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   296
     * passed to "Function" constructor is a valid or not.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   297
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   298
     * @return the list of IdentNodes representing the formal parameter list
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   299
     */
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   300
    public List<IdentNode> parseFormalParameterList() {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   301
        try {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   302
            stream = new TokenStream();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   303
            lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   304
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   305
            // Set up first token (skips opening EOL.)
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   306
            k = -1;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   307
            next();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   308
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   309
            return formalParameterList(TokenType.EOF);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   310
        } catch (final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   311
            handleParseException(e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   312
            return null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   313
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   314
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   315
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   316
    /**
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   317
     * Execute parse and return the resulting function node.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   318
     * Errors will be thrown and the error manager will contain information
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   319
     * if parsing should fail. This method is used to check if code String
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   320
     * passed to "Function" constructor is a valid function body or not.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   321
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   322
     * @return function node resulting from successful parse
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   323
     */
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   324
    public FunctionNode parseFunctionBody() {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   325
        try {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   326
            stream = new TokenStream();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   327
            lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   328
            final int functionLine = line;
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   329
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   330
            // Set up first token (skips opening EOL.)
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   331
            k = -1;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   332
            next();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   333
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   334
            // Make a fake token for the function.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   335
            final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   336
            // Set up the function to append elements.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   337
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   338
            FunctionNode function = newFunctionNode(
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   339
                functionToken,
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   340
                new IdentNode(functionToken, Token.descPosition(functionToken), PROGRAM.symbolName()),
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   341
                new ArrayList<IdentNode>(),
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   342
                FunctionNode.Kind.NORMAL,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   343
                functionLine);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   344
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   345
            functionDeclarations = new ArrayList<>();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   346
            sourceElements(false);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   347
            addFunctionDeclarations(function);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   348
            functionDeclarations = null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   349
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   350
            expect(EOF);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   351
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   352
            function.setFinish(source.getLength() - 1);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   353
            function = restoreFunctionNode(function, token); //commit code
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   354
            function = function.setBody(lc, function.getBody().setNeedsScope(lc));
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   355
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   356
            printAST(function);
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   357
            return function;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   358
        } catch (final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   359
            handleParseException(e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   360
            return null;
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   361
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   362
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   363
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   364
    private void handleParseException(final Exception e) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   365
        // Extract message from exception.  The message will be in error
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   366
        // message format.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   367
        String message = e.getMessage();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   368
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   369
        // If empty message.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   370
        if (message == null) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   371
            message = e.toString();
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   372
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   373
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   374
        // Issue message.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   375
        if (e instanceof ParserException) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   376
            errors.error((ParserException)e);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   377
        } else {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   378
            errors.error(message);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   379
        }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   380
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   381
        if (env._dump_on_error) {
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   382
            e.printStackTrace(env.getErr());
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
   383
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   384
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   385
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   386
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   387
     * Skip to a good parsing recovery point.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   389
    private void recover(final Exception e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   390
        if (e != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   391
            // Extract message from exception.  The message will be in error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   392
            // message format.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   393
            String message = e.getMessage();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   394
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   395
            // If empty message.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   396
            if (message == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   397
                message = e.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   399
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   400
            // Issue message.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   401
            if (e instanceof ParserException) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   402
                errors.error((ParserException)e);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   403
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   404
                errors.error(message);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   405
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   406
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   407
            if (env._dump_on_error) {
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   408
                e.printStackTrace(env.getErr());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   409
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   410
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   411
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   412
        // Skip to a recovery point.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   413
loop:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   414
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
            case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   417
                // Can not go any further.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
            case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
            case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
            case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   422
                // Good recovery points.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   423
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
                // So we can recover after EOL.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
                nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   428
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   429
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   430
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   433
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   434
     * Set up a new block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   435
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   436
     * @return New block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   437
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
    private Block newBlock() {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   439
        return lc.push(new Block(token, Token.descPosition(token)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   440
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   441
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   442
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   443
     * Set up a new function block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   444
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   445
     * @param ident Name of function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
     * @return New block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   448
    private FunctionNode newFunctionNode(final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
        // Build function name.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
        final StringBuilder sb = new StringBuilder();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   452
        final FunctionNode parentFunction = lc.getCurrentFunction();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   453
        if (parentFunction != null && !parentFunction.isProgram()) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   454
            sb.append(parentFunction.getName()).append('$');
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   456
22374
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   457
        assert ident.getName() != null;
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   458
        sb.append(ident.getName());
5231ab59e740 8030809: Anonymous functions should not be shown with internal names in script stack trace
sundar
parents: 21868
diff changeset
   459
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16211
diff changeset
   460
        final String name = namespace.uniqueName(sb.toString());
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   461
        assert parentFunction != null || name.equals(PROGRAM.symbolName()) || name.startsWith(RecompilableScriptFunctionData.RECOMPILATION_PREFIX) : "name = " + name;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   462
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   463
        int flags = 0;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   464
        if (isStrictMode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   465
            flags |= FunctionNode.IS_STRICT;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   466
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   467
        if (parentFunction == null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   468
            flags |= FunctionNode.IS_PROGRAM;
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   469
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   470
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
        // Start new block.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   472
        final FunctionNode functionNode =
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   473
            new FunctionNode(
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   474
                source,
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   475
                nextFunctionId++,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   476
                functionLine,
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   477
                token,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   478
                Token.descPosition(token),
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   479
                startToken,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   480
                namespace,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   481
                ident,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   482
                name,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   483
                parameters,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   484
                kind,
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 24994
diff changeset
   485
                flags);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   486
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   487
        lc.push(functionNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   488
        // Create new block, and just put it on the context stack, restoreFunctionNode() will associate it with the
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   489
        // FunctionNode.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   490
        newBlock();
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   491
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   492
        return functionNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   493
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   494
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   495
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   496
     * Restore the current block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   497
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   498
    private Block restoreBlock(final Block block) {
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   499
        return lc.pop(block);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   500
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   501
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   502
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   503
    private FunctionNode restoreFunctionNode(final FunctionNode functionNode, final long lastToken) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   504
        final Block newBody = restoreBlock(lc.getFunctionBody(functionNode));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   505
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   506
        return lc.pop(functionNode).
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   507
            setBody(lc, newBody).
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   508
            setLastToken(lc, lastToken).
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   509
            setState(lc, errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   510
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   512
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
     * Get the statements in a block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   514
     * @return Block statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   516
    private Block getBlock(final boolean needsBraces) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   517
        // Set up new block. Captures LBRACE.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   518
        Block newBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   519
        try {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   520
            // Block opening brace.
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   521
            if (needsBraces) {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   522
                expect(LBRACE);
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   523
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   524
            // Accumulate block statements.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   525
            statementList();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   526
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   527
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   528
            newBlock = restoreBlock(newBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   529
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
   531
        final int possibleEnd = Token.descPosition(token) + Token.descLength(token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   532
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
        // Block closing brace.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
        if (needsBraces) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   535
            expect(RBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   536
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   537
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
        newBlock.setFinish(possibleEnd);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   540
        return newBlock;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   541
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   542
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   543
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   544
     * Get all the statements generated by a single statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
     * @return Statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   547
    private Block getStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   548
        if (type == LBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   549
            return getBlock(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   550
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   551
        // Set up new block. Captures first token.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   552
        Block newBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   553
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   554
            statement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   555
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   556
            newBlock = restoreBlock(newBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   557
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   558
        return newBlock;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   559
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   560
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   561
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   562
     * Detect calls to special functions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   563
     * @param ident Called function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   564
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   565
    private void detectSpecialFunction(final IdentNode ident) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   566
        final String name = ident.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   568
        if (EVAL.symbolName().equals(name)) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17249
diff changeset
   569
            markEval(lc);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   570
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   571
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   572
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   573
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
     * Detect use of special properties.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
     * @param ident Referenced property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   576
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   577
    private void detectSpecialProperty(final IdentNode ident) {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   578
        if (isArguments(ident)) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   579
            lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_ARGUMENTS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   580
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   581
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   582
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   583
    private boolean useBlockScope() {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   584
        return env._es6;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   585
    }
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   586
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   587
    private static boolean isArguments(final String name) {
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   588
        return ARGUMENTS_NAME.equals(name);
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   589
    }
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   590
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   591
    private static boolean isArguments(final IdentNode ident) {
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   592
        return isArguments(ident.getName());
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   593
    }
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
   594
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
     * Tells whether a IdentNode can be used as L-value of an assignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
     * @param ident IdentNode to be checked
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   599
     * @return whether the ident can be used as L-value
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
    private static boolean checkIdentLValue(final IdentNode ident) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   602
        return Token.descType(ident.getToken()).getKind() != TokenKind.KEYWORD;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   603
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   604
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   605
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   606
     * Verify an assignment expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   607
     * @param op  Operation token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   608
     * @param lhs Left hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   609
     * @param rhs Right hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   610
     * @return Verified expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   611
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   612
    private Expression verifyAssignment(final long op, final Expression lhs, final Expression rhs) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   613
        final TokenType opType = Token.descType(op);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   614
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   615
        switch (opType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   616
        case ASSIGN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   617
        case ASSIGN_ADD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   618
        case ASSIGN_BIT_AND:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
        case ASSIGN_BIT_OR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   620
        case ASSIGN_BIT_XOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   621
        case ASSIGN_DIV:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   622
        case ASSIGN_MOD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   623
        case ASSIGN_MUL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   624
        case ASSIGN_SAR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   625
        case ASSIGN_SHL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   626
        case ASSIGN_SHR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   627
        case ASSIGN_SUB:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   628
            if (!(lhs instanceof AccessNode ||
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   629
                  lhs instanceof IndexNode ||
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   630
                  lhs instanceof IdentNode)) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
   631
                return referenceError(lhs, rhs, env._early_lvalue_error);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   632
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   633
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   634
            if (lhs instanceof IdentNode) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
   635
                if (!checkIdentLValue((IdentNode)lhs)) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
   636
                    return referenceError(lhs, rhs, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   637
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   638
                verifyStrictIdent((IdentNode)lhs, "assignment");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   639
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   640
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   641
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   642
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   643
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   644
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   645
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   646
        // Build up node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   647
        if(BinaryNode.isLogical(opType)) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   648
            return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   649
        }
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   650
        return new BinaryNode(op, lhs, rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   651
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   652
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
   653
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   654
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   655
     * Reduce increment/decrement to simpler operations.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   656
     * @param firstToken First token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   657
     * @param tokenType  Operation token (INCPREFIX/DEC.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   658
     * @param expression Left hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   659
     * @param isPostfix  Prefix or postfix.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   660
     * @return           Reduced expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   661
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   662
    private static UnaryNode incDecExpression(final long firstToken, final TokenType tokenType, final Expression expression, final boolean isPostfix) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   663
        if (isPostfix) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   664
            return new UnaryNode(Token.recast(firstToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX), expression.getStart(), Token.descPosition(firstToken) + Token.descLength(firstToken), expression);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   665
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   666
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   667
        return new UnaryNode(firstToken, expression);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   668
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   669
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   670
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   671
     * -----------------------------------------------------------------------
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   672
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   673
     * Grammar based on
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   674
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   675
     *      ECMAScript Language Specification
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   676
     *      ECMA-262 5th Edition / December 2009
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   677
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   678
     * -----------------------------------------------------------------------
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   679
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   680
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   681
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   682
     * Program :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   683
     *      SourceElements?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   684
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   685
     * See 14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   686
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   687
     * Parse the top level script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   688
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   689
    private FunctionNode program(final String scriptName, final boolean allowPropertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   690
        // Make a pseudo-token for the script holding its start and length.
24994
92a19723a5ac 8047035: (function() "hello")() crashes in Lexer with jdk9
sundar
parents: 24769
diff changeset
   691
        final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   692
        final int  functionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   693
        // Set up the script to append elements.
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
   694
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   695
        FunctionNode script = newFunctionNode(
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   696
            functionToken,
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   697
            new IdentNode(functionToken, Token.descPosition(functionToken), scriptName),
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   698
            new ArrayList<IdentNode>(),
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   699
            FunctionNode.Kind.SCRIPT,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   700
            functionLine);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   701
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   702
        // If ES6 block scope is enabled add a per-script block for top-level LET and CONST declarations.
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   703
        final int startLine = start;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   704
        Block outer = useBlockScope() ? newBlock() : null;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   705
        functionDeclarations = new ArrayList<>();
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   706
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   707
        try {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   708
            sourceElements(allowPropertyFunction);
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   709
            addFunctionDeclarations(script);
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   710
        } finally {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   711
            if (outer != null) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   712
                outer = restoreBlock(outer);
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   713
                appendStatement(new BlockStatement(startLine, outer));
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   714
            }
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   715
        }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   716
        functionDeclarations = null;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   717
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   718
        expect(EOF);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   719
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   720
        script.setFinish(source.getLength() - 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   721
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   722
        script = restoreFunctionNode(script, token); //commit code
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   723
        script = script.setBody(lc, script.getBody().setNeedsScope(lc));
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17257
diff changeset
   724
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   725
        return script;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   727
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   728
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
     * Directive value or null if statement is not a directive.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   731
     * @param stmt Statement to be checked
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   732
     * @return Directive value if the given statement is a directive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   733
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
    private String getDirective(final Node stmt) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   735
        if (stmt instanceof ExpressionStatement) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   736
            final Node expr = ((ExpressionStatement)stmt).getExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   737
            if (expr instanceof LiteralNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   738
                final LiteralNode<?> lit = (LiteralNode<?>)expr;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   739
                final long litToken = lit.getToken();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   740
                final TokenType tt = Token.descType(litToken);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   741
                // A directive is either a string or an escape string
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   742
                if (tt == TokenType.STRING || tt == TokenType.ESCSTRING) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   743
                    // Make sure that we don't unescape anything. Return as seen in source!
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   744
                    return source.getString(lit.getStart(), Token.descLength(litToken));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   745
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   746
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   747
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   748
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   749
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   750
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   751
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   752
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   753
     * SourceElements :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   754
     *      SourceElement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   755
     *      SourceElements SourceElement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   756
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   757
     * See 14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   758
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   759
     * Parse the elements of the script or function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   760
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   761
    private void sourceElements(final boolean shouldAllowPropertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   762
        List<Node>    directiveStmts        = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   763
        boolean       checkDirective        = true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   764
        boolean       allowPropertyFunction = shouldAllowPropertyFunction;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   765
        final boolean oldStrictMode         = isStrictMode;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   766
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   767
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   768
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   769
            // If is a script, then process until the end of the script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   770
            while (type != EOF) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   771
                // Break if the end of a code block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   772
                if (type == RBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   773
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   774
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   775
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   776
                try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   777
                    // Get the next element.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   778
                    statement(true, allowPropertyFunction);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   779
                    allowPropertyFunction = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   780
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   781
                    // check for directive prologues
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   782
                    if (checkDirective) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   783
                        // skip any debug statement like line number to get actual first line
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   784
                        final Node lastStatement = lc.getLastStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   785
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   786
                        // get directive prologue, if any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   787
                        final String directive = getDirective(lastStatement);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   788
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   789
                        // If we have seen first non-directive statement,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   790
                        // no more directive statements!!
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   791
                        checkDirective = directive != null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   792
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   793
                        if (checkDirective) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   794
                            if (!oldStrictMode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   795
                                if (directiveStmts == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   796
                                    directiveStmts = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   797
                                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   798
                                directiveStmts.add(lastStatement);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   799
                            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   800
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   801
                            // handle use strict directive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   802
                            if ("use strict".equals(directive)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   803
                                isStrictMode = true;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   804
                                final FunctionNode function = lc.getCurrentFunction();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   805
                                lc.setFlag(lc.getCurrentFunction(), FunctionNode.IS_STRICT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   806
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   807
                                // We don't need to check these, if lexical environment is already strict
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   808
                                if (!oldStrictMode && directiveStmts != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   809
                                    // check that directives preceding this one do not violate strictness
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   810
                                    for (final Node statement : directiveStmts) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   811
                                        // the get value will force unescape of preceeding
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   812
                                        // escaped string directives
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   813
                                        getValue(statement.getToken());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   814
                                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   815
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   816
                                    // verify that function name as well as parameter names
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16196
diff changeset
   817
                                    // satisfy strict mode restrictions.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   818
                                    verifyStrictIdent(function.getIdent(), "function name");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   819
                                    for (final IdentNode param : function.getParameters()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   820
                                        verifyStrictIdent(param, "function parameter");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   821
                                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   822
                                }
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   823
                            } else if (Context.DEBUG) {
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   824
                                final int flag = FunctionNode.getDirectiveFlag(directive);
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   825
                                if (flag != 0) {
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   826
                                    final FunctionNode function = lc.getCurrentFunction();
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   827
                                    lc.setFlag(function, flag);
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
   828
                                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   829
                            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   830
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   831
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   832
                } catch (final Exception e) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   833
                    //recover parsing
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   834
                    recover(e);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   835
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   836
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   837
                // No backtracking from here on.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   838
                stream.commit(k);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   839
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   840
        } finally {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   841
            isStrictMode = oldStrictMode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   842
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   843
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   844
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   845
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   846
     * Statement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   847
     *      Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   848
     *      VariableStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   849
     *      EmptyStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   850
     *      ExpressionStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   851
     *      IfStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   852
     *      IterationStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   853
     *      ContinueStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   854
     *      BreakStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   855
     *      ReturnStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   856
     *      WithStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   857
     *      LabelledStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   858
     *      SwitchStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   859
     *      ThrowStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   860
     *      TryStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   861
     *      DebuggerStatement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   862
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   863
     * see 12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   864
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   865
     * Parse any of the basic statement types.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   866
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   867
    private void statement() {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   868
        statement(false, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   869
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   870
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   871
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   872
     * @param topLevel does this statement occur at the "top level" of a script or a function?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   873
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   874
    private void statement(final boolean topLevel, final boolean allowPropertyFunction) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   875
        if (type == FUNCTION) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   876
            // As per spec (ECMA section 12), function declarations as arbitrary statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   877
            // is not "portable". Implementation can issue a warning or disallow the same.
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   878
            functionExpression(true, topLevel);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   879
            return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   880
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   881
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   882
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   883
        case LBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   884
            block();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   885
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   886
        case VAR:
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   887
            variableStatement(type, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   888
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   889
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   890
            emptyStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   891
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   892
        case IF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   893
            ifStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   894
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   895
        case FOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   896
            forStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   897
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   898
        case WHILE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
            whileStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   900
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   901
        case DO:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   902
            doStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   903
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   904
        case CONTINUE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   905
            continueStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   906
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   907
        case BREAK:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   908
            breakStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   909
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   910
        case RETURN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   911
            returnStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   912
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   913
        case YIELD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   914
            yieldStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   915
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   916
        case WITH:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   917
            withStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   918
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   919
        case SWITCH:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   920
            switchStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   921
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   922
        case THROW:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   923
            throwStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   924
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   925
        case TRY:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   926
            tryStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   927
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   928
        case DEBUGGER:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   929
            debuggerStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   930
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   931
        case RPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   932
        case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   933
        case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   934
            expect(SEMICOLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   935
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   936
        default:
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   937
            if (useBlockScope() && (type == LET || type == CONST)) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   938
                variableStatement(type, true);
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   939
                break;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   940
            }
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
   941
            if (env._const_as_var && type == CONST) {
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
   942
                variableStatement(TokenType.VAR, true);
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
   943
                break;
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
   944
            }
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
   945
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   946
            if (type == IDENT || isNonStrictModeIdent()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   947
                if (T(k + 1) == COLON) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   948
                    labelStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   949
                    return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   950
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   951
                if(allowPropertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   952
                    final String ident = (String)getValue();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   953
                    final long propertyToken = token;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   954
                    final int propertyLine = line;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   955
                    if("get".equals(ident)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   956
                        next();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   957
                        addPropertyFunctionStatement(propertyGetterFunction(propertyToken, propertyLine));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   958
                        return;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   959
                    } else if("set".equals(ident)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   960
                        next();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   961
                        addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   962
                        return;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   963
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   964
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   965
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   966
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   967
            expressionStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   968
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   969
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   970
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   971
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   972
    private void addPropertyFunctionStatement(final PropertyFunction propertyFunction) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   973
        final FunctionNode fn = propertyFunction.functionNode;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   974
        functionDeclarations.add(new ExpressionStatement(fn.getLineNumber(), fn.getToken(), finish, fn));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   975
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
   976
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   977
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   978
     * block :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   979
     *      { StatementList? }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   980
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   981
     * see 12.1
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   982
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   983
     * Parse a statement block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   984
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   985
    private void block() {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
   986
        appendStatement(new BlockStatement(line, getBlock(true)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   987
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   988
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   989
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   990
     * StatementList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   991
     *      Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   992
     *      StatementList Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   993
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   994
     * See 12.1
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   995
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   996
     * Parse a list of statements.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   997
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   998
    private void statementList() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   999
        // Accumulate statements until end of list. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1000
loop:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1001
        while (type != EOF) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1002
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1003
            case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1004
            case CASE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1005
            case DEFAULT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1006
            case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1007
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1008
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1009
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1010
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1011
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1012
            // Get next statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1013
            statement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1014
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1015
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1016
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1017
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1018
     * Make sure that in strict mode, the identifier name used is allowed.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1019
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1020
     * @param ident         Identifier that is verified
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1021
     * @param contextString String used in error message to give context to the user
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1022
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1023
    private void verifyStrictIdent(final IdentNode ident, final String contextString) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1024
        if (isStrictMode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1025
            switch (ident.getName()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1026
            case "eval":
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1027
            case "arguments":
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1028
                throw error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1029
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1030
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1031
            }
20571
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1032
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1033
            if (ident.isFutureStrictName()) {
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1034
                throw error(AbstractParser.message("strict.name", ident.getName(), contextString), ident.getToken());
f52b0abf5d88 8026039: future strict names are allowed as function name and argument name of a strict function
sundar
parents: 20559
diff changeset
  1035
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1036
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1037
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1038
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1039
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1040
     * VariableStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1041
     *      var VariableDeclarationList ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1042
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1043
     * VariableDeclarationList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1044
     *      VariableDeclaration
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1045
     *      VariableDeclarationList , VariableDeclaration
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1046
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1047
     * VariableDeclaration :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1048
     *      Identifier Initializer?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1049
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1050
     * Initializer :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1051
     *      = AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1052
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1053
     * See 12.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1054
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1055
     * Parse a VAR statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1056
     * @param isStatement True if a statement (not used in a FOR.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1057
     */
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1058
    private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1059
        // VAR tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1060
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1061
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1062
        final List<VarNode> vars = new ArrayList<>();
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1063
        int varFlags = VarNode.IS_STATEMENT;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1064
        if (varType == LET) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1065
            varFlags |= VarNode.IS_LET;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1066
        } else if (varType == CONST) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1067
            varFlags |= VarNode.IS_CONST;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1068
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1069
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1070
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1071
            // Get starting token.
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
  1072
            final int  varLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1073
            final long varToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1074
            // Get name of var.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1075
            final IdentNode name = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1076
            verifyStrictIdent(name, "variable name");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1077
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1078
            // Assume no init.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1079
            Expression init = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1080
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1081
            // Look for initializer assignment.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1082
            if (type == ASSIGN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1083
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1084
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1085
                // Get initializer expression. Suppress IN if not statement.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1086
                defaultNames.push(name);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1087
                try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1088
                    init = assignmentExpression(!isStatement);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1089
                } finally {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1090
                    defaultNames.pop();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  1091
                }
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1092
            } else if (varType == CONST) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1093
                throw error(AbstractParser.message("missing.const.assignment", name.getName()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1094
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1095
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1096
            // Allocate var node.
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1097
            final VarNode var = new VarNode(varLine, varToken, finish, name.setIsDeclaredHere(), init, varFlags);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1098
            vars.add(var);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1099
            appendStatement(var);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1100
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1101
            if (type != COMMARIGHT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1102
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1103
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1104
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1105
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1106
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1107
        // If is a statement then handle end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1108
        if (isStatement) {
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
  1109
            final boolean semicolon = type == SEMICOLON;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1110
            endOfLine();
16153
60de45bf54b0 8005703: Offsets miscalculated for blocks
jlaskey
parents: 16151
diff changeset
  1111
            if (semicolon) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1112
                lc.getCurrentBlock().setFinish(finish);
16153
60de45bf54b0 8005703: Offsets miscalculated for blocks
jlaskey
parents: 16151
diff changeset
  1113
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1114
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1115
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1116
        return vars;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1117
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1118
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1119
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1120
     * EmptyStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1121
     *      ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1122
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1123
     * See 12.3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1124
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1125
     * Parse an empty statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1126
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1127
    private void emptyStatement() {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  1128
        if (env._empty_statements) {
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
  1129
            appendStatement(new EmptyNode(line, token, Token.descPosition(token) + Token.descLength(token)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1130
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1131
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1132
        // SEMICOLON checked in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1133
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1134
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1135
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1136
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1137
     * ExpressionStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1138
     *      Expression ; // [lookahead ~( or  function )]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1139
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1140
     * See 12.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1141
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1142
     * Parse an expression used in a statement block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1143
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1144
    private void expressionStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1145
        // Lookahead checked in caller.
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
  1146
        final int  expressionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1147
        final long expressionToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1148
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1149
        // Get expression and add as statement.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1150
        final Expression expression = expression();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1151
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1152
        ExpressionStatement expressionStatement = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1153
        if (expression != null) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1154
            expressionStatement = new ExpressionStatement(expressionLine, expressionToken, finish, expression);
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1155
            appendStatement(expressionStatement);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1156
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1157
            expect(null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1158
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1159
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1160
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1161
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1162
        if (expressionStatement != null) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1163
            expressionStatement.setFinish(finish);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1164
            lc.getCurrentBlock().setFinish(finish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1165
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1166
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1167
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1168
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1169
     * IfStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1170
     *      if ( Expression ) Statement else Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1171
     *      if ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1172
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1173
     * See 12.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1174
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1175
     * Parse an IF statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1176
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1177
    private void ifStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1178
        // Capture IF token.
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
  1179
        final int  ifLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1180
        final long ifToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1181
         // IF tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1182
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1183
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1184
        expect(LPAREN);
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1185
        final Expression test = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1186
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1187
        final Block pass = getStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1188
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1189
        Block fail = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1190
        if (type == ELSE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1191
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1192
            fail = getStatement();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1193
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1194
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
  1195
        appendStatement(new IfNode(ifLine, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1196
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1197
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1198
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1199
     * ... IterationStatement:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1200
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1201
     *           for ( Expression[NoIn]?; Expression? ; Expression? ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1202
     *           for ( var VariableDeclarationList[NoIn]; Expression? ; Expression? ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1203
     *           for ( LeftHandSideExpression in Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1204
     *           for ( var VariableDeclaration[NoIn] in Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1205
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1206
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1207
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1208
     * Parse a FOR statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1209
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1210
    private void forStatement() {
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1211
        // When ES6 for-let is enabled we create a container block to capture the LET.
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1212
        final int startLine = start;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1213
        Block outer = useBlockScope() ? newBlock() : null;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1214
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1215
        // Create FOR node, capturing FOR token.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1216
        ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, ForNode.IS_FOR);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1217
        lc.push(forNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1218
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1219
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1220
            // FOR tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1221
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1222
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1223
            // Nashorn extension: for each expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1224
            // iterate property values rather than property names.
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  1225
            if (!env._no_syntax_extensions && type == IDENT && "each".equals(getValue())) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1226
                forNode = forNode.setIsForEach(lc);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1227
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1228
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1229
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1230
            expect(LPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1231
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1232
            List<VarNode> vars = null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1234
            switch (type) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1235
            case VAR:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1236
                // Var statements captured in for outer block.
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1237
                vars = variableStatement(type, false);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1238
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1239
            case SEMICOLON:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1240
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1241
            default:
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1242
                if (useBlockScope() && (type == LET || type == CONST)) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1243
                    // LET/CONST captured in container block created above.
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1244
                    vars = variableStatement(type, false);
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1245
                    break;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1246
                }
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1247
                if (env._const_as_var && type == CONST) {
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1248
                    // Var statements captured in for outer block.
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1249
                    vars = variableStatement(TokenType.VAR, false);
24279
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1250
                    break;
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1251
                }
33b0fbd03872 8027933: Add --const-as-var option
sundar
parents: 23766
diff changeset
  1252
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1253
                final Expression expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1254
                forNode = forNode.setInit(lc, expression);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1255
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1256
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1257
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1258
            switch (type) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1259
            case SEMICOLON:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1260
                // for (init; test; modify)
18843
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1261
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1262
                // for each (init; test; modify) is invalid
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1263
                if (forNode.isForEach()) {
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1264
                    throw error(AbstractParser.message("for.each.without.in"), token);
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1265
                }
eea6d1b8263e 8019805: for each (init; test; modify) is invalid
sundar
parents: 18632
diff changeset
  1266
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1267
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1268
                if (type != SEMICOLON) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1269
                    forNode = forNode.setTest(lc, joinPredecessorExpression());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1270
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1271
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1272
                if (type != RPAREN) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1273
                    forNode = forNode.setModify(lc, joinPredecessorExpression());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1274
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1275
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1276
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1277
            case IN:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1278
                forNode = forNode.setIsForIn(lc).setTest(lc, new JoinPredecessorExpression());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1279
                if (vars != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1280
                    // for (var i in obj)
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1281
                    if (vars.size() == 1) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1282
                        forNode = forNode.setInit(lc, new IdentNode(vars.get(0).getName()));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1283
                    } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1284
                        // for (var i, j in obj) is invalid
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1285
                        throw error(AbstractParser.message("many.vars.in.for.in.loop"), vars.get(1).getToken());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1286
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1287
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1288
                } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1289
                    // for (expr in obj)
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1290
                    final Node init = forNode.getInit();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1291
                    assert init != null : "for..in init expression can not be null here";
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1292
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1293
                    // check if initial expression is a valid L-value
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1294
                    if (!(init instanceof AccessNode ||
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1295
                          init instanceof IndexNode ||
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1296
                          init instanceof IdentNode)) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1297
                        throw error(AbstractParser.message("not.lvalue.for.in.loop"), init.getToken());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1298
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1299
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1300
                    if (init instanceof IdentNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1301
                        if (!checkIdentLValue((IdentNode)init)) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1302
                            throw error(AbstractParser.message("not.lvalue.for.in.loop"), init.getToken());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1303
                        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1304
                        verifyStrictIdent((IdentNode)init, "for-in iterator");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1305
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1306
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1307
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1308
                next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1309
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1310
                // Get the collection expression.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1311
                forNode = forNode.setModify(lc, joinPredecessorExpression());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1312
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1313
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1314
            default:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1315
                expect(SEMICOLON);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1316
                break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1317
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1318
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1319
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1320
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1321
            // Set the for body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1322
            final Block body = getStatement();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1323
            forNode = forNode.setBody(lc, body);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1324
            forNode.setFinish(body.getFinish());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1325
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1326
            appendStatement(forNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1327
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1328
            lc.pop(forNode);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1329
            if (outer != null) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1330
                outer.setFinish(forNode.getFinish());
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1331
                outer = restoreBlock(outer);
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1332
                appendStatement(new BlockStatement(startLine, outer));
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1333
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1334
        }
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1335
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1336
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1337
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1338
     * ... IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1339
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1340
     *           Expression[NoIn]?; Expression? ; Expression?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1341
     *           var VariableDeclarationList[NoIn]; Expression? ; Expression?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1342
     *           LeftHandSideExpression in Expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1343
     *           var VariableDeclaration[NoIn] in Expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1344
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1345
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1346
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1347
     * Parse the control section of a FOR statement.  Also used for
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1348
     * comprehensions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1349
     * @param forNode Owning FOR.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1350
     */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1351
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1352
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1353
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1354
     * ...IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1355
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1356
     *           while ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1357
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1358
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1359
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1360
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1361
     * Parse while statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1362
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1363
    private void whileStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1364
        // Capture WHILE token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1365
        final long whileToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1366
        // WHILE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1367
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1368
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1369
        // Construct WHILE node.
21868
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1370
        WhileNode whileNode = new WhileNode(line, whileToken, Token.descPosition(whileToken), false);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1371
        lc.push(whileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1372
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1373
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1374
            expect(LPAREN);
21868
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1375
            final int whileLine = line;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1376
            final JoinPredecessorExpression test = joinPredecessorExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1377
            expect(RPAREN);
21868
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1378
            final Block body = getStatement();
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1379
            appendStatement(whileNode =
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1380
                new WhileNode(whileLine, whileToken, finish, false).
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1381
                    setTest(lc, test).
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1382
                    setBody(lc, body));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1383
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1384
            lc.pop(whileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1385
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1386
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1387
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1388
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1389
     * ...IterationStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1390
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1391
     *           do Statement while( Expression ) ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1392
     *           ...
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1393
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1394
     * See 12.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1395
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1396
     * Parse DO WHILE statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1397
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1398
    private void doStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1399
        // Capture DO token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1400
        final long doToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1401
        // DO tested in the caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1402
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1403
21868
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1404
        WhileNode doWhileNode = new WhileNode(-1, doToken, Token.descPosition(doToken), true);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1405
        lc.push(doWhileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1406
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1407
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1408
           // Get DO body.
21868
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1409
            final Block body = getStatement();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1410
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1411
            expect(WHILE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1412
            expect(LPAREN);
21868
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1413
            final int doLine = line;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1414
            final JoinPredecessorExpression test = joinPredecessorExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1415
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1416
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1417
            if (type == SEMICOLON) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1418
                endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1419
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1420
            doWhileNode.setFinish(finish);
21868
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1421
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1422
            //line number is last
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1423
            appendStatement(doWhileNode =
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1424
                new WhileNode(doLine, doToken, finish, true).
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1425
                    setBody(lc, body).
f3cd4fa7f8b9 8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
lagergren
parents: 20938
diff changeset
  1426
                    setTest(lc, test));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1427
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1428
            lc.pop(doWhileNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1429
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1430
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1431
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1432
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1433
     * ContinueStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1434
     *      continue Identifier? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1435
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1436
     * See 12.7
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1437
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1438
     * Parse CONTINUE statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1439
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1440
    private void continueStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1441
        // Capture CONTINUE token.
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
  1442
        final int  continueLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1443
        final long continueToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1444
        // CONTINUE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1445
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1446
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1447
        LabelNode labelNode = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1448
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1449
        // SEMICOLON or label.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1450
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1451
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1452
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1453
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  1454
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1455
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1456
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1457
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1458
            final IdentNode ident = getIdent();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1459
            labelNode = lc.findLabel(ident.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1460
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1461
            if (labelNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1462
                throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1463
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1464
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1465
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1466
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1467
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1468
        final String labelName = labelNode == null ? null : labelNode.getLabelName();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1469
        final LoopNode targetNode = lc.getContinueTo(labelName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1470
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1471
        if (targetNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1472
            throw error(AbstractParser.message("illegal.continue.stmt"), continueToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1473
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1474
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1475
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1476
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1477
        // Construct and add CONTINUE node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1478
        appendStatement(new ContinueNode(continueLine, continueToken, finish, labelName));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1479
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1480
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1481
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1482
     * BreakStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1483
     *      break Identifier? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1484
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1485
     * See 12.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1486
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1487
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1488
    private void breakStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1489
        // Capture BREAK token.
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
  1490
        final int  breakLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1491
        final long breakToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1492
        // BREAK tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1493
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1494
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1495
        LabelNode labelNode = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1496
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1497
        // SEMICOLON or label.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1498
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1499
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1500
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1501
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  1502
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1503
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1504
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1505
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1506
            final IdentNode ident = getIdent();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1507
            labelNode = lc.findLabel(ident.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1508
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1509
            if (labelNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1510
                throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1511
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1512
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1513
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1514
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1515
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1516
        //either an explicit label - then get its node or just a "break" - get first breakable
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1517
        //targetNode is what we are breaking out from.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1518
        final String labelName = labelNode == null ? null : labelNode.getLabelName();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1519
        final BreakableNode targetNode = lc.getBreakable(labelName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1520
        if (targetNode == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1521
            throw error(AbstractParser.message("illegal.break.stmt"), breakToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1522
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1523
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1524
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1525
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1526
        // Construct and add BREAK node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1527
        appendStatement(new BreakNode(breakLine, breakToken, finish, labelName));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1528
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1529
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1530
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1531
     * ReturnStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1532
     *      return Expression? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1533
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1534
     * See 12.9
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1535
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1536
     * Parse RETURN statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1537
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1538
    private void returnStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1539
        // check for return outside function
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1540
        if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1541
            throw error(AbstractParser.message("invalid.return"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1542
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1543
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1544
        // Capture RETURN token.
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
  1545
        final int  returnLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1546
        final long returnToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1547
        // RETURN tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1548
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1549
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1550
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1551
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1552
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1553
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1554
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1555
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1556
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  1557
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1558
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1559
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1560
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1561
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1562
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1563
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1564
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1565
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1566
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1567
        // Construct and add RETURN node.
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
  1568
        appendStatement(new ReturnNode(returnLine, returnToken, finish, expression));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1569
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1570
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1571
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1572
     * YieldStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1573
     *      yield Expression? ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1574
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1575
     * JavaScript 1.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1576
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1577
     * Parse YIELD statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1578
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1579
    private void yieldStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1580
        // Capture YIELD token.
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
  1581
        final int  yieldLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1582
        final long yieldToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1583
        // YIELD tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1584
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1585
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1586
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1587
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1588
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1589
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1590
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1591
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1592
        case EOL:
18625
13558072545a 8019473: Parser issues related to functions and blocks
sundar
parents: 18335
diff changeset
  1593
        case EOF:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1594
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1595
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1596
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1597
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1598
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1599
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1600
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1601
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1602
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1603
        // Construct and add YIELD node.
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
  1604
        appendStatement(new ReturnNode(yieldLine, yieldToken, finish, expression));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1605
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1606
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1607
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1608
     * WithStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1609
     *      with ( Expression ) Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1610
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1611
     * See 12.10
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1612
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1613
     * Parse WITH statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1614
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1615
    private void withStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1616
        // Capture WITH token.
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
  1617
        final int  withLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1618
        final long withToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1619
        // WITH tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1620
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1621
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1622
        // ECMA 12.10.1 strict mode restrictions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1623
        if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1624
            throw error(AbstractParser.message("strict.no.with"), withToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1625
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1626
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1627
        // Get WITH expression.
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
  1628
        WithNode withNode = new WithNode(withLine, withToken, finish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1629
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1630
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1631
            lc.push(withNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1632
            expect(LPAREN);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1633
            withNode = withNode.setExpression(lc, expression());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1634
            expect(RPAREN);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1635
            withNode = withNode.setBody(lc, getStatement());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1636
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1637
            lc.pop(withNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1638
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1639
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1640
        appendStatement(withNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1641
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1642
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1643
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1644
     * SwitchStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1645
     *      switch ( Expression ) CaseBlock
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1646
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1647
     * CaseBlock :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1648
     *      { CaseClauses? }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1649
     *      { CaseClauses? DefaultClause CaseClauses }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1650
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1651
     * CaseClauses :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1652
     *      CaseClause
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1653
     *      CaseClauses CaseClause
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1654
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1655
     * CaseClause :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1656
     *      case Expression : StatementList?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1657
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1658
     * DefaultClause :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1659
     *      default : StatementList?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1660
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1661
     * See 12.11
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1662
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1663
     * Parse SWITCH statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1664
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1665
    private void switchStatement() {
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
  1666
        final int  switchLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1667
        final long switchToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1668
        // SWITCH tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1669
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1670
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1671
        // Create and add switch statement.
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  1672
        SwitchNode switchNode = new SwitchNode(switchLine, switchToken, Token.descPosition(switchToken), null, new ArrayList<CaseNode>(), null);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1673
        lc.push(switchNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1674
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1675
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1676
            expect(LPAREN);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1677
            switchNode = switchNode.setExpression(lc, expression());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1678
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1679
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1680
            expect(LBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1681
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1682
            // Prepare to accumulate cases.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1683
            final List<CaseNode> cases = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1684
            CaseNode defaultCase = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1685
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1686
            while (type != RBRACE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1687
                // Prepare for next case.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1688
                Expression caseExpression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1689
                final long caseToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1690
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1691
                switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1692
                case CASE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1693
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1694
                    caseExpression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1695
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1696
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1697
                case DEFAULT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1698
                    if (defaultCase != null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1699
                        throw error(AbstractParser.message("duplicate.default.in.switch"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1700
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1701
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1702
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1703
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1704
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1705
                    // Force an error.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1706
                    expect(CASE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1707
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1708
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1709
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1710
                expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1711
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1712
                // Get CASE body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1713
                final Block statements = getBlock(false);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  1714
                final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
16153
60de45bf54b0 8005703: Offsets miscalculated for blocks
jlaskey
parents: 16151
diff changeset
  1715
                statements.setFinish(finish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1716
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1717
                if (caseExpression == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1718
                    defaultCase = caseNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1719
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1720
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1721
                cases.add(caseNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1722
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1723
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1724
            switchNode = switchNode.setCases(lc, cases, defaultCase);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1725
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1726
            switchNode.setFinish(finish);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1727
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1728
            appendStatement(switchNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1729
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1730
            lc.pop(switchNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1731
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1732
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1733
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1734
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1735
     * LabelledStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1736
     *      Identifier : Statement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1737
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1738
     * See 12.12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1739
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1740
     * Parse label statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1741
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1742
    private void labelStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1743
        // Capture label token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1744
        final long labelToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1745
        // Get label ident.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1746
        final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1747
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1748
        expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1749
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1750
        if (lc.findLabel(ident.getName()) != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1751
            throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1752
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1753
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1754
        LabelNode labelNode = new LabelNode(line, labelToken, finish, ident.getName(), null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1755
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1756
            lc.push(labelNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1757
            labelNode = labelNode.setBody(lc, getStatement());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1758
            labelNode.setFinish(finish);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1759
            appendStatement(labelNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1760
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1761
            assert lc.peek() instanceof LabelNode;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1762
            lc.pop(labelNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1763
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1764
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1765
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  1766
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1767
     * ThrowStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1768
     *      throw Expression ; // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1769
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1770
     * See 12.13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1771
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1772
     * Parse throw statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1773
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1774
    private void throwStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1775
        // Capture THROW token.
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
  1776
        final int  throwLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1777
        final long throwToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1778
        // THROW tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1779
        nextOrEOL();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1780
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1781
        Expression expression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1782
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1783
        // SEMICOLON or expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1784
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1785
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1786
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1787
        case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1788
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1789
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1790
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1791
            expression = expression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1792
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1793
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1794
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1795
        if (expression == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1796
            throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1797
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1798
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1799
        endOfLine();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1800
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1801
        appendStatement(new ThrowNode(throwLine, throwToken, finish, expression, false));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1802
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1803
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1804
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1805
     * TryStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1806
     *      try Block Catch
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1807
     *      try Block Finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1808
     *      try Block Catch Finally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1809
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1810
     * Catch :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1811
     *      catch( Identifier if Expression ) Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1812
     *      catch( Identifier ) Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1813
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1814
     * Finally :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1815
     *      finally Block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1816
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1817
     * See 12.14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1818
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1819
     * Parse TRY statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1820
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1821
    private void tryStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1822
        // Capture TRY token.
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
  1823
        final int  tryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1824
        final long tryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1825
        // TRY tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1826
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1827
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  1828
        // Container block needed to act as target for labeled break statements
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1829
        final int startLine = line;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1830
        Block outer = newBlock();
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  1831
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1832
        // Create try.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1833
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1834
        try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1835
            final Block       tryBody     = getBlock(true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1836
            final List<Block> catchBlocks = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1837
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1838
            while (type == CATCH) {
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
  1839
                final int  catchLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1840
                final long catchToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1841
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1842
                expect(LPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1843
                final IdentNode exception = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1844
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1845
                // ECMA 12.4.1 strict mode restrictions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1846
                verifyStrictIdent(exception, "catch argument");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1847
23766
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  1848
                // Nashorn extension: catch clause can have optional
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  1849
                // condition. So, a single try can have more than one
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  1850
                // catch clause each with it's own condition.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1851
                final Expression ifExpression;
23766
a3ef17770bab 8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
sundar
parents: 23372
diff changeset
  1852
                if (!env._no_syntax_extensions && type == IF) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1853
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1854
                    // Get the exception condition.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1855
                    ifExpression = expression();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1856
                } else {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1857
                    ifExpression = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1858
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1859
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1860
                expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1861
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1862
                Block catchBlock = newBlock();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1863
                try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1864
                    // Get CATCH body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1865
                    final Block catchBody = getBlock(true);
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  1866
                    final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, false);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1867
                    appendStatement(catchNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1868
                } finally {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1869
                    catchBlock = restoreBlock(catchBlock);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1870
                    catchBlocks.add(catchBlock);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1871
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1872
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1873
                // If unconditional catch then should to be the end.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1874
                if (ifExpression == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1875
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1876
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1877
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1878
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1879
            // Prepare to capture finally statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1880
            Block finallyStatements = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1881
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1882
            if (type == FINALLY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1883
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1884
                finallyStatements = getBlock(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1885
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1886
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1887
            // Need at least one catch or a finally.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1888
            if (catchBlocks.isEmpty() && finallyStatements == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1889
                throw error(AbstractParser.message("missing.catch.or.finally"), tryToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1890
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1891
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
  1892
            final TryNode tryNode = new TryNode(tryLine, tryToken, Token.descPosition(tryToken), tryBody, catchBlocks, finallyStatements);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1893
            // Add try.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1894
            assert lc.peek() == outer;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1895
            appendStatement(tryNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1896
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1897
            tryNode.setFinish(finish);
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  1898
            outer.setFinish(finish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1899
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1900
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1901
            outer = restoreBlock(outer);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1902
        }
16239
fbae49f786c6 8008215: break in catch clause causes java.lang.VerifyError: Inconsistent stackmap
hannesw
parents: 16237
diff changeset
  1903
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1904
        appendStatement(new BlockStatement(startLine, outer));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1905
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1906
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1907
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1908
     * DebuggerStatement :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1909
     *      debugger ;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1910
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1911
     * See 12.15
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1912
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1913
     * Parse debugger statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1914
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1915
    private void  debuggerStatement() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1916
        // Capture DEBUGGER token.
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
  1917
        final int  debuggerLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1918
        final long debuggerToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1919
        // DEBUGGER tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1920
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1921
        endOfLine();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1922
        appendStatement(new ExpressionStatement(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Expression>())));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1923
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1924
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1925
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1926
     * PrimaryExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1927
     *      this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1928
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1929
     *      Literal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1930
     *      ArrayLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1931
     *      ObjectLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1932
     *      ( Expression )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1933
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1934
     *  See 11.1
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1935
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1936
     * Parse primary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1937
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1938
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1939
    @SuppressWarnings("fallthrough")
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1940
    private Expression primaryExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1941
        // Capture first token.
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
  1942
        final int  primaryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1943
        final long primaryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1944
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1945
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1946
        case THIS:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1947
            final String name = type.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1948
            next();
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 22390
diff changeset
  1949
            lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_THIS);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  1950
            return new IdentNode(primaryToken, finish, name);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1951
        case IDENT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1952
            final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1953
            if (ident == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1954
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1955
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1956
            detectSpecialProperty(ident);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1957
            return ident;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1958
        case OCTAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1959
            if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1960
               throw error(AbstractParser.message("strict.no.octal"), token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1961
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1962
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1963
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1964
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1965
        case HEXADECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1966
        case FLOATING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1967
        case REGEX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1968
        case XML:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1969
            return getLiteral();
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  1970
        case EXECSTRING:
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
  1971
            return execString(primaryLine, primaryToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1972
        case FALSE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1973
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  1974
            return LiteralNode.newInstance(primaryToken, finish, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1975
        case TRUE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1976
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  1977
            return LiteralNode.newInstance(primaryToken, finish, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1978
        case NULL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1979
            next();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  1980
            return LiteralNode.newInstance(primaryToken, finish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1981
        case LBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1982
            return arrayLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1983
        case LBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1984
            return objectLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1985
        case LPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1986
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1987
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  1988
            final Expression expression = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1989
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1990
            expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1991
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1992
            return expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1993
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1994
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1995
            // In this context some operator tokens mark the start of a literal.
18870
aa4fceda2fba 8020437: Wrong handling of line numbers with multiline string literals
sundar
parents: 18867
diff changeset
  1996
            if (lexer.scanLiteral(primaryToken, type, lineInfoReceiver)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1997
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1998
                return getLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1999
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2000
            if (isNonStrictModeIdent()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2001
                return getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2002
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2003
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2004
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2005
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2006
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2007
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2008
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2009
    /**
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2010
     * Convert execString to a call to $EXEC.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2011
     *
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2012
     * @param primaryToken Original string token.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2013
     * @return callNode to $EXEC.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2014
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2015
    CallNode execString(final int primaryLine, final long primaryToken) {
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2016
        // Synthesize an ident to call $EXEC.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2017
        final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2018
        // Skip over EXECSTRING.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2019
        next();
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2020
        // Set up argument list for call.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2021
        // Skip beginning of edit string expression.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2022
        expect(LBRACE);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2023
        // Add the following expression to arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2024
        final List<Expression> arguments = Collections.singletonList(expression());
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2025
        // Skip ending of edit string expression.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2026
        expect(RBRACE);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2027
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2028
        return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments, false);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16206
diff changeset
  2029
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2030
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2031
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2032
     * ArrayLiteral :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2033
     *      [ Elision? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2034
     *      [ ElementList ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2035
     *      [ ElementList , Elision? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2036
     *      [ expression for (LeftHandExpression in expression) ( (if ( Expression ) )? ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2037
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2038
     * ElementList : Elision? AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2039
     *      ElementList , Elision? AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2040
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2041
     * Elision :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2042
     *      ,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2043
     *      Elision ,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2044
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2045
     * See 12.1.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2046
     * JavaScript 1.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2047
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2048
     * Parse array literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2049
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2050
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2051
    private LiteralNode<Expression[]> arrayLiteral() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2052
        // Capture LBRACKET token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2053
        final long arrayToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2054
        // LBRACKET tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2055
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2056
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2057
        // Prepare to accummulating elements.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2058
        final List<Expression> elements = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2059
        // Track elisions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2060
        boolean elision = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2061
loop:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2062
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2063
             switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2064
            case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2065
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2066
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2067
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2068
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2069
            case COMMARIGHT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2070
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2071
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2072
                // If no prior expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2073
                if (elision) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2074
                    elements.add(null);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2075
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2076
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2077
                elision = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2078
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2079
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2080
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2081
            default:
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2082
                if (!elision) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2083
                    throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2084
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2085
                // Add expression element.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2086
                final Expression expression = assignmentExpression(false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2087
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2088
                if (expression != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2089
                    elements.add(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2090
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2091
                    expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2092
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2093
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2094
                elision = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2095
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2096
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2097
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2098
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2099
        return LiteralNode.newInstance(arrayToken, finish, elements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2100
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2101
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2102
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2103
     * ObjectLiteral :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2104
     *      { }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2105
     *      { PropertyNameAndValueList } { PropertyNameAndValueList , }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2106
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2107
     * PropertyNameAndValueList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2108
     *      PropertyAssignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2109
     *      PropertyNameAndValueList , PropertyAssignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2110
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2111
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2112
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2113
     * Parse an object literal.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2114
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2115
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2116
    private ObjectNode objectLiteral() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2117
        // Capture LBRACE token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2118
        final long objectToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2119
        // LBRACE tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2120
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2121
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2122
        // Object context.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2123
        // Prepare to accumulate elements.
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2124
        final List<PropertyNode> elements = new ArrayList<>();
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2125
        final Map<String, Integer> map = new HashMap<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2126
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2127
        // Create a block for the object literal.
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2128
        boolean commaSeen = true;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2129
loop:
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2130
        while (true) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2131
            switch (type) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2132
                case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2133
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2134
                    break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2135
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2136
                case COMMARIGHT:
18629
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2137
                    if (commaSeen) {
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2138
                        throw error(AbstractParser.message("expected.property.id", type.getNameOrType()));
6b0b6aab4280 8019508: Comma handling in object literal parsing is wrong
sundar
parents: 18625
diff changeset
  2139
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2140
                    next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2141
                    commaSeen = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2142
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2143
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2144
                default:
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2145
                    if (!commaSeen) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2146
                        throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2147
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2148
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2149
                    commaSeen = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2150
                    // Get and add the next property.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2151
                    final PropertyNode property = propertyAssignment();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2152
                    final String key = property.getKeyName();
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2153
                    final Integer existing = map.get(key);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2154
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2155
                    if (existing == null) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2156
                        map.put(key, elements.size());
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2157
                        elements.add(property);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2158
                        break;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2159
                    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2160
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2161
                    final PropertyNode existingProperty = elements.get(existing);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2162
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2163
                    // ECMA section 11.1.5 Object Initialiser
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2164
                    // point # 4 on property assignment production
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2165
                    final Expression   value  = property.getValue();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2166
                    final FunctionNode getter = property.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2167
                    final FunctionNode setter = property.getSetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2168
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2169
                    final Expression   prevValue  = existingProperty.getValue();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2170
                    final FunctionNode prevGetter = existingProperty.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2171
                    final FunctionNode prevSetter = existingProperty.getSetter();
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2172
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2173
                    // ECMA 11.1.5 strict mode restrictions
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2174
                    if (isStrictMode && value != null && prevValue != null) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2175
                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2176
                    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2177
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2178
                    final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2179
                    final boolean isAccessor     = getter != null     || setter != null;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2180
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2181
                    // data property redefined as accessor property
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2182
                    if (prevValue != null && isAccessor) {
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2183
                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2184
                    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2185
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2186
                    // accessor property redefined as data
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2187
                    if (isPrevAccessor && value != null) {
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2188
                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2189
                    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2190
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2191
                    if (isAccessor && isPrevAccessor) {
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2192
                        if (getter != null && prevGetter != null ||
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2193
                                setter != null && prevSetter != null) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2194
                            throw error(AbstractParser.message("property.redefinition", key), property.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2195
                        }
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2196
                    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2197
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2198
                    if (value != null) {
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2199
                        elements.add(property);
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2200
                    } else if (getter != null) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2201
                        elements.set(existing, existingProperty.setGetter(getter));
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2202
                    } else if (setter != null) {
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2203
                        elements.set(existing, existingProperty.setSetter(setter));
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2204
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2205
                    break;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2206
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2207
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2208
18877
6d75ba520886 8020354: Object literal property initialization is not done in source order
hannesw
parents: 18870
diff changeset
  2209
        return new ObjectNode(objectToken, finish, elements);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2210
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2211
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2212
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2213
     * PropertyName :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2214
     *      IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2215
     *      StringLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2216
     *      NumericLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2217
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2218
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2219
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2220
     * @return PropertyName node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2221
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2222
    @SuppressWarnings("fallthrough")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2223
    private PropertyKey propertyName() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2224
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2225
        case IDENT:
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2226
            return getIdent().setIsPropertyName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2227
        case OCTAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2228
            if (isStrictMode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2229
                throw error(AbstractParser.message("strict.no.octal"), token);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2230
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2231
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2232
        case ESCSTRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2233
        case DECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2234
        case HEXADECIMAL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2235
        case FLOATING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2236
            return getLiteral();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2237
        default:
19883
aae0838ac6ee 8024255: When a keyword is used as object property name, the property can not be deleted
sundar
parents: 19472
diff changeset
  2238
            return getIdentifierName().setIsPropertyName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2239
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2240
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2241
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2242
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2243
     * PropertyAssignment :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2244
     *      PropertyName : AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2245
     *      get PropertyName ( ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2246
     *      set PropertyName ( PropertySetParameterList ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2247
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2248
     * PropertySetParameterList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2249
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2250
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2251
     * PropertyName :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2252
     *      IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2253
     *      StringLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2254
     *      NumericLiteral
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2255
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2256
     * See 11.1.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2257
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2258
     * Parse an object literal property.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2259
     * @return Property or reference node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2260
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2261
    private PropertyNode propertyAssignment() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2262
        // Capture firstToken.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2263
        final long propertyToken = token;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2264
        final int  functionLine  = line;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2265
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2266
        PropertyKey propertyName;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2267
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2268
        if (type == IDENT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2269
            // Get IDENT.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2270
            final String ident = (String)expectValue(IDENT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2271
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2272
            if (type != COLON) {
20938
e92d8249f60c 8026302: source representation of getter and setter methods is wrong
sundar
parents: 20934
diff changeset
  2273
                final long getSetToken = propertyToken;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2274
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2275
                switch (ident) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2276
                case "get":
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2277
                    final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2278
                    return new PropertyNode(propertyToken, finish, getter.ident, null, getter.functionNode, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2279
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2280
                case "set":
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2281
                    final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2282
                    return new PropertyNode(propertyToken, finish, setter.ident, null, null, setter.functionNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2283
                default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2284
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2285
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2286
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2287
26243
438aba09d465 8055911: Don't use String.intern for IdentNode
attila
parents: 26068
diff changeset
  2288
            propertyName =  createIdentNode(propertyToken, finish, ident).setIsPropertyName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2289
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2290
            propertyName = propertyName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2291
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2292
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2293
        expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2294
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2295
        defaultNames.push(propertyName);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2296
        try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2297
            return new PropertyNode(propertyToken, finish, propertyName, assignmentExpression(false), null, null);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2298
        } finally {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2299
            defaultNames.pop();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2300
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2301
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2302
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2303
    private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2304
        final PropertyKey getIdent = propertyName();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2305
        final String getterName = getIdent.getPropertyName();
26243
438aba09d465 8055911: Don't use String.intern for IdentNode
attila
parents: 26068
diff changeset
  2306
        final IdentNode getNameNode = createIdentNode(((Node)getIdent).getToken(), finish, NameCodec.encode("get " + getterName));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2307
        expect(LPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2308
        expect(RPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2309
        final FunctionNode functionNode = functionBody(getSetToken, getNameNode, new ArrayList<IdentNode>(), FunctionNode.Kind.GETTER, functionLine);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2310
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2311
        return new PropertyFunction(getIdent, functionNode);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2312
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2313
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2314
    private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2315
        final PropertyKey setIdent = propertyName();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2316
        final String setterName = setIdent.getPropertyName();
26243
438aba09d465 8055911: Don't use String.intern for IdentNode
attila
parents: 26068
diff changeset
  2317
        final IdentNode setNameNode = createIdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2318
        expect(LPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2319
        // be sloppy and allow missing setter parameter even though
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2320
        // spec does not permit it!
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2321
        final IdentNode argIdent;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2322
        if (type == IDENT || isNonStrictModeIdent()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2323
            argIdent = getIdent();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2324
            verifyStrictIdent(argIdent, "setter argument");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2325
        } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2326
            argIdent = null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2327
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2328
        expect(RPAREN);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2329
        final List<IdentNode> parameters = new ArrayList<>();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2330
        if (argIdent != null) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2331
            parameters.add(argIdent);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2332
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2333
        final FunctionNode functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER, functionLine);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2334
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2335
        return new PropertyFunction(setIdent, functionNode);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2336
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2337
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2338
    private static class PropertyFunction {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2339
        final PropertyKey ident;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2340
        final FunctionNode functionNode;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2341
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2342
        PropertyFunction(final PropertyKey ident, final FunctionNode function) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2343
            this.ident = ident;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2344
            this.functionNode = function;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2345
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2346
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2347
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2348
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2349
     * LeftHandSideExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2350
     *      NewExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2351
     *      CallExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2352
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2353
     * CallExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2354
     *      MemberExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2355
     *      CallExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2356
     *      CallExpression [ Expression ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2357
     *      CallExpression . IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2358
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2359
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2360
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2361
     * Parse left hand side expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2362
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2363
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2364
    private Expression leftHandSideExpression() {
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
  2365
        int  callLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2366
        long callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2367
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2368
        Expression lhs = memberExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2369
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2370
        if (type == LPAREN) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2371
            final List<Expression> arguments = optimizeList(argumentList());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2372
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2373
            // Catch special functions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2374
            if (lhs instanceof IdentNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2375
                detectSpecialFunction((IdentNode)lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2376
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2377
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2378
            lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2379
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2380
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2381
loop:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2382
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2383
            // Capture token.
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
  2384
            callLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2385
            callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2386
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2387
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2388
            case LPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2389
                // Get NEW or FUNCTION arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2390
                final List<Expression> arguments = optimizeList(argumentList());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2391
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2392
                // Create call node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2393
                lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2394
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2395
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2396
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2397
            case LBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2398
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2399
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2400
                // Get array index.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2401
                final Expression rhs = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2402
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2403
                expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2404
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2405
                // Create indexing node.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2406
                lhs = new IndexNode(callToken, finish, lhs, rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2407
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2408
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2409
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2410
            case PERIOD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2411
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2412
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2413
                final IdentNode property = getIdentifierName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2414
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2415
                // Create property access node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2416
                lhs = new AccessNode(callToken, finish, lhs, property.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2417
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2418
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2419
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2420
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2421
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2422
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2423
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2424
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2425
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2426
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2427
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2428
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2429
     * NewExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2430
     *      MemberExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2431
     *      new NewExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2432
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2433
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2434
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2435
     * Parse new expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2436
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2437
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2438
    private Expression newExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2439
        final long newToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2440
        // NEW is tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2441
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2442
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2443
        // Get function base.
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
  2444
        final int  callLine    = line;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2445
        final Expression constructor = memberExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2446
        if (constructor == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2447
            return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2448
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2449
        // Get arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2450
        ArrayList<Expression> arguments;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2451
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2452
        // Allow for missing arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2453
        if (type == LPAREN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2454
            arguments = argumentList();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2455
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2456
            arguments = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2457
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2458
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  2459
        // Nashorn extension: This is to support the following interface implementation
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  2460
        // syntax:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2461
        //
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2462
        //     var r = new java.lang.Runnable() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2463
        //         run: function() { println("run"); }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2464
        //     };
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2465
        //
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2466
        // The object literal following the "new Constructor()" expresssion
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2467
        // is passed as an additional (last) argument to the constructor.
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  2468
        if (!env._no_syntax_extensions && type == LBRACE) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2469
            arguments.add(objectLiteral());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2470
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2471
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2472
        final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, optimizeList(arguments), true);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2473
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2474
        return new UnaryNode(newToken, callNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2475
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2476
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2477
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2478
     * MemberExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2479
     *      PrimaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2480
     *      FunctionExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2481
     *      MemberExpression [ Expression ]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2482
     *      MemberExpression . IdentifierName
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2483
     *      new MemberExpression Arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2484
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2485
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2486
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2487
     * Parse member expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2488
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2489
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2490
    private Expression memberExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2491
        // Prepare to build operation.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2492
        Expression lhs;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2493
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2494
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2495
        case NEW:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2496
            // Get new expression.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2497
            lhs = newExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2498
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2499
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2500
        case FUNCTION:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2501
            // Get function expression.
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2502
            lhs = functionExpression(false, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2503
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2504
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2505
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2506
            // Get primary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2507
            lhs = primaryExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2508
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2509
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2510
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2511
loop:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2512
        while (true) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2513
            // Capture token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2514
            final long callToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2515
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2516
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2517
            case LBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2518
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2519
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2520
                // Get array index.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2521
                final Expression index = expression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2522
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2523
                expect(RBRACKET);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2524
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2525
                // Create indexing node.
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2526
                lhs = new IndexNode(callToken, finish, lhs, index);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2527
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2528
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2529
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2530
            case PERIOD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2531
                if (lhs == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2532
                    throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2533
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2534
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2535
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2536
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2537
                final IdentNode property = getIdentifierName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2538
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2539
                // Create property access node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2540
                lhs = new AccessNode(callToken, finish, lhs, property.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2541
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2542
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2543
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2544
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2545
                break loop;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2546
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2547
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2548
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2549
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2550
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2551
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2552
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2553
     * Arguments :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2554
     *      ( )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2555
     *      ( ArgumentList )
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2556
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2557
     * ArgumentList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2558
     *      AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2559
     *      ArgumentList , AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2560
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2561
     * See 11.2
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2562
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2563
     * Parse function call arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2564
     * @return Argument list.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2565
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2566
    private ArrayList<Expression> argumentList() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2567
        // Prepare to accumulate list of arguments.
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2568
        final ArrayList<Expression> nodeList = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2569
        // LPAREN tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2570
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2571
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2572
        // Track commas.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2573
        boolean first = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2574
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2575
        while (type != RPAREN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2576
            // Comma prior to every argument except the first.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2577
            if (!first) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2578
                expect(COMMARIGHT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2579
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2580
                first = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2581
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2582
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2583
            // Get argument expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2584
            nodeList.add(assignmentExpression(false));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2585
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2586
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2587
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2588
        return nodeList;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2589
    }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2590
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
  2591
    private static <T> List<T> optimizeList(final ArrayList<T> list) {
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2592
        switch(list.size()) {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2593
            case 0: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2594
                return Collections.emptyList();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2595
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2596
            case 1: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2597
                return Collections.singletonList(list.get(0));
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2598
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2599
            default: {
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2600
                list.trimToSize();
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2601
                return list;
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2602
            }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2603
        }
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2604
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2605
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2606
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2607
     * FunctionDeclaration :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2608
     *      function Identifier ( FormalParameterList? ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2609
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2610
     * FunctionExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2611
     *      function Identifier? ( FormalParameterList? ) { FunctionBody }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2612
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2613
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2614
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2615
     * Parse function declaration.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2616
     * @param isStatement True if for is a statement.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2617
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2618
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2619
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2620
    private Expression functionExpression(final boolean isStatement, final boolean topLevel) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2621
        final long functionToken = token;
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
  2622
        final int  functionLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2623
        // FUNCTION is tested in caller.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2624
        next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2625
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2626
        IdentNode name = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2627
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2628
        if (type == IDENT || isNonStrictModeIdent()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2629
            name = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2630
            verifyStrictIdent(name, "function name");
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  2631
        } else if (isStatement) {
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  2632
            // Nashorn extension: anonymous function statements
18335
1b5fdae617cf 8016550: nashorn.option.no.syntax.extensions has the wrong default
sundar
parents: 17981
diff changeset
  2633
            if (env._no_syntax_extensions) {
16196
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  2634
                expect(IDENT);
58f6f046bb5e 8006983: Introduce a command line option to switch off syntactic extensions of nashorn
sundar
parents: 16191
diff changeset
  2635
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2636
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2637
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2638
        // name is null, generate anonymous name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2639
        boolean isAnonymous = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2640
        if (name == null) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2641
            final String tmpName = getDefaultValidFunctionName(functionLine);
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2642
            name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2643
            isAnonymous = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2644
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2645
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2646
        expect(LPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2647
        final List<IdentNode> parameters = formalParameterList();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2648
        expect(RPAREN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2649
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2650
        FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL, functionLine);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2651
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2652
        if (isStatement) {
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2653
            if (topLevel || useBlockScope()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2654
                functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED);
17257
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  2655
            } else if (isStrictMode) {
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  2656
                throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  2657
            } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ERROR) {
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  2658
                throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here"), functionToken);
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  2659
            } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.WARNING) {
a2232050cd8f 8008814: Configurable ignore/warning/error behavior for function declaration as statement
attila
parents: 17255
diff changeset
  2660
                warning(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here.warn"), functionToken);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2661
            }
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
  2662
            if (isArguments(name)) {
17249
a2014831ae7a 8013325: function named 'arguments' should set DEFINES_ARGUMENTS flag in its parent, not itself
attila
parents: 17233
diff changeset
  2663
                lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  2664
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2665
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2666
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2667
        if (isAnonymous) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2668
            functionNode = functionNode.setFlag(lc, FunctionNode.IS_ANONYMOUS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2669
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2670
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2671
        final int arity = parameters.size();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2672
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2673
        final boolean strict = functionNode.isStrict();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2674
        if (arity > 1) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2675
            final HashSet<String> parametersSet = new HashSet<>(arity);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2676
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2677
            for (int i = arity - 1; i >= 0; i--) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2678
                final IdentNode parameter = parameters.get(i);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2679
                String parameterName = parameter.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2680
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
  2681
                if (isArguments(parameterName)) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2682
                    functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2683
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2684
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2685
                if (parametersSet.contains(parameterName)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2686
                    // redefinition of parameter name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2687
                    if (strict) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2688
                        throw error(AbstractParser.message("strict.param.redefinition", parameterName), parameter.getToken());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2689
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2690
                    // rename in non-strict mode
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2691
                    parameterName = functionNode.uniqueName(parameterName);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2692
                    final long parameterToken = parameter.getToken();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2693
                    parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2694
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2695
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2696
                parametersSet.add(parameterName);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2697
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2698
        } else if (arity == 1) {
19898
58c39862aa3f 8024846: keep separate internal arguments variable
attila
parents: 19883
diff changeset
  2699
            if (isArguments(parameters.get(0))) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2700
                functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2701
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2702
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2703
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2704
        if (isStatement) {
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2705
            int varFlags = VarNode.IS_STATEMENT;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2706
            if (!topLevel && useBlockScope()) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2707
                // mark ES6 block functions as lexically scoped
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2708
                varFlags |= VarNode.IS_LET;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2709
            }
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2710
            final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2711
            if (topLevel) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2712
                functionDeclarations.add(varNode);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2713
            } else if (useBlockScope()) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26246
diff changeset
  2714
                prependStatement(varNode); // Hoist to beginning of current block
16191
7dd981da8e11 8006755: Functions inside with statements dont get correct scope
sundar
parents: 16187
diff changeset
  2715
            } else {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2716
                appendStatement(varNode);
16191
7dd981da8e11 8006755: Functions inside with statements dont get correct scope
sundar
parents: 16187
diff changeset
  2717
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2718
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2719
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2720
        return functionNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2721
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2722
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2723
    private String getDefaultValidFunctionName(final int functionLine) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2724
        final String defaultFunctionName = getDefaultFunctionName();
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
  2725
        return isValidIdentifier(defaultFunctionName) ? defaultFunctionName : ANON_FUNCTION_PREFIX.symbolName() + functionLine;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2726
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2727
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24727
diff changeset
  2728
    private static boolean isValidIdentifier(final String name) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2729
        if(name == null || name.isEmpty()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2730
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2731
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2732
        if(!Character.isJavaIdentifierStart(name.charAt(0))) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2733
            return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2734
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2735
        for(int i = 1; i < name.length(); ++i) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2736
            if(!Character.isJavaIdentifierPart(name.charAt(i))) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2737
                return false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2738
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2739
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2740
        return true;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2741
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2742
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2743
    private String getDefaultFunctionName() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2744
        if(!defaultNames.isEmpty()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2745
            final Object nameExpr = defaultNames.peek();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2746
            if(nameExpr instanceof PropertyKey) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2747
                markDefaultNameUsed();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2748
                return ((PropertyKey)nameExpr).getPropertyName();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2749
            } else if(nameExpr instanceof AccessNode) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2750
                markDefaultNameUsed();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2751
                return ((AccessNode)nameExpr).getProperty();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2752
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2753
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2754
        return null;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2755
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2756
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2757
    private void markDefaultNameUsed() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2758
        defaultNames.pop();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2759
        // Can be any value as long as getDefaultFunctionName doesn't recognize it as something it can extract a value
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2760
        // from. Can't be null
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2761
        defaultNames.push("");
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2762
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2763
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2764
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2765
     * FormalParameterList :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2766
     *      Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2767
     *      FormalParameterList , Identifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2768
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2769
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2770
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2771
     * Parse function parameter list.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2772
     * @return List of parameter nodes.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2773
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2774
    private List<IdentNode> formalParameterList() {
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2775
        return formalParameterList(RPAREN);
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2776
    }
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2777
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2778
    /**
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2779
     * Same as the other method of the same name - except that the end
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2780
     * token type expected is passed as argument to this method.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2781
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2782
     * FormalParameterList :
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2783
     *      Identifier
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2784
     *      FormalParameterList , Identifier
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2785
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2786
     * See 13
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2787
     *
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2788
     * Parse function parameter list.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2789
     * @return List of parameter nodes.
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2790
     */
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2791
    private List<IdentNode> formalParameterList(final TokenType endType) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2792
        // Prepare to gather parameters.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2793
        final ArrayList<IdentNode> parameters = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2794
        // Track commas.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2795
        boolean first = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2796
17973
d220c8157f25 8015345: Function("}),print('test'),({") should throw SyntaxError
sundar
parents: 17745
diff changeset
  2797
        while (type != endType) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2798
            // Comma prior to every argument except the first.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2799
            if (!first) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2800
                expect(COMMARIGHT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2801
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2802
                first = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2803
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2804
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2805
            // Get and add parameter.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2806
            final IdentNode ident = getIdent();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2807
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2808
            // ECMA 13.1 strict mode restrictions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2809
            verifyStrictIdent(ident, "function parameter");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2810
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2811
            parameters.add(ident);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2812
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2813
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  2814
        parameters.trimToSize();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2815
        return parameters;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2816
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2817
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2818
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2819
     * FunctionBody :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2820
     *      SourceElements?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2821
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2822
     * See 13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2823
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2824
     * Parse function body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2825
     * @return function node (body.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2826
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2827
    private FunctionNode functionBody(final long firstToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2828
        FunctionNode functionNode = null;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2829
        long lastToken = 0L;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2830
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2831
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2832
            // Create a new function block.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2833
            functionNode = newFunctionNode(firstToken, ident, parameters, kind, functionLine);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2834
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2835
            // Nashorn extension: expression closures
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  2836
            if (!env._no_syntax_extensions && type != LBRACE) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2837
                /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2838
                 * Example:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2839
                 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2840
                 * function square(x) x * x;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2841
                 * print(square(3));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2842
                 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2843
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2844
                // just expression as function body
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2845
                final Expression expr = assignmentExpression(true);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2846
                lastToken = previousToken;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2847
                assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2848
                // EOL uses length field to store the line number
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2849
                final int lastFinish = Token.descPosition(lastToken) + (Token.descType(lastToken) == EOL ? 0 : Token.descLength(lastToken));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2850
                final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2851
                appendStatement(returnNode);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2852
                functionNode.setFinish(lastFinish);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2853
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2854
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2855
                expect(LBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2856
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2857
                // Gather the function elements.
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
  2858
                final List<Statement> prevFunctionDecls = functionDeclarations;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2859
                functionDeclarations = new ArrayList<>();
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2860
                try {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  2861
                    sourceElements(false);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2862
                    addFunctionDeclarations(functionNode);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2863
                } finally {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2864
                    functionDeclarations = prevFunctionDecls;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2865
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2866
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2867
                lastToken = token;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2868
                expect(RBRACE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2869
                functionNode.setFinish(finish);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2870
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2871
        } finally {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2872
            functionNode = restoreFunctionNode(functionNode, lastToken);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2873
        }
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2874
        printAST(functionNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2875
        return functionNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2876
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2877
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2878
    private void printAST(final FunctionNode functionNode) {
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2879
        if (functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2880
            env.getErr().println(new ASTWriter(functionNode));
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2881
        }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2882
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2883
        if (functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2884
            env.getErr().println(new PrintVisitor(functionNode, true, false));
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2885
        }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2886
    }
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  2887
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2888
    private void addFunctionDeclarations(final FunctionNode functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2889
        VarNode lastDecl = null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2890
        for (int i = functionDeclarations.size() - 1; i >= 0; i--) {
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
  2891
            Statement decl = functionDeclarations.get(i);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2892
            if (lastDecl == null && decl instanceof VarNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2893
                decl = lastDecl = ((VarNode)decl).setFlag(VarNode.IS_LAST_FUNCTION_DECLARATION);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2894
                lc.setFlag(functionNode, FunctionNode.HAS_FUNCTION_DECLARATIONS);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2895
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2896
            prependStatement(decl);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2897
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2898
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2899
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2900
    private RuntimeNode referenceError(final Expression lhs, final Expression rhs, final boolean earlyError) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  2901
        if (earlyError) {
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  2902
            throw error(JSErrorType.REFERENCE_ERROR, AbstractParser.message("invalid.lvalue"), lhs.getToken());
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  2903
        }
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2904
        final ArrayList<Expression> args = new ArrayList<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2905
        args.add(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2906
        if (rhs == null) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2907
            args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2908
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2909
            args.add(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2910
        }
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2911
        args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish(), lhs.toString()));
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2912
        return new RuntimeNode(lhs.getToken(), lhs.getFinish(), RuntimeNode.Request.REFERENCE_ERROR, args);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2913
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2914
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2915
    /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2916
     * parse LHS [a, b, ..., c].
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2917
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2918
     * JavaScript 1.8.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2919
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2920
    //private Node destructureExpression() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2921
    //    return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2922
    //}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2923
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2924
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2925
     * PostfixExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2926
     *      LeftHandSideExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2927
     *      LeftHandSideExpression ++ // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2928
     *      LeftHandSideExpression -- // [no LineTerminator here]
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2929
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2930
     * See 11.3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2931
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2932
     * UnaryExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2933
     *      PostfixExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2934
     *      delete UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2935
     *      Node UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2936
     *      typeof UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2937
     *      ++ UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2938
     *      -- UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2939
     *      + UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2940
     *      - UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2941
     *      ~ UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2942
     *      ! UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2943
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2944
     * See 11.4
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2945
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2946
     * Parse unary expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2947
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2948
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2949
    private Expression unaryExpression() {
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
  2950
        final int  unaryLine  = line;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2951
        final long unaryToken = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2952
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2953
        switch (type) {
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
  2954
        case DELETE: {
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
  2955
            next();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2956
            final Expression expr = unaryExpression();
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
  2957
            if (expr instanceof BaseNode || expr instanceof IdentNode) {
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
  2958
                return new UnaryNode(unaryToken, expr);
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
  2959
            }
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2960
            appendStatement(new ExpressionStatement(unaryLine, unaryToken, finish, expr));
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
  2961
            return LiteralNode.newInstance(unaryToken, finish, true);
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
  2962
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2963
        case VOID:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2964
        case TYPEOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2965
        case ADD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2966
        case SUB:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2967
        case BIT_NOT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2968
        case NOT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2969
            next();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2970
            final Expression expr = unaryExpression();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  2971
            return new UnaryNode(unaryToken, expr);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2972
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2973
        case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2974
        case DECPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2975
            final TokenType opType = type;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2976
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2977
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  2978
            final Expression lhs = leftHandSideExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2979
            // ++, -- without operand..
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2980
            if (lhs == null) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  2981
                throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2982
            }
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  2983
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2984
            if (!(lhs instanceof AccessNode ||
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2985
                  lhs instanceof IndexNode ||
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2986
                  lhs instanceof IdentNode)) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  2987
                return referenceError(lhs, null, env._early_lvalue_error);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2988
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2989
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2990
            if (lhs instanceof IdentNode) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  2991
                if (!checkIdentLValue((IdentNode)lhs)) {
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  2992
                    return referenceError(lhs, null, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2993
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2994
                verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2995
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2996
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2997
            return incDecExpression(unaryToken, opType, lhs, false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2998
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2999
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3000
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3001
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3002
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3003
        Expression expression = leftHandSideExpression();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3004
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3005
        if (last != EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3006
            switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3007
            case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3008
            case DECPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3009
                final TokenType opType = type;
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3010
                final Expression lhs = expression;
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  3011
                // ++, -- without operand..
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  3012
                if (lhs == null) {
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  3013
                    throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  3014
                }
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  3015
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3016
                if (!(lhs instanceof AccessNode ||
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3017
                   lhs instanceof IndexNode ||
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3018
                   lhs instanceof IdentNode)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3019
                    next();
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  3020
                    return referenceError(lhs, null, env._early_lvalue_error);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3021
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3022
                if (lhs instanceof IdentNode) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16262
diff changeset
  3023
                    if (!checkIdentLValue((IdentNode)lhs)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3024
                        next();
18632
93017277615e 8019553: NPE on illegal l-value for increment and decrement
sundar
parents: 18629
diff changeset
  3025
                        return referenceError(lhs, null, false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3026
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3027
                    verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3028
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3029
                expression = incDecExpression(token, type, expression, true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3030
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3031
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3032
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3033
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3034
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3035
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3036
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3037
        if (expression == null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3038
            throw error(AbstractParser.message("expected.operand", type.getNameOrType()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3039
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3040
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3041
        return expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3042
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3043
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3044
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3045
     * MultiplicativeExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3046
     *      UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3047
     *      MultiplicativeExpression * UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3048
     *      MultiplicativeExpression / UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3049
     *      MultiplicativeExpression % UnaryExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3050
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3051
     * See 11.5
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3052
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3053
     * AdditiveExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3054
     *      MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3055
     *      AdditiveExpression + MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3056
     *      AdditiveExpression - MultiplicativeExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3057
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3058
     * See 11.6
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3059
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3060
     * ShiftExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3061
     *      AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3062
     *      ShiftExpression << AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3063
     *      ShiftExpression >> AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3064
     *      ShiftExpression >>> AdditiveExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3065
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3066
     * See 11.7
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3067
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3068
     * RelationalExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3069
     *      ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3070
     *      RelationalExpression < ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3071
     *      RelationalExpression > ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3072
     *      RelationalExpression <= ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3073
     *      RelationalExpression >= ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3074
     *      RelationalExpression instanceof ShiftExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3075
     *      RelationalExpression in ShiftExpression // if !noIf
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3076
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3077
     * See 11.8
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3078
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3079
     *      RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3080
     *      EqualityExpression == RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3081
     *      EqualityExpression != RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3082
     *      EqualityExpression === RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3083
     *      EqualityExpression !== RelationalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3084
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3085
     * See 11.9
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3086
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3087
     * BitwiseANDExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3088
     *      EqualityExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3089
     *      BitwiseANDExpression & EqualityExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3090
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3091
     * BitwiseXORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3092
     *      BitwiseANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3093
     *      BitwiseXORExpression ^ BitwiseANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3094
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3095
     * BitwiseORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3096
     *      BitwiseXORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3097
     *      BitwiseORExpression | BitwiseXORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3098
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3099
     * See 11.10
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3100
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3101
     * LogicalANDExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3102
     *      BitwiseORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3103
     *      LogicalANDExpression && BitwiseORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3104
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3105
     * LogicalORExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3106
     *      LogicalANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3107
     *      LogicalORExpression || LogicalANDExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3108
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3109
     * See 11.11
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3110
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3111
     * ConditionalExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3112
     *      LogicalORExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3113
     *      LogicalORExpression ? AssignmentExpression : AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3114
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3115
     * See 11.12
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3116
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3117
     * AssignmentExpression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3118
     *      ConditionalExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3119
     *      LeftHandSideExpression AssignmentOperator AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3120
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3121
     * AssignmentOperator :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3122
     *      = *= /= %= += -= <<= >>= >>>= &= ^= |=
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3123
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3124
     * See 11.13
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3125
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3126
     * Expression :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3127
     *      AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3128
     *      Expression , AssignmentExpression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3129
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3130
     * See 11.14
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3131
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3132
     * Parse expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3133
     * @return Expression node.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3134
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3135
    private Expression expression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3136
        // TODO - Destructuring array.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3137
        // Include commas in expression parsing.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3138
        return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3139
    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3140
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3141
    private JoinPredecessorExpression joinPredecessorExpression() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3142
        return new JoinPredecessorExpression(expression());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3143
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3144
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3145
    private Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3146
        // Get the precedence of the next operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3147
        int precedence = type.getPrecedence();
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3148
        Expression lhs = exprLhs;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3149
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3150
        // While greater precedence.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3151
        while (type.isOperator(noIn) && precedence >= minPrecedence) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3152
            // Capture the operator token.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3153
            final long op = token;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3154
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3155
            if (type == TERNARY) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3156
                // Skip operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3157
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3158
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3159
                // Pass expression. Middle expression of a conditional expression can be a "in"
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3160
                // expression - even in the contexts where "in" is not permitted.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3161
                final Expression trueExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3162
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3163
                expect(COLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3164
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3165
                // Fail expression.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3166
                final Expression falseExpr = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3167
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3168
                // Build up node.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24745
diff changeset
  3169
                lhs = new TernaryNode(op, lhs, new JoinPredecessorExpression(trueExpr), new JoinPredecessorExpression(falseExpr));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3170
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3171
                // Skip operator.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3172
                next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3173
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3174
                 // Get the next primary expression.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3175
                Expression rhs;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3176
                final boolean isAssign = Token.descType(op) == ASSIGN;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3177
                if(isAssign) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3178
                    defaultNames.push(lhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3179
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3180
                try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3181
                    rhs = unaryExpression();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3182
                    // Get precedence of next operator.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3183
                    int nextPrecedence = type.getPrecedence();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3184
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3185
                    // Subtask greater precedence.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3186
                    while (type.isOperator(noIn) &&
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3187
                           (nextPrecedence > precedence ||
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3188
                           nextPrecedence == precedence && !type.isLeftAssociative())) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3189
                        rhs = expression(rhs, nextPrecedence, noIn);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3190
                        nextPrecedence = type.getPrecedence();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3191
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3192
                } finally {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3193
                    if(isAssign) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3194
                        defaultNames.pop();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3195
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22390
diff changeset
  3196
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3197
                lhs = verifyAssignment(op, lhs, rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3198
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3199
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3200
            precedence = type.getPrecedence();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3201
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3202
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3203
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3204
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3205
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 18853
diff changeset
  3206
    private Expression assignmentExpression(final boolean noIn) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3207
        // TODO - Handle decompose.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3208
        // Exclude commas in expression parsing.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3209
        return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3210
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3211
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3212
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3213
     * Parse an end of line.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3214
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3215
    private void endOfLine() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3216
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3217
        case SEMICOLON:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3218
        case EOL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3219
            next();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3220
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3221
        case RPAREN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3222
        case RBRACKET:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3223
        case RBRACE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3224
        case EOF:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3225
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3226
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3227
            if (last != EOL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3228
                expect(SEMICOLON);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3229
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3230
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3231
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3232
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3233
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  3234
    @Override
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  3235
    public String toString() {
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
  3236
        return "'JavaScript Parsing'";
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16245
diff changeset
  3237
    }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3238
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17249
diff changeset
  3239
    private static void markEval(final LexicalContext lc) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3240
        final Iterator<FunctionNode> iter = lc.getFunctions();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3241
        boolean flaggedCurrentFn = false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3242
        while (iter.hasNext()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3243
            final FunctionNode fn = iter.next();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3244
            if (!flaggedCurrentFn) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17249
diff changeset
  3245
                lc.setFlag(fn, FunctionNode.HAS_EVAL);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3246
                flaggedCurrentFn = true;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3247
            } else {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17249
diff changeset
  3248
                lc.setFlag(fn, FunctionNode.HAS_NESTED_EVAL);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3249
            }
18853
25ba8264b427 8019819: scope symbol didn't get a slot in certain cases
attila
parents: 18852
diff changeset
  3250
            lc.setBlockNeedsScope(lc.getFunctionBody(fn));
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3251
        }
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3252
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3253
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
  3254
    private void prependStatement(final Statement statement) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3255
        lc.prependStatement(statement);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3256
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3257
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
  3258
    private void appendStatement(final Statement statement) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3259
        lc.appendStatement(statement);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3260
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3261
}