nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
author attila
Wed, 05 Jun 2013 10:44:32 +0200
changeset 17981 9b8e085aa1fe
parent 17969 0a4ddfce5b84
child 18618 136279c4cbe6
permissions -rw-r--r--
8015955: ObjectNode.elements should be stronger typed Reviewed-by: lagergren, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.codegen;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.PRIVATE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.STATIC;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    30
import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    31
import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import static jdk.nashorn.internal.codegen.CompilerConstants.QUICK_PREFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
import static jdk.nashorn.internal.codegen.CompilerConstants.REGEX_PREFIX;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    36
import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_ARRAY_ARG;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    39
import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    40
import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    41
import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
    42
import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
import static jdk.nashorn.internal.codegen.CompilerConstants.staticField;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    47
import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    48
import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    49
import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_SCOPE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
import java.io.PrintWriter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
import java.util.ArrayList;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
import java.util.Arrays;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
import java.util.EnumSet;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
import java.util.Iterator;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
import java.util.LinkedList;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    60
import java.util.List;
17778
991ccffbeb13 8015459: Octane test run fails on Turkish locale
sundar
parents: 17769
diff changeset
    61
import java.util.Locale;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
import java.util.TreeMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    64
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    66
import jdk.nashorn.internal.codegen.types.ArrayType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    67
import jdk.nashorn.internal.codegen.types.Type;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
import jdk.nashorn.internal.ir.AccessNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
import jdk.nashorn.internal.ir.BaseNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
import jdk.nashorn.internal.ir.BinaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
import jdk.nashorn.internal.ir.Block;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
import jdk.nashorn.internal.ir.BreakNode;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    73
import jdk.nashorn.internal.ir.BreakableNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
import jdk.nashorn.internal.ir.CallNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
import jdk.nashorn.internal.ir.CaseNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
import jdk.nashorn.internal.ir.CatchNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
import jdk.nashorn.internal.ir.ContinueNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
import jdk.nashorn.internal.ir.EmptyNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
import jdk.nashorn.internal.ir.ExecuteNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
import jdk.nashorn.internal.ir.ForNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
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
    82
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
import jdk.nashorn.internal.ir.IdentNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    84
import jdk.nashorn.internal.ir.IfNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    85
import jdk.nashorn.internal.ir.IndexNode;
17968
108ba976aa02 8015684: FieldObjectCreator.putField ignores getValueType
attila
parents: 17778
diff changeset
    86
import jdk.nashorn.internal.ir.LexicalContext;
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
    87
import jdk.nashorn.internal.ir.LexicalContextNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    88
import jdk.nashorn.internal.ir.LiteralNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    91
import jdk.nashorn.internal.ir.LoopNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    92
import jdk.nashorn.internal.ir.Node;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
import jdk.nashorn.internal.ir.ObjectNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    94
import jdk.nashorn.internal.ir.PropertyNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
import jdk.nashorn.internal.ir.ReturnNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
import jdk.nashorn.internal.ir.RuntimeNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
import jdk.nashorn.internal.ir.RuntimeNode.Request;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
import jdk.nashorn.internal.ir.SplitNode;
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
    99
import jdk.nashorn.internal.ir.Statement;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
import jdk.nashorn.internal.ir.SwitchNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
import jdk.nashorn.internal.ir.Symbol;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
import jdk.nashorn.internal.ir.TernaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   103
import jdk.nashorn.internal.ir.ThrowNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   104
import jdk.nashorn.internal.ir.TryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   105
import jdk.nashorn.internal.ir.UnaryNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   106
import jdk.nashorn.internal.ir.VarNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
import jdk.nashorn.internal.ir.WhileNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
import jdk.nashorn.internal.ir.WithNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
import jdk.nashorn.internal.ir.debug.ASTWriter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   110
import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   111
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   112
import jdk.nashorn.internal.parser.Lexer.RegexToken;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   113
import jdk.nashorn.internal.parser.TokenType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   114
import jdk.nashorn.internal.runtime.Context;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   115
import jdk.nashorn.internal.runtime.Debug;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   116
import jdk.nashorn.internal.runtime.DebugLogger;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   117
import jdk.nashorn.internal.runtime.ECMAException;
17241
c337fefb8c84 8012334: ToUint32, ToInt32, and ToUint16 don't conform to spec
hannesw
parents: 17239
diff changeset
   118
import jdk.nashorn.internal.runtime.JSType;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
   119
import jdk.nashorn.internal.runtime.Property;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
import jdk.nashorn.internal.runtime.PropertyMap;
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: 16268
diff changeset
   121
import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
import jdk.nashorn.internal.runtime.Scope;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
import jdk.nashorn.internal.runtime.ScriptFunction;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
import jdk.nashorn.internal.runtime.ScriptObject;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   125
import jdk.nashorn.internal.runtime.ScriptRuntime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   126
import jdk.nashorn.internal.runtime.Source;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   127
import jdk.nashorn.internal.runtime.Undefined;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   128
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   129
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   130
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   131
 * This is the lowest tier of the code generator. It takes lowered ASTs emitted
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   132
 * from Lower and emits Java byte code. The byte code emission logic is broken
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   133
 * out into MethodEmitter. MethodEmitter works internally with a type stack, and
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   134
 * keeps track of the contents of the byte code stack. This way we avoid a large
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   135
 * number of special cases on the form
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   136
 * <pre>
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   137
 * if (type == INT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   138
 *     visitInsn(ILOAD, slot);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   139
 * } else if (type == DOUBLE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   140
 *     visitInsn(DOUBLE, slot);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   141
 * }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   142
 * </pre>
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   143
 * This quickly became apparent when the code generator was generalized to work
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   144
 * with all types, and not just numbers or objects.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   145
 * <p>
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   146
 * The CodeGenerator visits nodes only once, tags them as resolved and emits
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   147
 * bytecode for them.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   148
 */
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   149
final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContext> {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   150
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   151
    /** Name of the Global object, cannot be referred to as .class, @see CodeGenerator */
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   152
    private static final String GLOBAL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "Global";
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   153
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   154
    /** Name of the ScriptFunctionImpl, cannot be referred to as .class @see FunctionObjectCreator */
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   155
    private static final String SCRIPTFUNCTION_IMPL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "ScriptFunctionImpl";
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   156
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   157
    /** Constant data & installation. The only reason the compiler keeps this is because it is assigned
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
   158
     *  by reflection in class installation */
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
    private final Compiler compiler;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   160
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   161
    /** Call site flags given to the code generator to be used for all generated call sites */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
    private final int callSiteFlags;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   163
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   164
    /** How many regexp fields have been emitted */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
    private int regexFieldCount;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   167
    /** Line number for last statement. If we encounter a new line number, line number bytecode information
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   168
     *  needs to be generated */
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   169
    private int lastLineNumber = -1;
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   170
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   171
    /** When should we stop caching regexp expressions in fields to limit bytecode size? */
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   172
    private static final int MAX_REGEX_FIELDS = 2 * 1024;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   173
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   174
    /** Current method emitter */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   175
    private MethodEmitter method;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   176
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   177
    /** Current compile unit */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   178
    private CompileUnit unit;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   179
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   180
    private static final DebugLogger LOG   = new DebugLogger("codegen", "nashorn.codegen.debug");
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   181
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   182
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
     * Constructor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
     * @param compiler
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
    CodeGenerator(final Compiler compiler) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   189
        super(new CodeGeneratorLexicalContext());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   190
        this.compiler      = compiler;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
   191
        this.callSiteFlags = compiler.getEnv()._callsite_flags;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   194
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   195
     * Gets the call site flags, adding the strict flag if the current function
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   196
     * being generated is in strict mode
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   197
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   198
     * @return the correct flags for a call site in the current function
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   199
     */
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
   200
    int getCallSiteFlags() {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   201
        return lc.getCurrentFunction().isStrict() ? callSiteFlags | CALLSITE_STRICT : callSiteFlags;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   202
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   203
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   205
     * Load an identity node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   207
     * @param identNode an identity node to load
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   208
     * @return the method generator used
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   209
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   210
    private MethodEmitter loadIdent(final IdentNode identNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   211
        final Symbol symbol = identNode.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   213
        if (!symbol.isScope()) {
16209
18e55b352d56 8007460: var assignment to a parameter in a varargs method causes compilation error
attila
parents: 16206
diff changeset
   214
            assert symbol.hasSlot() || symbol.isParam();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
            return method.load(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   216
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   217
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   218
        final String name   = symbol.getName();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   219
        final Source source = lc.getCurrentFunction().getSource();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
        if (CompilerConstants.__FILE__.name().equals(name)) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   222
            return method.load(source.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
        } else if (CompilerConstants.__DIR__.name().equals(name)) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   224
            return method.load(source.getBase());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   225
        } else if (CompilerConstants.__LINE__.name().equals(name)) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
   226
            return method.load(source.getLine(identNode.position())).convert(Type.OBJECT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   227
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
            assert identNode.getSymbol().isScope() : identNode + " is not in scope!";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   229
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   230
            final int flags = CALLSITE_SCOPE | getCallSiteFlags();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   231
            method.loadCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   232
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   233
            if (isFastScope(symbol)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   234
                // Only generate shared scope getter for fast-scope symbols so we know we can dial in correct scope.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
                if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   236
                    return loadSharedScopeVar(identNode.getType(), symbol, flags);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
                return loadFastScopeVar(identNode.getType(), symbol, flags, identNode.isFunction());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   239
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   240
            return method.dynamicGet(identNode.getType(), identNode.getName(), flags, identNode.isFunction());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   241
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   243
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   244
    /**
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   245
     * Check if this symbol can be accessed directly with a putfield or getfield or dynamic load
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   246
     *
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   247
     * @param function function to check for fast scope
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   248
     * @return true if fast scope
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   249
     */
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   250
    private boolean isFastScope(final Symbol symbol) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   251
        if (!symbol.isScope()) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   252
            return false;
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   253
        }
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   254
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   255
        if (!lc.inDynamicScope()) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   256
            // If there's no with or eval in context, and the symbol is marked as scoped, it is fast scoped. Such a
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   257
            // symbol must either be global, or its defining block must need scope.
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   258
            assert symbol.isGlobal() || lc.getDefiningBlock(symbol).needsScope() : symbol.getName();
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   259
            return true;
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   260
        }
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   261
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   262
        if (symbol.isGlobal()) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   263
            // Shortcut: if there's a with or eval in context, globals can't be fast scoped
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   264
            return false;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   265
        }
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   266
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   267
        // Otherwise, check if there's a dynamic scope between use of the symbol and its definition
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   268
        final String name = symbol.getName();
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   269
        boolean previousWasBlock = false;
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   270
        for (final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   271
            final LexicalContextNode node = it.next();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   272
            if (node instanceof Block) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   273
                // If this block defines the symbol, then we can fast scope the symbol.
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   274
                final Block block = (Block)node;
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   275
                if (block.getExistingSymbol(name) == symbol) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   276
                    assert block.needsScope();
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   277
                    return true;
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   278
                }
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   279
                previousWasBlock = true;
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   280
            } else {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   281
                if ((node instanceof WithNode && previousWasBlock) || (node instanceof FunctionNode && CodeGeneratorLexicalContext.isFunctionDynamicScope((FunctionNode)node))) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   282
                    // If we hit a scope that can have symbols introduced into it at run time before finding the defining
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   283
                    // block, the symbol can't be fast scoped. A WithNode only counts if we've immediately seen a block
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   284
                    // before - its block. Otherwise, we are currently processing the WithNode's expression, and that's
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   285
                    // obviously not subjected to introducing new symbols.
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   286
                    return false;
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   287
                }
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   288
                previousWasBlock = false;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   289
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   290
        }
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   291
        // Should've found the symbol defined in a block
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
   292
        throw new AssertionError();
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   293
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   294
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   295
    private MethodEmitter loadSharedScopeVar(final Type valueType, final Symbol symbol, final int flags) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   296
        method.load(isFastScope(symbol) ? getScopeProtoDepth(lc.getCurrentBlock(), symbol) : -1);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   297
        final SharedScopeCall scopeCall = lc.getScopeGet(unit, valueType, symbol, flags | CALLSITE_FAST_SCOPE);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   298
        return scopeCall.generateInvoke(method);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   299
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   300
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
    private MethodEmitter loadFastScopeVar(final Type valueType, final Symbol symbol, final int flags, final boolean isMethod) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   302
        loadFastScopeProto(symbol, false);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   303
        return method.dynamicGet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE, isMethod);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   304
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
    private MethodEmitter storeFastScopeVar(final Type valueType, final Symbol symbol, final int flags) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
        loadFastScopeProto(symbol, true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   308
        method.dynamicSet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
        return method;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   310
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   312
    private int getScopeProtoDepth(final Block startingBlock, final Symbol symbol) {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   313
        int depth = 0;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   314
        final String name = symbol.getName();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   315
        for(final Iterator<Block> blocks = lc.getBlocks(startingBlock); blocks.hasNext();) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   316
            final Block currentBlock = blocks.next();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   317
            if (currentBlock.getExistingSymbol(name) == symbol) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   318
                return depth;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   319
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   320
            if (currentBlock.needsScope()) {
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   321
                ++depth;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   322
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   323
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   324
        return -1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   325
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   326
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   327
    private void loadFastScopeProto(final Symbol symbol, final boolean swap) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   328
        final int depth = getScopeProtoDepth(lc.getCurrentBlock(), symbol);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   329
        assert depth != -1;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   330
        if (depth > 0) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   331
            if (swap) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
                method.swap();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
            for (int i = 0; i < depth; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
                method.invoke(ScriptObject.GET_PROTO);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   336
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   337
            if (swap) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   338
                method.swap();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   339
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   340
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   341
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   342
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   343
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   344
     * Generate code that loads this node to the stack. This method is only
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   345
     * public to be accessible from the maps sub package. Do not call externally
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   346
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   347
     * @param node node to load
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   348
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   349
     * @return the method emitter used
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   350
     */
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
   351
    MethodEmitter load(final Node node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   352
        return load(node, false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   353
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   354
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   355
    private MethodEmitter load(final Node node, final boolean baseAlreadyOnStack) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   356
        final Symbol symbol = node.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   357
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   358
        // If we lack symbols, we just generate what we see.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   359
        if (symbol == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   360
            node.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   361
            return method;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   362
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   363
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   364
        /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   365
         * The load may be of type IdentNode, e.g. "x", AccessNode, e.g. "x.y"
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   366
         * or IndexNode e.g. "x[y]". Both AccessNodes and IndexNodes are
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   367
         * BaseNodes and the logic for loading the base object is reused
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   368
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   369
        final CodeGenerator codegen = this;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   370
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   371
        node.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   372
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   373
            public boolean enterIdentNode(final IdentNode identNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   374
                loadIdent(identNode);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   375
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   376
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   377
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   378
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   379
            public boolean enterAccessNode(final AccessNode accessNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   380
                if (!baseAlreadyOnStack) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   381
                    load(accessNode.getBase()).convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   382
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   383
                assert method.peekType().isObject();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   384
                method.dynamicGet(node.getType(), accessNode.getProperty().getName(), getCallSiteFlags(), accessNode.isFunction());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   385
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   386
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   387
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   389
            public boolean enterIndexNode(final IndexNode indexNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   390
                if (!baseAlreadyOnStack) {
16190
23e52f635bb6 8006575: Error in codegen for element access on primitive value
sundar
parents: 16176
diff changeset
   391
                    load(indexNode.getBase()).convert(Type.OBJECT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   392
                    load(indexNode.getIndex());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   393
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   394
                method.dynamicGetIndex(node.getType(), getCallSiteFlags(), indexNode.isFunction());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   395
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   396
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   397
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   399
            public boolean enterFunctionNode(FunctionNode functionNode) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   400
                // function nodes will always leave a constructed function object on stack, no need to load the symbol
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   401
                // separately as in enterDefault()
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   402
                functionNode.accept(codegen);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   403
                return false;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   404
            }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   405
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   406
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   407
            public boolean enterDefault(final Node otherNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   408
                otherNode.accept(codegen); // generate code for whatever we are looking at.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   409
                method.load(symbol); // load the final symbol to the stack (or nop if no slot, then result is already there)
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   410
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   411
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   412
        });
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   413
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   414
        return method;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   417
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   418
    public boolean enterAccessNode(final AccessNode accessNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
        load(accessNode);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   420
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   422
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   423
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
     * Initialize a specific set of vars to undefined. This has to be done at
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
     * the start of each method for local variables that aren't passed as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
     * parameters.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   428
     * @param symbols list of symbols.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   429
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   430
    private void initSymbols(final Iterable<Symbol> symbols) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
        final LinkedList<Symbol> numbers = new LinkedList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
        final LinkedList<Symbol> objects = new LinkedList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   433
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   434
        for (final Symbol symbol : symbols) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   435
            /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   436
             * The following symbols are guaranteed to be defined and thus safe
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   437
             * from having undefined written to them: parameters internals this
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
             *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   439
             * Otherwise we must, unless we perform control/escape analysis,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   440
             * assign them undefined.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   441
             */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   442
            final boolean isInternal = symbol.isParam() || symbol.isInternal() || symbol.isThis() || !symbol.canBeUndefined();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   443
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   444
            if (symbol.hasSlot() && !isInternal) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   445
                assert symbol.getSymbolType().isNumber() || symbol.getSymbolType().isObject() : "no potentially undefined narrower local vars than doubles are allowed: " + symbol + " in " + lc.getCurrentFunction();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
                if (symbol.getSymbolType().isNumber()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
                    numbers.add(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
                } else if (symbol.getSymbolType().isObject()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
                    objects.add(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   452
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   454
        initSymbols(numbers, Type.NUMBER);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
        initSymbols(objects, Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   456
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
    private void initSymbols(final LinkedList<Symbol> symbols, final Type type) {
17969
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   459
        final Iterator<Symbol> it = symbols.iterator();
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   460
        if(it.hasNext()) {
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   461
            method.loadUndefined(type);
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   462
            boolean hasNext;
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   463
            do {
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   464
                final Symbol symbol = it.next();
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   465
                hasNext = it.hasNext();
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   466
                if(hasNext) {
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   467
                    method.dup();
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   468
                }
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   469
                method.store(symbol);
0a4ddfce5b84 8015674: CodeGenerator.initSymbols mutates a list
attila
parents: 17968
diff changeset
   470
            } while(hasNext);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   472
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   473
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   475
     * Create symbol debug information.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
     * @param block block containing symbols.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   478
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
    private void symbolInfo(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: 17255
diff changeset
   480
        for (final Symbol symbol : block.getSymbols()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   481
            if (symbol.hasSlot()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   482
                method.localVariable(symbol, block.getEntryLabel(), block.getBreakLabel());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   483
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   484
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   485
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   486
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   487
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   488
    public boolean enterBlock(final Block block) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   489
        method.label(block.getEntryLabel());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   490
        initLocals(block);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   491
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   492
        return true;
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
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   496
    public Node leaveBlock(final Block block) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   497
        method.label(block.getBreakLabel());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   498
        symbolInfo(block);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   499
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   500
        if (block.needsScope() && !block.isTerminal()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   501
            popBlockScope(block);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   502
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   503
        return block;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   504
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   505
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   506
    private void popBlockScope(final Block block) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   507
        final Label exitLabel     = new Label("block_exit");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   508
        final Label recoveryLabel = new Label("block_catch");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   509
        final Label skipLabel     = new Label("skip_catch");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   510
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
        /* pop scope a la try-finally */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   512
        method.loadCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
        method.invoke(ScriptObject.GET_PROTO);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   514
        method.storeCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
        method._goto(skipLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   516
        method.label(exitLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   517
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   518
        method._catch(recoveryLabel);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   519
        method.loadCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   520
        method.invoke(ScriptObject.GET_PROTO);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   521
        method.storeCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
        method.athrow();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
        method.label(skipLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   524
        method._try(block.getEntryLabel(), exitLabel, recoveryLabel, Throwable.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   526
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   527
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   528
    public boolean enterBreakNode(final BreakNode breakNode) {
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
   529
        lineNumber(breakNode);
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
   530
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   531
        final BreakableNode breakFrom = lc.getBreakable(breakNode.getLabel());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   532
        for (int i = 0; i < lc.getScopeNestingLevelTo(breakFrom); i++) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
            closeWith();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
        }
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   535
        method.splitAwareGoto(lc, breakFrom.getBreakLabel());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   536
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   537
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   540
    private int loadArgs(final List<Node> args) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   541
        return loadArgs(args, null, false, args.size());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   542
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   543
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   544
    private int loadArgs(final List<Node> args, final String signature, final boolean isVarArg, final int argCount) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
        // arg have already been converted to objects here.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
        if (isVarArg || argCount > LinkerCallSite.ARGLIMIT) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   547
            loadArgsArray(args);
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   548
            return 1;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   549
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   550
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   551
        // pad with undefined if size is too short. argCount is the real number of args
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   552
        int n = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   553
        final Type[] params = signature == null ? null : Type.getMethodArguments(signature);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   554
        for (final Node arg : args) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   555
            assert arg != null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   556
            load(arg);
16175
13ac6c5cc6a4 8006337: Discarded arguments for INVOKESTATIC must still be evaluated for side effects
attila
parents: 16174
diff changeset
   557
            if (n >= argCount) {
13ac6c5cc6a4 8006337: Discarded arguments for INVOKESTATIC must still be evaluated for side effects
attila
parents: 16174
diff changeset
   558
                method.pop(); // we had to load the arg for its side effects
13ac6c5cc6a4 8006337: Discarded arguments for INVOKESTATIC must still be evaluated for side effects
attila
parents: 16174
diff changeset
   559
            } else if (params != null) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   560
                method.convert(params[n]);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   561
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   562
            n++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   563
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   564
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   565
        while (n < argCount) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   566
            method.loadUndefined(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
            n++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   568
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   569
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   570
        return argCount;
16147
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
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   574
    public boolean enterCallNode(final CallNode callNode) {
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
   575
        lineNumber(callNode);
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
   576
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   577
        final List<Node>   args            = callNode.getArgs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   578
        final Node         function        = callNode.getFunction();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   579
        final Block        currentBlock    = lc.getCurrentBlock();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   580
        final CodeGeneratorLexicalContext codegenLexicalContext = lc;
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   581
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   582
        function.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   583
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   584
            private MethodEmitter sharedScopeCall(final IdentNode identNode, final int flags) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   585
                final Symbol symbol = identNode.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   586
                int    scopeCallFlags = flags;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   587
                method.loadCompilerConstant(SCOPE);
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   588
                if (isFastScope(symbol)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   589
                    method.load(getScopeProtoDepth(currentBlock, symbol));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   590
                    scopeCallFlags |= CALLSITE_FAST_SCOPE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   591
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   592
                    method.load(-1); // Bypass fast-scope code in shared callsite
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
                loadArgs(args);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
                final Type[] paramTypes = method.getTypesFromStack(args.size());
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   596
                final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNode.getType(), paramTypes, scopeCallFlags);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   597
                return scopeCall.generateInvoke(method);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   599
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
            private void scopeCall(final IdentNode node, final int flags) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
                load(node);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   602
                method.convert(Type.OBJECT); // foo() makes no sense if foo == 3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   603
                // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   604
                method.loadNull(); //the 'this'
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   605
                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), flags);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   606
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   607
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   608
            private void evalCall(final IdentNode node, final int flags) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   609
                load(node);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   610
                method.convert(Type.OBJECT); // foo() makes no sense if foo == 3
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   611
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   612
                final Label not_eval  = new Label("not_eval");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   613
                final Label eval_done = new Label("eval_done");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   614
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   615
                // check if this is the real built-in eval
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   616
                method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   617
                globalIsEval();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   618
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
                method.ifeq(not_eval);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   620
                // We don't need ScriptFunction object for 'eval'
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   621
                method.pop();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   622
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   623
                method.loadCompilerConstant(SCOPE); // Load up self (scope).
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   624
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   625
                final CallNode.EvalArgs evalArgs = callNode.getEvalArgs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   626
                // load evaluated code
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
   627
                load(evalArgs.getCode());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   628
                method.convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   629
                // special/extra 'eval' arguments
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
   630
                load(evalArgs.getThis());
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
   631
                method.load(evalArgs.getLocation());
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
   632
                method.load(evalArgs.getStrictMode());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   633
                method.convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   634
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   635
                // direct call to Global.directEval
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   636
                globalDirectEval();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   637
                method.convert(callNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   638
                method._goto(eval_done);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   639
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   640
                method.label(not_eval);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   641
                // This is some scope 'eval' or global eval replaced by user
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   642
                // but not the built-in ECMAScript 'eval' function call
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   643
                method.loadNull();
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   644
                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), flags);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   645
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   646
                method.label(eval_done);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   647
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   648
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   649
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   650
            public boolean enterIdentNode(final IdentNode node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   651
                final Symbol symbol = node.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   652
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   653
                if (symbol.isScope()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   654
                    final int flags = getCallSiteFlags() | CALLSITE_SCOPE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   655
                    final int useCount = symbol.getUseCount();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   656
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   657
                    // Threshold for generating shared scope callsite is lower for fast scope symbols because we know
17239
6dd68632cdcd 8011065: Problems when script implements an interface with variadic methods
attila
parents: 17233
diff changeset
   658
                    // we can dial in the correct scope. However, we also need to enable it for non-fast scopes to
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   659
                    // support huge scripts like mandreel.js.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   660
                    if (callNode.isEval()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   661
                        evalCall(node, flags);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   662
                    } else if (useCount <= SharedScopeCall.FAST_SCOPE_CALL_THRESHOLD
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
   663
                            || (!isFastScope(symbol) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD)
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   664
                            || CodeGenerator.this.lc.inDynamicScope()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   665
                        scopeCall(node, flags);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   666
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   667
                        sharedScopeCall(node, flags);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   668
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   669
                    assert method.peekType().equals(callNode.getType()) : method.peekType() + "!=" + callNode.getType();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   670
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   671
                    enterDefault(node);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   672
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   673
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   674
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   675
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   676
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   677
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   678
            public boolean enterAccessNode(final AccessNode node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   679
                load(node.getBase());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   680
                method.convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   681
                method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   682
                method.dynamicGet(node.getType(), node.getProperty().getName(), getCallSiteFlags(), true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   683
                method.swap();
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   684
                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   685
                assert method.peekType().equals(callNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   686
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   687
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   688
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   689
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   690
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   691
            public boolean enterFunctionNode(final FunctionNode origCallee) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   692
                // NOTE: visiting the callee will leave a constructed ScriptFunction object on the stack if
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   693
                // callee.needsCallee() == true
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   694
                final FunctionNode callee = (FunctionNode)origCallee.accept(CodeGenerator.this);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   695
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   696
                final boolean      isVarArg = callee.isVarArg();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
                final int          argCount = isVarArg ? -1 : callee.getParameters().size();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   699
                final String signature = new FunctionSignature(true, callee.needsCallee(), callee.getReturnType(), isVarArg ? null : callee.getParameters()).toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   700
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   701
                if (callee.isStrict()) { // self is undefined
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   702
                    method.loadUndefined(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   703
                } else { // get global from scope (which is the self)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   704
                    globalInstance();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   705
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   706
                loadArgs(args, signature, isVarArg, argCount);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   707
                assert callee.getCompileUnit() != null : "no compile unit for " + callee.getName() + " " + Debug.id(callee) + " " + callNode;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
   708
                method.invokestatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   709
                assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   710
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   711
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   712
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   714
            public boolean enterIndexNode(final IndexNode node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   715
                load(node.getBase());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   716
                method.convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   717
                method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   718
                load(node.getIndex());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
                final Type indexType = node.getIndex().getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   720
                if (indexType.isObject() || indexType.isBoolean()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   721
                    method.convert(Type.OBJECT); //TODO
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   723
                method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   724
                method.swap();
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   725
                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
                assert method.peekType().equals(callNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   727
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   728
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   731
            @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   732
            protected boolean enterDefault(final Node node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   733
                // Load up function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
                load(function);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   735
                method.convert(Type.OBJECT); //TODO, e.g. booleans can be used as functions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   736
                method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
   737
                method.dynamicCall(callNode.getType(), 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   738
                assert method.peekType().equals(callNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   739
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   740
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   741
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   742
        });
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   743
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   744
        method.store(callNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   745
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   746
        return false;
16147
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
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   750
    public boolean enterContinueNode(final ContinueNode continueNode) {
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
   751
        lineNumber(continueNode);
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
   752
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   753
        final LoopNode continueTo = lc.getContinueTo(continueNode.getLabel());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   754
        for (int i = 0; i < lc.getScopeNestingLevelTo(continueTo); i++) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   755
            closeWith();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   756
        }
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   757
        method.splitAwareGoto(lc, continueTo.getContinueLabel());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   758
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   759
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   760
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   761
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   762
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   763
    public boolean enterEmptyNode(final EmptyNode emptyNode) {
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
   764
        lineNumber(emptyNode);
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
   765
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   766
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   767
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   768
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   769
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   770
    public boolean enterExecuteNode(final ExecuteNode executeNode) {
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
   771
        lineNumber(executeNode);
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
   772
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   773
        final Node expression = executeNode.getExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   774
        expression.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   775
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   776
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   777
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   778
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   779
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   780
    public boolean enterForNode(final ForNode forNode) {
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
   781
        lineNumber(forNode);
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
   782
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   783
        if (forNode.isForIn()) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   784
            enterForIn(forNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   785
        } else {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   786
            enterFor(forNode);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   787
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   788
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   789
        return false;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   790
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   791
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   792
    private void enterFor(final ForNode forNode) {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   793
        final Node  init   = forNode.getInit();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   794
        final Node  test   = forNode.getTest();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   795
        final Block body   = forNode.getBody();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   796
        final Node  modify = forNode.getModify();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   797
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   798
        if (init != null) {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   799
            init.accept(this);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   800
        }
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   801
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   802
        final Label loopLabel = new Label("loop");
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   803
        final Label testLabel = new Label("test");
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   804
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   805
        method._goto(testLabel);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   806
        method.label(loopLabel);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   807
        body.accept(this);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   808
        method.label(forNode.getContinueLabel());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   809
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   810
        if (!body.isTerminal() && modify != null) {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   811
            load(modify);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   812
        }
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   813
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   814
        method.label(testLabel);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   815
        if (test != null) {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   816
            new BranchOptimizer(this, method).execute(test, loopLabel, true);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   817
        } else {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   818
            method._goto(loopLabel);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   819
        }
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   820
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   821
        method.label(forNode.getBreakLabel());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   822
    }
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   823
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   824
    private void enterForIn(final ForNode forNode) {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   825
        final Block body   = forNode.getBody();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   826
        final Node  modify = forNode.getModify();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   827
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   828
        final Symbol iter      = forNode.getIterator();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   829
        final Label  loopLabel = new Label("loop");
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   830
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   831
        Node init = forNode.getInit();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   832
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   833
        // We have to evaluate the optional initializer expression
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   834
        // of the iterator variable of the for-in statement.
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   835
        if (init instanceof VarNode) {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   836
            init.accept(this);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   837
            init = ((VarNode)init).getName();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   838
        }
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   839
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   840
        load(modify);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   841
        assert modify.getType().isObject();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   842
        method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   843
        method.store(iter);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   844
        method._goto(forNode.getContinueLabel());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   845
        method.label(loopLabel);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   846
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   847
        new Store<Node>(init) {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   848
            @Override
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   849
            protected void storeNonDiscard() {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   850
                return;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   851
            }
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   852
            @Override
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   853
            protected void evaluate() {
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   854
                method.load(iter);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   855
                method.invoke(interfaceCallNoLookup(Iterator.class, "next", Object.class));
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   856
            }
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   857
        }.store();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   858
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   859
        body.accept(this);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   860
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   861
        method.label(forNode.getContinueLabel());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   862
        method.load(iter);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   863
        method.invoke(interfaceCallNoLookup(Iterator.class, "hasNext", boolean.class));
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   864
        method.ifne(loopLabel);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   865
        method.label(forNode.getBreakLabel());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   866
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   867
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   868
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   869
     * Initialize the slots in a frame to undefined.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   870
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   871
     * @param block block with local vars.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   872
     */
16168
f0c208287983 8005976: Break out AccessSpecializer into one pass before CodeGenerator instead of iterative applications from CodeGenerator
lagergren
parents: 16152
diff changeset
   873
    private void initLocals(final Block block) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   874
        lc.nextFreeSlot(block);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   875
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   876
        final boolean isFunctionBody = lc.isFunctionBody();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   877
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   878
        final FunctionNode function = lc.getCurrentFunction();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   879
        if (isFunctionBody) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   880
            /* Fix the predefined slots so they have numbers >= 0, like varargs. */
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   881
            if (function.needsParentScope()) {
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   882
                initParentScope();
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   883
            }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   884
            if (function.needsArguments()) {
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   885
                initArguments(function);
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   886
            }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   887
        }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   888
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   889
        /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   890
         * Determine if block needs scope, if not, just do initSymbols for this block.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   891
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   892
        if (block.needsScope()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   893
            /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   894
             * Determine if function is varargs and consequently variables have to
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   895
             * be in the scope.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   896
             */
16252
3bfe9b68a0fa 8008648: Lazy JIT scope and callee semantics bugfixes. Broke out wallclock timer.
lagergren
parents: 16240
diff changeset
   897
            final boolean varsInScope = function.allVarsInScope();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   898
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
            // TODO for LET we can do better: if *block* does not contain any eval/with, we don't need its vars in scope.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   900
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   901
            final List<String> nameList = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   902
            final List<Symbol> locals   = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   903
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   904
            // Initalize symbols and values
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   905
            final List<Symbol> newSymbols = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   906
            final List<Symbol> values     = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   907
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   908
            final boolean hasArguments = function.needsArguments();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   909
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: 17255
diff changeset
   910
            for (final Symbol symbol : block.getSymbols()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   911
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   912
                if (symbol.isInternal() || symbol.isThis() || symbol.isTemp()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   913
                    continue;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   914
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   915
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   916
                if (symbol.isVar()) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   917
                    if (varsInScope || symbol.isScope()) {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   918
                        nameList.add(symbol.getName());
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   919
                        newSymbols.add(symbol);
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   920
                        values.add(null);
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   921
                        assert symbol.isScope()   : "scope for " + symbol + " should have been set in Lower already " + function.getName();
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   922
                        assert !symbol.hasSlot()  : "slot for " + symbol + " should have been removed in Lower already" + function.getName();
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   923
                    } else {
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   924
                        assert symbol.hasSlot() : symbol + " should have a slot only, no scope";
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   925
                        locals.add(symbol);
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   926
                    }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   927
                } else if (symbol.isParam() && (varsInScope || hasArguments || symbol.isScope())) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   928
                    nameList.add(symbol.getName());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   929
                    newSymbols.add(symbol);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   930
                    values.add(hasArguments ? null : symbol);
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   931
                    assert symbol.isScope()   : "scope for " + symbol + " should have been set in Lower already " + function.getName() + " varsInScope="+varsInScope+" hasArguments="+hasArguments+" symbol.isScope()=" + symbol.isScope();
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   932
                    assert !(hasArguments && symbol.hasSlot())  : "slot for " + symbol + " should have been removed in Lower already " + function.getName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   933
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   934
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   935
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   936
            // we may have locals that need to be initialized
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   937
            initSymbols(locals);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   938
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   939
            /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   940
             * Create a new object based on the symbols and values, generate
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   941
             * bootstrap code for object
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   942
             */
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   943
            final FieldObjectCreator<Symbol> foc = new FieldObjectCreator<Symbol>(this, nameList, newSymbols, values, true, hasArguments) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   944
                @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   945
                protected void loadValue(final Symbol value) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   946
                    method.load(value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   947
                }
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   948
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   949
                @Override
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   950
                protected void loadScope(MethodEmitter m) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   951
                    if (function.needsParentScope()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   952
                        m.loadCompilerConstant(SCOPE);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   953
                    } else {
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   954
                        m.loadNull();
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   955
                    }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   956
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   957
            };
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   958
            foc.makeObject(method);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   959
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   960
            // runScript(): merge scope into global
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   961
            if (isFunctionBody && function.isProgram()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   962
                method.invoke(ScriptRuntime.MERGE_SCOPE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   963
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   964
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   965
            method.storeCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   966
        } else {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   967
            // Since we don't have a scope, parameters didn't get assigned array indices by the FieldObjectCreator, so
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   968
            // we need to assign them separately here.
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   969
            int nextParam = 0;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   970
            if (isFunctionBody && function.isVarArg()) {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   971
                for (final IdentNode param : function.getParameters()) {
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   972
                    param.getSymbol().setFieldIndex(nextParam++);
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   973
                }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   974
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   975
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: 17255
diff changeset
   976
            initSymbols(block.getSymbols());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   977
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   978
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   979
        // Debugging: print symbols? @see --print-symbols flag
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   980
        printSymbols(block, (isFunctionBody ? "Function " : "Block in ") + (function.getIdent() == null ? "<anonymous>" : function.getIdent().getName()));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   981
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   982
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   983
    private void initArguments(final FunctionNode function) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   984
        method.loadCompilerConstant(VARARGS);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
   985
        if (function.needsCallee()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   986
            method.loadCompilerConstant(CALLEE);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   987
        } else {
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   988
            // If function is strict mode, "arguments.callee" is not populated, so we don't necessarily need the
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   989
            // caller.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   990
            assert function.isStrict();
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   991
            method.loadNull();
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   992
        }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   993
        method.load(function.getParameters().size());
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   994
        globalAllocateArguments();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   995
        method.storeCompilerConstant(ARGUMENTS);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   996
    }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   997
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
   998
    private void initParentScope() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   999
        method.loadCompilerConstant(CALLEE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1000
        method.invoke(ScriptFunction.GET_SCOPE);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1001
        method.storeCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1002
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1003
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1004
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1005
    public boolean enterFunctionNode(final FunctionNode functionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1006
        if (functionNode.isLazy()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1007
            // Must do it now; can't postpone it until leaveFunctionNode()
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1008
            newFunctionObject(functionNode, functionNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1009
            return false;
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  1010
        }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  1011
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1012
        LOG.info("=== BEGIN ", functionNode.getName());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1013
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1014
        assert functionNode.getCompileUnit() != null : "no compile unit for " + functionNode.getName() + " " + Debug.id(functionNode);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1015
        unit = lc.pushCompileUnit(functionNode.getCompileUnit());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1016
        assert lc.hasCompileUnits();
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1017
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1018
        method = lc.pushMethodEmitter(unit.getClassEmitter().method(functionNode));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1019
        // Mark end for variable tables.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1020
        method.begin();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1021
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1022
        return true;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1023
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1024
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1025
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  1026
    public Node leaveFunctionNode(final FunctionNode functionNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1027
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1028
            method.end(); // wrap up this method
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1029
            unit   = lc.popCompileUnit(functionNode.getCompileUnit());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1030
            method = lc.popMethodEmitter(method);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1031
            LOG.info("=== END ", functionNode.getName());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1032
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1033
            final FunctionNode newFunctionNode = functionNode.setState(lc, CompilationState.EMITTED);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1034
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1035
            newFunctionObject(newFunctionNode, functionNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1036
            return newFunctionNode;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1037
        } catch (final Throwable t) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1038
            Context.printStackTrace(t);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1039
            final VerifyError e = new VerifyError("Code generation bug in \"" + functionNode.getName() + "\": likely stack misaligned: " + t + " " + functionNode.getSource().getName());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1040
            e.initCause(t);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1041
            throw e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1042
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1043
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1044
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1045
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1046
    public boolean enterIdentNode(final IdentNode identNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1047
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1048
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1049
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1050
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1051
    public boolean enterIfNode(final IfNode ifNode) {
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
  1052
        lineNumber(ifNode);
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
  1053
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1054
        final Node  test = ifNode.getTest();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1055
        final Block pass = ifNode.getPass();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1056
        final Block fail = ifNode.getFail();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1057
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1058
        final Label failLabel  = new Label("if_fail");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1059
        final Label afterLabel = fail == null ? failLabel : new Label("if_done");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1060
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1061
        new BranchOptimizer(this, method).execute(test, failLabel, false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1062
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1063
        boolean passTerminal = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1064
        boolean failTerminal = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1065
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1066
        pass.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1067
        if (!pass.hasTerminalFlags()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1068
            method._goto(afterLabel); //don't fallthru to fail block
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1069
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1070
            passTerminal = pass.isTerminal();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1071
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1072
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1073
        if (fail != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1074
            method.label(failLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1075
            fail.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1076
            failTerminal = fail.isTerminal();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1077
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1078
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1079
        //if if terminates, put the after label there
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1080
        if (!passTerminal || !failTerminal) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1081
            method.label(afterLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1082
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1083
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1084
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1085
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1086
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1087
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1088
    public boolean enterIndexNode(final IndexNode indexNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1089
        load(indexNode);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1090
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1091
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1092
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
  1093
    private void lineNumber(final Statement statement) {
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
  1094
        final int lineNumber = statement.getLineNumber();
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  1095
        if (lineNumber != lastLineNumber) {
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
  1096
            method.lineNumber(statement.getLineNumber());
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  1097
        }
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
  1098
        lastLineNumber = lineNumber;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1099
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1100
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1101
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1102
     * Load a list of nodes as an array of a specific type
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1103
     * The array will contain the visited nodes.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1104
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1105
     * @param arrayLiteralNode the array of contents
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1106
     * @param arrayType        the type of the array, e.g. ARRAY_NUMBER or ARRAY_OBJECT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1107
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1108
     * @return the method generator that was used
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1109
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1110
    private MethodEmitter loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1111
        assert arrayType == Type.INT_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1112
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1113
        final Node[]          nodes    = arrayLiteralNode.getValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1114
        final Object          presets  = arrayLiteralNode.getPresets();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1115
        final int[]           postsets = arrayLiteralNode.getPostsets();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1116
        final Class<?>        type     = arrayType.getTypeClass();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1117
        final List<ArrayUnit> units    = arrayLiteralNode.getUnits();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1118
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1119
        loadConstant(presets);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1120
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1121
        final Type elementType = arrayType.getElementType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1122
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1123
        if (units != null) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1124
            final MethodEmitter savedMethod = method;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1125
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1126
            for (final ArrayUnit arrayUnit : units) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1127
                unit = lc.pushCompileUnit(arrayUnit.getCompileUnit());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1128
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1129
                final String className = unit.getUnitClassName();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1130
                final String name      = lc.getCurrentFunction().uniqueName(SPLIT_PREFIX.symbolName());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1131
                final String signature = methodDescriptor(type, Object.class, ScriptFunction.class, ScriptObject.class, type);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1132
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1133
                final MethodEmitter me = unit.getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1134
                method = lc.pushMethodEmitter(me);
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1135
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1136
                method.setFunctionNode(lc.getCurrentFunction());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1137
                method.begin();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1138
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1139
                fixScopeSlot();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1140
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1141
                method.load(arrayType, SPLIT_ARRAY_ARG.slot());
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1142
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1143
                for (int i = arrayUnit.getLo(); i < arrayUnit.getHi(); i++) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1144
                    storeElement(nodes, elementType, postsets[i]);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1145
                }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1146
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1147
                method._return();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1148
                method.end();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1149
                method = lc.popMethodEmitter(me);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1150
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1151
                assert method == savedMethod;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1152
                method.loadCompilerConstant(THIS);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1153
                method.swap();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1154
                method.loadCompilerConstant(CALLEE);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1155
                method.swap();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1156
                method.loadCompilerConstant(SCOPE);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1157
                method.swap();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1158
                method.invokestatic(className, name, signature);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1159
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1160
                unit = lc.popCompileUnit(unit);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1161
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1162
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1163
            return method;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1164
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1165
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1166
        for (final int postset : postsets) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1167
            storeElement(nodes, elementType, postset);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1168
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1169
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1170
        return method;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1171
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1172
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1173
    private void storeElement(final Node[] nodes, final Type elementType, final int index) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1174
        method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1175
        method.load(index);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1176
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1177
        final Node element = nodes[index];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1178
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1179
        if (element == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1180
            method.loadEmpty(elementType);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1181
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1182
            assert elementType.isEquivalentTo(element.getType()) : "array element type doesn't match array type";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1183
            load(element);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1184
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1185
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1186
        method.arraystore();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1187
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1188
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1189
    private MethodEmitter loadArgsArray(final List<Node> args) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1190
        final Object[] array = new Object[args.size()];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1191
        loadConstant(array);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1192
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1193
        for (int i = 0; i < args.size(); i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1194
            method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1195
            method.load(i);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1196
            load(args.get(i)).convert(Type.OBJECT); //has to be upcast to object or we fail
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1197
            method.arraystore();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1198
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1199
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1200
        return method;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1201
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1202
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1203
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1204
     * Load a constant from the constant array. This is only public to be callable from the objects
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1205
     * subpackage. Do not call directly.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1206
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1207
     * @param string string to load
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1208
     */
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1209
    void loadConstant(final String string) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1210
        final String       unitClassName = unit.getUnitClassName();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1211
        final ClassEmitter classEmitter  = unit.getClassEmitter();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1212
        final int          index         = compiler.getConstantData().add(string);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1213
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1214
        method.load(index);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1215
        method.invokestatic(unitClassName, GET_STRING.symbolName(), methodDescriptor(String.class, int.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1216
        classEmitter.needGetConstantMethod(String.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1217
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1218
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1219
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1220
     * Load a constant from the constant array. This is only public to be callable from the objects
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1221
     * subpackage. Do not call directly.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1222
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1223
     * @param object object to load
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1224
     */
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1225
    void loadConstant(final Object object) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1226
        final String       unitClassName = unit.getUnitClassName();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1227
        final ClassEmitter classEmitter  = unit.getClassEmitter();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1228
        final int          index         = compiler.getConstantData().add(object);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1229
        final Class<?>     cls           = object.getClass();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1230
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1231
        if (cls == PropertyMap.class) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1232
            method.load(index);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1233
            method.invokestatic(unitClassName, GET_MAP.symbolName(), methodDescriptor(PropertyMap.class, int.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1234
            classEmitter.needGetConstantMethod(PropertyMap.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1235
        } else if (cls.isArray()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1236
            method.load(index);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1237
            final String methodName = ClassEmitter.getArrayMethodName(cls);
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1238
            method.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1239
            classEmitter.needGetConstantMethod(cls);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1240
        } else {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  1241
            method.loadConstants().load(index).arrayload();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1242
            if (cls != Object.class) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1243
                method.checkcast(cls);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1244
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1245
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1246
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1247
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1248
    // literal values
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1249
    private MethodEmitter load(final LiteralNode<?> node) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1250
        final Object value = node.getValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1251
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1252
        if (value == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1253
            method.loadNull();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1254
        } else if (value instanceof Undefined) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1255
            method.loadUndefined(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1256
        } else if (value instanceof String) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1257
            final String string = (String)value;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1258
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1259
            if (string.length() > (MethodEmitter.LARGE_STRING_THRESHOLD / 3)) { // 3 == max bytes per encoded char
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1260
                loadConstant(string);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1261
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1262
                method.load(string);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1263
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1264
        } else if (value instanceof RegexToken) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1265
            loadRegex((RegexToken)value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1266
        } else if (value instanceof Boolean) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1267
            method.load((Boolean)value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1268
        } else if (value instanceof Integer) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1269
            method.load((Integer)value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1270
        } else if (value instanceof Long) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1271
            method.load((Long)value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1272
        } else if (value instanceof Double) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1273
            method.load((Double)value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1274
        } else if (node instanceof ArrayLiteralNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1275
            final ArrayType type = (ArrayType)node.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1276
            loadArray((ArrayLiteralNode)node, type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1277
            globalAllocateArray(type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1278
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1279
            assert false : "Unknown literal for " + node.getClass() + " " + value.getClass() + " " + value;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1280
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1281
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1282
        return method;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1283
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1284
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1285
    private MethodEmitter loadRegexToken(final RegexToken value) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1286
        method.load(value.getExpression());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1287
        method.load(value.getOptions());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1288
        return globalNewRegExp();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1289
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1290
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1291
    private MethodEmitter loadRegex(final RegexToken regexToken) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1292
        if (regexFieldCount > MAX_REGEX_FIELDS) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1293
            return loadRegexToken(regexToken);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1294
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1295
        // emit field
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1296
        final String       regexName    = lc.getCurrentFunction().uniqueName(REGEX_PREFIX.symbolName());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1297
        final ClassEmitter classEmitter = unit.getClassEmitter();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1298
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1299
        classEmitter.field(EnumSet.of(PRIVATE, STATIC), regexName, Object.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1300
        regexFieldCount++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1301
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1302
        // get field, if null create new regex, finally clone regex object
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1303
        method.getStatic(unit.getUnitClassName(), regexName, typeDescriptor(Object.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1304
        method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1305
        final Label cachedLabel = new Label("cached");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1306
        method.ifnonnull(cachedLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1307
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1308
        method.pop();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1309
        loadRegexToken(regexToken);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1310
        method.dup();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1311
        method.putStatic(unit.getUnitClassName(), regexName, typeDescriptor(Object.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1312
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1313
        method.label(cachedLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1314
        globalRegExpCopy();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1315
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1316
        return method;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1317
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1318
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1319
    @SuppressWarnings("rawtypes")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1320
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1321
    public boolean enterLiteralNode(final LiteralNode literalNode) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1322
        assert literalNode.getSymbol() != null : literalNode + " has no symbol";
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1323
        load(literalNode).store(literalNode.getSymbol());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1324
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1325
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1326
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1327
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1328
    public boolean enterObjectNode(final ObjectNode objectNode) {
17981
9b8e085aa1fe 8015955: ObjectNode.elements should be stronger typed
attila
parents: 17969
diff changeset
  1329
        final List<PropertyNode> elements = objectNode.getElements();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1330
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1331
        final List<String> keys    = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1332
        final List<Symbol> symbols = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1333
        final List<Node>   values  = new ArrayList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1334
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1335
        boolean hasGettersSetters = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1336
17981
9b8e085aa1fe 8015955: ObjectNode.elements should be stronger typed
attila
parents: 17969
diff changeset
  1337
        for (PropertyNode propertyNode: elements) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1338
            final Node         value        = propertyNode.getValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1339
            final String       key          = propertyNode.getKeyName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1340
            final Symbol       symbol       = value == null ? null : propertyNode.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1341
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1342
            if (value == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1343
                hasGettersSetters = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1344
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1345
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1346
            keys.add(key);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1347
            symbols.add(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1348
            values.add(value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1349
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1350
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1351
        new FieldObjectCreator<Node>(this, keys, symbols, values) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1352
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1353
            protected void loadValue(final Node node) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1354
                load(node);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1355
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1356
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1357
            /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1358
             * Ensure that the properties start out as object types so that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1359
             * we can do putfield initializations instead of dynamicSetIndex
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1360
             * which would be the case to determine initial property type
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1361
             * otherwise.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1362
             *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1363
             * Use case, it's very expensive to do a million var x = {a:obj, b:obj}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1364
             * just to have to invalidate them immediately on initialization
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1365
             *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1366
             * see NASHORN-594
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1367
             */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1368
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1369
            protected MapCreator newMapCreator(final Class<?> fieldObjectClass) {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1370
                return new MapCreator(fieldObjectClass, keys, symbols) {
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1371
                    @Override
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1372
                    protected int getPropertyFlags(final Symbol symbol, final boolean isVarArg) {
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1373
                        return super.getPropertyFlags(symbol, isVarArg) | Property.IS_ALWAYS_OBJECT;
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1374
                    }
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1375
                };
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1376
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1377
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1378
        }.makeObject(method);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1379
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1380
        method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1381
        globalObjectPrototype();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1382
        method.invoke(ScriptObject.SET_PROTO);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1383
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1384
        if (!hasGettersSetters) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1385
            method.store(objectNode.getSymbol());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1386
            return false;
16147
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
        for (final Node element : elements) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  1390
            final PropertyNode propertyNode = (PropertyNode)element;
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  1391
            final Object       key          = propertyNode.getKey();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1392
            final FunctionNode getter       = propertyNode.getGetter();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1393
            final FunctionNode setter       = propertyNode.getSetter();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1394
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1395
            if (getter == null && setter == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1396
                continue;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1397
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1398
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1399
            method.dup().loadKey(key);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1400
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1401
            if (getter == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1402
                method.loadNull();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1403
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1404
                getter.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1405
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1406
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1407
            if (setter == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1408
                method.loadNull();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1409
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1410
                setter.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1411
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1412
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1413
            method.invoke(ScriptObject.SET_USER_ACCESSORS);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1414
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1415
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1416
        method.store(objectNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1417
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1418
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1419
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1420
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1421
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1422
    public boolean enterReturnNode(final ReturnNode returnNode) {
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
  1423
        lineNumber(returnNode);
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
  1424
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1425
        method.registerReturn();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1426
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1427
        final Type returnType = lc.getCurrentFunction().getReturnType();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1428
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1429
        final Node expression = returnNode.getExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1430
        if (expression != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1431
            load(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1432
        } else {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1433
            method.loadUndefined(returnType);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1434
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1435
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1436
        method._return(returnType);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1437
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1438
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1439
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1440
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1441
    private static boolean isNullLiteral(final Node node) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1442
        return node instanceof LiteralNode<?> && ((LiteralNode<?>) node).isNull();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1443
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1444
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1445
    private boolean nullCheck(final RuntimeNode runtimeNode, final List<Node> args, final String signature) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1446
        final Request request = runtimeNode.getRequest();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1447
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1448
        if (!Request.isEQ(request) && !Request.isNE(request)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1449
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1450
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1451
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1452
        assert args.size() == 2 : "EQ or NE or TYPEOF need two args";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1453
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1454
        Node lhs = args.get(0);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1455
        Node rhs = args.get(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1456
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1457
        if (isNullLiteral(lhs)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1458
            final Node tmp = lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1459
            lhs = rhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1460
            rhs = tmp;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1461
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1462
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1463
        if (isNullLiteral(rhs)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1464
            final Label trueLabel  = new Label("trueLabel");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1465
            final Label falseLabel = new Label("falseLabel");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1466
            final Label endLabel   = new Label("end");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1467
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1468
            load(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1469
            method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1470
            if (Request.isEQ(request)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1471
                method.ifnull(trueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1472
            } else if (Request.isNE(request)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1473
                method.ifnonnull(trueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1474
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1475
                assert false : "Invalid request " + request;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1476
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1477
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1478
            method.label(falseLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1479
            load(rhs);
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1480
            method.invokestatic(CompilerConstants.className(ScriptRuntime.class), request.toString(), signature);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1481
            method._goto(endLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1482
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1483
            method.label(trueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1484
            // if NE (not strict) this can be "undefined != null" which is supposed to be false
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1485
            if (request == Request.NE) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1486
                method.loadUndefined(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1487
                final Label isUndefined = new Label("isUndefined");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1488
                final Label afterUndefinedCheck = new Label("afterUndefinedCheck");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1489
                method.if_acmpeq(isUndefined);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1490
                // not undefined
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1491
                method.load(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1492
                method._goto(afterUndefinedCheck);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1493
                method.label(isUndefined);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1494
                method.load(false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1495
                method.label(afterUndefinedCheck);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1496
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1497
                method.pop();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1498
                method.load(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1499
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1500
            method.label(endLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1501
            method.convert(runtimeNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1502
            method.store(runtimeNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1503
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1504
            return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1505
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1506
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1507
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1508
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1509
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1510
    private boolean specializationCheck(final RuntimeNode.Request request, final Node node, final List<Node> args) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1511
        if (!request.canSpecialize()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1512
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1513
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1514
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1515
        assert args.size() == 2;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1516
        final Type returnType = node.getType();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1517
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1518
        load(args.get(0));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1519
        load(args.get(1));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1520
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1521
        Request finalRequest = request;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1522
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1523
        //if the request is a comparison, i.e. one that can be reversed
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1524
        //it keeps its semantic, but make sure that the object comes in
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1525
        //last
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1526
        final Request reverse = Request.reverse(request);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1527
        if (method.peekType().isObject() && reverse != null) { //rhs is object
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1528
            if (!method.peekType(1).isObject()) { //lhs is not object
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1529
                method.swap(); //prefer object as lhs
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1530
                finalRequest = reverse;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1531
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1532
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1533
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1534
        method.dynamicRuntimeCall(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1535
                new SpecializedRuntimeNode(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1536
                    finalRequest,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1537
                    new Type[] {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1538
                        method.peekType(1),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1539
                        method.peekType()
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1540
                    },
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1541
                    returnType).getInitialName(),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1542
                returnType,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1543
                finalRequest);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1544
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1545
        method.convert(node.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1546
        method.store(node.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1547
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1548
        return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1549
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1550
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1551
    private static boolean isReducible(final Request request) {
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1552
        return Request.isComparison(request) || request == Request.ADD;
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1553
    }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1554
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1555
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1556
    public boolean enterRuntimeNode(final RuntimeNode runtimeNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1557
        /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1558
         * First check if this should be something other than a runtime node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1559
         * AccessSpecializer might have changed the type
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1560
         *
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1561
         * TODO - remove this - Access Specializer will always know after Attr/Lower
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1562
         */
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1563
        if (runtimeNode.isPrimitive() && !runtimeNode.isFinal() && isReducible(runtimeNode.getRequest())) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1564
            final Node lhs = runtimeNode.getArgs().get(0);
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1565
            assert runtimeNode.getArgs().size() > 1 : runtimeNode + " must have two args";
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  1566
            final Node rhs = runtimeNode.getArgs().get(1);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1567
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1568
            final Type   type   = runtimeNode.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1569
            final Symbol symbol = runtimeNode.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1570
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1571
            switch (runtimeNode.getRequest()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1572
            case EQ:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1573
            case EQ_STRICT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1574
                return enterCmp(lhs, rhs, Condition.EQ, type, symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1575
            case NE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1576
            case NE_STRICT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1577
                return enterCmp(lhs, rhs, Condition.NE, type, symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1578
            case LE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1579
                return enterCmp(lhs, rhs, Condition.LE, type, symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1580
            case LT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1581
                return enterCmp(lhs, rhs, Condition.LT, type, symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1582
            case GE:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1583
                return enterCmp(lhs, rhs, Condition.GE, type, symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1584
            case GT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1585
                return enterCmp(lhs, rhs, Condition.GT, type, symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1586
            case ADD:
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1587
                Type widest = Type.widest(lhs.getType(), rhs.getType());
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1588
                load(lhs);
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1589
                method.convert(widest);
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1590
                load(rhs);
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1591
                method.convert(widest);
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1592
                method.add();
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1593
                method.convert(type);
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1594
                method.store(symbol);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1595
                return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1596
            default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1597
                // it's ok to send this one on with only primitive arguments, maybe INSTANCEOF(true, true) or similar
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1598
                // assert false : runtimeNode + " has all primitive arguments. This is an inconsistent state";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1599
                break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1600
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1601
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1602
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1603
        // Get the request arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1604
        final List<Node> args = runtimeNode.getArgs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1605
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
  1606
        if (nullCheck(runtimeNode, args, new FunctionSignature(false, false, runtimeNode.getType(), args).toString())) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1607
            return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1608
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1609
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  1610
        if (!runtimeNode.isFinal() && specializationCheck(runtimeNode.getRequest(), runtimeNode, args)) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1611
            return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1612
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1613
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1614
        for (final Node arg : runtimeNode.getArgs()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1615
            load(arg).convert(Type.OBJECT); //TODO this should not be necessary below Lower
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1616
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1617
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1618
        method.invokestatic(
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1619
            CompilerConstants.className(ScriptRuntime.class),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1620
            runtimeNode.getRequest().toString(),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1621
            new FunctionSignature(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1622
                false,
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
  1623
                false,
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1624
                runtimeNode.getType(),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1625
                runtimeNode.getArgs().size()).toString());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1626
        method.convert(runtimeNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1627
        method.store(runtimeNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1628
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1629
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1630
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1631
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1632
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1633
    public boolean enterSplitNode(final SplitNode splitNode) {
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
  1634
        lineNumber(splitNode);
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
  1635
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1636
        final CompileUnit splitCompileUnit = splitNode.getCompileUnit();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1637
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1638
        final FunctionNode fn   = lc.getCurrentFunction();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1639
        final String className  = splitCompileUnit.getUnitClassName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1640
        final String name       = splitNode.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1641
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1642
        final Class<?>   rtype          = fn.getReturnType().getTypeClass();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1643
        final boolean    needsArguments = fn.needsArguments();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1644
        final Class<?>[] ptypes         = needsArguments ?
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16210
diff changeset
  1645
                new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class, Object.class} :
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16210
diff changeset
  1646
                new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class};
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1647
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1648
        final MethodEmitter caller = method;
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1649
        unit = lc.pushCompileUnit(splitCompileUnit);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1650
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1651
        final Call splitCall = staticCallNoLookup(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1652
            className,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1653
            name,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1654
            methodDescriptor(rtype, ptypes));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1655
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1656
        final MethodEmitter splitEmitter =
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1657
                splitCompileUnit.getClassEmitter().method(
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1658
                        splitNode,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1659
                        name,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1660
                        rtype,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1661
                        ptypes);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1662
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1663
        method = lc.pushMethodEmitter(splitEmitter);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1664
        method.setFunctionNode(fn);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1665
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1666
        if (fn.needsCallee()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1667
            caller.loadCompilerConstant(CALLEE);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  1668
        } else {
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  1669
            caller.loadNull();
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  1670
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1671
        caller.loadCompilerConstant(THIS);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1672
        caller.loadCompilerConstant(SCOPE);
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  1673
        if (needsArguments) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1674
            caller.loadCompilerConstant(ARGUMENTS);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1675
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1676
        caller.invoke(splitCall);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1677
        caller.storeCompilerConstant(RETURN);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1678
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1679
        method.begin();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1680
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1681
        method.loadUndefined(fn.getReturnType());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1682
        method.storeCompilerConstant(RETURN);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1683
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1684
        fixScopeSlot();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1685
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1686
        return true;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1687
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1688
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1689
    private void fixScopeSlot() {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1690
        if (lc.getCurrentFunction().compilerConstant(SCOPE).getSlot() != SCOPE.slot()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1691
            // TODO hack to move the scope to the expected slot (that's needed because split methods reuse the same slots as the root method)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1692
            method.load(Type.typeFor(ScriptObject.class), SCOPE.slot());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1693
            method.storeCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1694
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1695
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1696
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1697
    @Override
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  1698
    public Node leaveSplitNode(final SplitNode splitNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1699
        assert method instanceof SplitMethodEmitter;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1700
        final boolean     hasReturn = method.hasReturn();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1701
        final List<Label> targets   = method.getExternalTargets();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1702
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1703
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1704
            // Wrap up this method.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1705
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1706
            method.loadCompilerConstant(RETURN);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1707
            method._return(lc.getCurrentFunction().getReturnType());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1708
            method.end();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1709
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1710
            unit   = lc.popCompileUnit(splitNode.getCompileUnit());
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1711
            method = lc.popMethodEmitter(method);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1712
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1713
        } catch (final Throwable t) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1714
            Context.printStackTrace(t);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1715
            final VerifyError e = new VerifyError("Code generation bug in \"" + splitNode.getName() + "\": likely stack misaligned: " + t + " " + lc.getCurrentFunction().getSource().getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1716
            e.initCause(t);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1717
            throw e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1718
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1719
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1720
        // Handle return from split method if there was one.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1721
        final MethodEmitter caller = method;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1722
        final int     targetCount = targets.size();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1723
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1724
        //no external jump targets or return in switch node
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1725
        if (!hasReturn && targets.isEmpty()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1726
            return splitNode;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1727
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1728
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1729
        caller.loadCompilerConstant(SCOPE);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1730
        caller.checkcast(Scope.class);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1731
        caller.invoke(Scope.GET_SPLIT_STATE);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1732
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1733
        final Label breakLabel = new Label("no_split_state");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1734
        // Split state is -1 for no split state, 0 for return, 1..n+1 for break/continue
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1735
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1736
        //the common case is that we don't need a switch
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1737
        if (targetCount == 0) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1738
            assert hasReturn;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1739
            caller.ifne(breakLabel);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1740
            //has to be zero
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1741
            caller.label(new Label("split_return"));
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1742
            method.loadCompilerConstant(RETURN);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1743
            caller._return(lc.getCurrentFunction().getReturnType());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1744
            caller.label(breakLabel);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1745
        } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1746
            assert !targets.isEmpty();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1747
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1748
            final int     low         = hasReturn ? 0 : 1;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1749
            final int     labelCount  = targetCount + 1 - low;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1750
            final Label[] labels      = new Label[labelCount];
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1751
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1752
            for (int i = 0; i < labelCount; i++) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1753
                labels[i] = new Label(i == 0 ? "split_return" : "split_" + targets.get(i - 1));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1754
            }
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1755
            caller.tableswitch(low, targetCount, breakLabel, labels);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1756
            for (int i = low; i <= targetCount; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1757
                caller.label(labels[i - low]);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1758
                if (i == 0) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1759
                    caller.loadCompilerConstant(RETURN);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1760
                    caller._return(lc.getCurrentFunction().getReturnType());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1761
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1762
                    // Clear split state.
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1763
                    caller.loadCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1764
                    caller.checkcast(Scope.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1765
                    caller.load(-1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1766
                    caller.invoke(Scope.SET_SPLIT_STATE);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1767
                    caller.splitAwareGoto(lc, targets.get(i - 1));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1768
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1769
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1770
            caller.label(breakLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1771
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1772
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1773
        return splitNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1774
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1775
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1776
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1777
    public boolean enterSwitchNode(final SwitchNode switchNode) {
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
  1778
        lineNumber(switchNode);
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
  1779
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1780
        final Node           expression  = switchNode.getExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1781
        final Symbol         tag         = switchNode.getTag();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1782
        final boolean        allInteger  = tag.getSymbolType().isInteger();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1783
        final List<CaseNode> cases       = switchNode.getCases();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1784
        final CaseNode       defaultCase = switchNode.getDefaultCase();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1785
        final Label          breakLabel  = switchNode.getBreakLabel();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1786
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1787
        Label defaultLabel = breakLabel;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1788
        boolean hasDefault = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1789
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1790
        if (defaultCase != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1791
            defaultLabel = defaultCase.getEntry();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1792
            hasDefault = true;
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 (cases.isEmpty()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1796
            method.label(breakLabel);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1797
            return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1798
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1799
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1800
        if (allInteger) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1801
            // Tree for sorting values.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1802
            final TreeMap<Integer, Label> tree = new TreeMap<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1803
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1804
            // Build up sorted tree.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1805
            for (final CaseNode caseNode : cases) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1806
                final Node test = caseNode.getTest();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1807
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1808
                if (test != null) {
16235
cc200fdc3478 8008206: The allInteger case for SwitchNode generation in CodeGenerator assumes integer LITERALS only.
lagergren
parents: 16233
diff changeset
  1809
                    final Integer value = (Integer)((LiteralNode<?>)test).getValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1810
                    final Label   entry = caseNode.getEntry();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1811
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1812
                    // Take first duplicate.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1813
                    if (!(tree.containsKey(value))) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1814
                        tree.put(value, entry);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1815
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1816
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1817
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1818
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1819
            // Copy values and labels to arrays.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1820
            final int       size   = tree.size();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1821
            final Integer[] values = tree.keySet().toArray(new Integer[size]);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1822
            final Label[]   labels = tree.values().toArray(new Label[size]);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1823
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1824
            // Discern low, high and range.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1825
            final int lo    = values[0];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1826
            final int hi    = values[size - 1];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1827
            final int range = hi - lo + 1;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1828
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1829
            // Find an unused value for default.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1830
            int deflt = Integer.MIN_VALUE;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1831
            for (final int value : values) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1832
                if (deflt == value) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1833
                    deflt++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1834
                } else if (deflt < value) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1835
                    break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1836
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1837
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1838
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1839
            // Load switch expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1840
            load(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1841
            final Type type = expression.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1842
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1843
            // If expression not int see if we can convert, if not use deflt to trigger default.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1844
            if (!type.isInteger()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1845
                method.load(deflt);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1846
                method.invoke(staticCallNoLookup(ScriptRuntime.class, "switchTagAsInt", int.class, type.getTypeClass(), int.class));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1847
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1848
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1849
            // If reasonable size and not too sparse (80%), use table otherwise use lookup.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1850
            if (range > 0 && range < 4096 && range < (size * 5 / 4)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1851
                final Label[] table = new Label[range];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1852
                Arrays.fill(table, defaultLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1853
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1854
                for (int i = 0; i < size; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1855
                    final int value = values[i];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1856
                    table[value - lo] = labels[i];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1857
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1858
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1859
                method.tableswitch(lo, hi, defaultLabel, table);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1860
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1861
                final int[] ints = new int[size];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1862
                for (int i = 0; i < size; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1863
                    ints[i] = values[i];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1864
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1865
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1866
                method.lookupswitch(defaultLabel, ints, labels);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1867
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1868
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1869
            load(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1870
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1871
            if (expression.getType().isInteger()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1872
                method.convert(Type.NUMBER).dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1873
                method.store(tag);
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  1874
                method.conditionalJump(Condition.NE, true, defaultLabel);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1875
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1876
                method.store(tag);
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
            for (final CaseNode caseNode : cases) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1880
                final Node test = caseNode.getTest();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1881
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1882
                if (test != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1883
                    method.load(tag);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1884
                    load(test);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1885
                    method.invoke(ScriptRuntime.EQ_STRICT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1886
                    method.ifne(caseNode.getEntry());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1887
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1888
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1889
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1890
            method._goto(hasDefault ? defaultLabel : breakLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1891
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1892
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1893
        for (final CaseNode caseNode : cases) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1894
            method.label(caseNode.getEntry());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1895
            caseNode.getBody().accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1896
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1897
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1898
        if (!switchNode.isTerminal()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1899
            method.label(breakLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1900
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1901
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1902
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1903
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1904
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1905
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1906
    public boolean enterThrowNode(final ThrowNode throwNode) {
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
  1907
        lineNumber(throwNode);
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
  1908
17745
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1909
        if (throwNode.isSyntheticRethrow()) {
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1910
            //do not wrap whatever this is in an ecma exception, just rethrow it
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1911
            load(throwNode.getExpression());
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1912
            method.athrow();
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1913
            return false;
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1914
        }
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1915
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1916
        method._new(ECMAException.class).dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1917
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1918
        final Source source     = lc.getCurrentFunction().getSource();
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17518
diff changeset
  1919
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1920
        final Node   expression = throwNode.getExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1921
        final int    position   = throwNode.position();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1922
        final int    line       = source.getLine(position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1923
        final int    column     = source.getColumn(position);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1924
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1925
        load(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1926
        assert expression.getType().isObject();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1927
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1928
        method.load(source.getName());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1929
        method.load(line);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1930
        method.load(column);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1931
        method.invoke(ECMAException.THROW_INIT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1932
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1933
        method.athrow();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1934
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1935
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1936
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1937
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1938
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1939
    public boolean enterTryNode(final TryNode tryNode) {
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  1940
        lineNumber(tryNode);
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
  1941
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1942
        final Block       body        = tryNode.getBody();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1943
        final List<Block> catchBlocks = tryNode.getCatchBlocks();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1944
        final Symbol      symbol      = tryNode.getException();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1945
        final Label       entry       = new Label("try");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1946
        final Label       recovery    = new Label("catch");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1947
        final Label       exit        = tryNode.getExit();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1948
        final Label       skip        = new Label("skip");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1949
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1950
        method.label(entry);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1951
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1952
        body.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1953
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1954
        if (!body.hasTerminalFlags()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1955
            method._goto(skip);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1956
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1957
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1958
        method.label(exit);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1959
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1960
        method._catch(recovery);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1961
        method.store(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1962
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1963
        for (int i = 0; i < catchBlocks.size(); i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1964
            final Block catchBlock = catchBlocks.get(i);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1965
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1966
            //TODO this is very ugly - try not to call enter/leave methods directly
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1967
            //better to use the implicit lexical context scoping given by the visitor's
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1968
            //accept method.
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1969
            lc.push(catchBlock);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1970
            enterBlock(catchBlock);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1971
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1972
            final CatchNode catchNode          = (CatchNode)catchBlocks.get(i).getStatements().get(0);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1973
            final IdentNode exception          = catchNode.getException();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1974
            final Node      exceptionCondition = catchNode.getExceptionCondition();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1975
            final Block     catchBody          = catchNode.getBody();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1976
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1977
            new Store<IdentNode>(exception) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1978
                @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1979
                protected void storeNonDiscard() {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1980
                    return;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1981
                }
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  1982
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1983
                @Override
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1984
                protected void evaluate() {
17745
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1985
                    if (catchNode.isSyntheticRethrow()) {
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1986
                        method.load(symbol);
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1987
                        return;
86e5a15b3b20 8014426: Original exception no longer thrown away when a finally rethrows
lagergren
parents: 17524
diff changeset
  1988
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1989
                    /*
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1990
                     * If caught object is an instance of ECMAException, then
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1991
                     * bind obj.thrown to the script catch var. Or else bind the
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1992
                     * caught object itself to the script catch var.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1993
                     */
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1994
                    final Label notEcmaException = new Label("no_ecma_exception");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1995
                    method.load(symbol).dup()._instanceof(ECMAException.class).ifeq(notEcmaException);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1996
                    method.checkcast(ECMAException.class); //TODO is this necessary?
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1997
                    method.getField(ECMAException.THROWN);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1998
                    method.label(notEcmaException);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  1999
                }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2000
            }.store();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2001
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2002
            final Label next;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2003
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2004
            if (exceptionCondition != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2005
                next = new Label("next");
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2006
                load(exceptionCondition).convert(Type.BOOLEAN).ifeq(next);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2007
            } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2008
                next = null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2009
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2010
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2011
            catchBody.accept(this);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2012
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2013
            if (i + 1 != catchBlocks.size() && !catchBody.hasTerminalFlags()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2014
                method._goto(skip);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2015
            }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2016
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2017
            if (next != null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2018
                if (i + 1 == catchBlocks.size()) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2019
                    // no next catch block - rethrow if condition failed
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2020
                    method._goto(skip);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2021
                    method.label(next);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2022
                    method.load(symbol).athrow();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2023
                } else {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2024
                    method.label(next);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2025
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2026
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2027
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2028
            leaveBlock(catchBlock);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2029
            lc.pop(catchBlock);
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
        method.label(skip);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2033
        method._try(entry, exit, recovery, Throwable.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2034
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2035
        // Finally body is always inlined elsewhere so it doesn't need to be emitted
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2036
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2037
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2038
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2039
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2040
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2041
    public boolean enterVarNode(final VarNode varNode) {
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
  2042
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2043
        final Node init = varNode.getInit();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2044
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2045
        if (init == null) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2046
            return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2047
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2048
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
  2049
        lineNumber(varNode);
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17523
diff changeset
  2050
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2051
        final Symbol varSymbol = varNode.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2052
        assert varSymbol != null : "variable node " + varNode + " requires a symbol";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2053
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2054
        assert method != null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2055
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2056
        final boolean needsScope = varSymbol.isScope();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2057
        if (needsScope) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2058
            method.loadCompilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2059
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2060
        load(init);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2061
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2062
        if (needsScope) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2063
            int flags = CALLSITE_SCOPE | getCallSiteFlags();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2064
            final IdentNode identNode = varNode.getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2065
            final Type type = identNode.getType();
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  2066
            if (isFastScope(varSymbol)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2067
                storeFastScopeVar(type, varSymbol, flags);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2068
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2069
                method.dynamicSet(type, identNode.getName(), flags);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2070
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2071
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2072
            assert varNode.getType() == varNode.getName().getType() : "varNode type=" + varNode.getType() + " nametype=" + varNode.getName().getType() + " inittype=" + init.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2073
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2074
            method.convert(varNode.getType()); // aw: convert moved here
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2075
            method.store(varSymbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2076
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2077
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2078
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2079
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2080
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2081
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2082
    public boolean enterWhileNode(final WhileNode whileNode) {
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
  2083
        lineNumber(whileNode);
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
  2084
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2085
        final Node  test          = whileNode.getTest();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2086
        final Block body          = whileNode.getBody();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2087
        final Label breakLabel    = whileNode.getBreakLabel();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2088
        final Label continueLabel = whileNode.getContinueLabel();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2089
        final Label loopLabel     = new Label("loop");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2090
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2091
        if (!whileNode.isDoWhile()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2092
            method._goto(continueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2093
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2094
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2095
        method.label(loopLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2096
        body.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2097
        if (!whileNode.isTerminal()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2098
            method.label(continueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2099
            new BranchOptimizer(this, method).execute(test, loopLabel, true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2100
            method.label(breakLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2101
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2102
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2103
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2104
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2105
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2106
    private void closeWith() {
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
  2107
        if (method.hasScope()) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2108
            method.loadCompilerConstant(SCOPE);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2109
            method.invoke(ScriptRuntime.CLOSE_WITH);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2110
            method.storeCompilerConstant(SCOPE);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2111
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2112
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2113
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2114
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2115
    public boolean enterWithNode(final WithNode withNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2116
        final Node expression = withNode.getExpression();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2117
        final Node body       = withNode.getBody();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2118
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2119
        // It is possible to have a "pathological" case where the with block does not reference *any* identifiers. It's
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2120
        // pointless, but legal. In that case, if nothing else in the method forced the assignment of a slot to the
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2121
        // scope object, its' possible that it won't have a slot assigned. In this case we'll only evaluate expression
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2122
        // for its side effect and visit the body, and not bother opening and closing a WithObject.
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2123
        final boolean hasScope = method.hasScope();
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2124
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2125
        final Label tryLabel;
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2126
        if (hasScope) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2127
            tryLabel = new Label("with_try");
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2128
            method.label(tryLabel);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2129
            method.loadCompilerConstant(SCOPE);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2130
        } else {
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2131
            tryLabel = null;
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2132
        }
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2133
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2134
        load(expression);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2135
        assert expression.getType().isObject() : "with expression needs to be object: " + expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2136
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2137
        if (hasScope) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2138
            // Construct a WithObject if we have a scope
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2139
            method.invoke(ScriptRuntime.OPEN_WITH);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2140
            method.storeCompilerConstant(SCOPE);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2141
        } else {
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2142
            // We just loaded the expression for its side effect; discard it
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2143
            method.pop();
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2144
        }
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2145
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2146
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2147
        // Always process body
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2148
        body.accept(this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2149
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
  2150
        if (hasScope) {
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2151
            // Ensure we always close the WithObject
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2152
            final Label endLabel   = new Label("with_end");
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2153
            final Label catchLabel = new Label("with_catch");
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2154
            final Label exitLabel  = new Label("with_exit");
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2155
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2156
            if (!body.isTerminal()) {
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2157
                closeWith();
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2158
                method._goto(exitLabel);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2159
            }
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2160
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2161
            method.label(endLabel);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2162
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2163
            method._catch(catchLabel);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2164
            closeWith();
17255
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2165
            method.athrow();
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2166
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2167
            method.label(exitLabel);
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2168
aa61d23e36e5 8013419: Streamline handling of with and eval
attila
parents: 17246
diff changeset
  2169
            method._try(tryLabel, endLabel, catchLabel);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2170
        }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2171
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2172
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2173
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2174
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2175
    public boolean enterADD(final UnaryNode unaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2176
        load(unaryNode.rhs());
17766
01444678d608 8012083: Array literal constant folding issue
lagergren
parents: 17745
diff changeset
  2177
        assert unaryNode.rhs().getType().isNumber() : unaryNode.rhs().getType() + " "+ unaryNode.getSymbol();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2178
        method.store(unaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2179
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2180
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2181
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2182
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2183
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2184
    public boolean enterBIT_NOT(final UnaryNode unaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2185
        load(unaryNode.rhs()).convert(Type.INT).load(-1).xor().store(unaryNode.getSymbol());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2186
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2187
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2188
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2189
    // do this better with convert calls to method. TODO
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2190
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2191
    public boolean enterCONVERT(final UnaryNode unaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2192
        final Node rhs = unaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2193
        final Type to  = unaryNode.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2194
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2195
        if (to.isObject() && rhs instanceof LiteralNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2196
            final LiteralNode<?> literalNode = (LiteralNode<?>)rhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2197
            final Object value = literalNode.getValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2198
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2199
            if (value instanceof Number) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2200
                assert !to.isArray() : "type hygiene - cannot convert number to array: (" + to.getTypeClass().getSimpleName() + ')' + value;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2201
                if (value instanceof Integer) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2202
                    method.load((Integer)value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2203
                } else if (value instanceof Long) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2204
                    method.load((Long)value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2205
                } else if (value instanceof Double) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2206
                    method.load((Double)value);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2207
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2208
                    assert false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2209
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2210
                method.convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2211
            } else if (value instanceof Boolean) {
17778
991ccffbeb13 8015459: Octane test run fails on Turkish locale
sundar
parents: 17769
diff changeset
  2212
                method.getField(staticField(Boolean.class, value.toString().toUpperCase(Locale.ENGLISH), Boolean.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2213
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2214
                load(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2215
                method.convert(unaryNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2216
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2217
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2218
            load(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2219
            method.convert(unaryNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2220
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2221
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2222
        method.store(unaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2223
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2224
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2225
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2226
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2227
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2228
    public boolean enterDECINC(final UnaryNode unaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2229
        final Node      rhs         = unaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2230
        final Type      type        = unaryNode.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2231
        final TokenType tokenType   = unaryNode.tokenType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2232
        final boolean   isPostfix   = tokenType == TokenType.DECPOSTFIX || tokenType == TokenType.INCPOSTFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2233
        final boolean   isIncrement = tokenType == TokenType.INCPREFIX || tokenType == TokenType.INCPOSTFIX;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2234
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2235
        assert !type.isObject();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2236
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2237
        new SelfModifyingStore<UnaryNode>(unaryNode, rhs) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2238
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2239
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2240
            protected void evaluate() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2241
                load(rhs, true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2242
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2243
                method.convert(type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2244
                if (!isPostfix) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2245
                    if (type.isInteger()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2246
                        method.load(isIncrement ? 1 : -1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2247
                    } else if (type.isLong()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2248
                        method.load(isIncrement ? 1L : -1L);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2249
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2250
                        method.load(isIncrement ? 1.0 : -1.0);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2251
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2252
                    method.add();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2253
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2254
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2255
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2256
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2257
            protected void storeNonDiscard() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2258
                super.storeNonDiscard();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2259
                if (isPostfix) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2260
                    if (type.isInteger()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2261
                        method.load(isIncrement ? 1 : -1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2262
                    } else if (type.isLong()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2263
                        method.load(isIncrement ? 1L : 1L);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2264
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2265
                        method.load(isIncrement ? 1.0 : -1.0);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2266
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2267
                    method.add();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2268
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2269
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2270
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2271
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2272
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2273
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2274
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2275
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2276
    public boolean enterDISCARD(final UnaryNode unaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2277
        final Node rhs = unaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2278
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2279
        lc.pushDiscard(rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2280
        load(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2281
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2282
        if (lc.getCurrentDiscard() == rhs) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2283
            assert !rhs.isAssignment();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2284
            method.pop();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2285
            lc.popDiscard();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2286
        }
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: 17255
diff changeset
  2287
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2288
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2289
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2290
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2291
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2292
    public boolean enterNEW(final UnaryNode unaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2293
        final CallNode callNode = (CallNode)unaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2294
        final List<Node> args   = callNode.getArgs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2295
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2296
        // Load function reference.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2297
        load(callNode.getFunction()).convert(Type.OBJECT); // must detect type error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2298
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
  2299
        method.dynamicNew(1 + loadArgs(args), getCallSiteFlags());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2300
        method.store(unaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2301
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2302
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2303
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2304
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2305
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2306
    public boolean enterNOT(final UnaryNode unaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2307
        final Node rhs = unaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2308
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2309
        load(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2310
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2311
        final Label trueLabel  = new Label("true");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2312
        final Label afterLabel = new Label("after");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2313
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2314
        method.convert(Type.BOOLEAN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2315
        method.ifne(trueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2316
        method.load(true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2317
        method._goto(afterLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2318
        method.label(trueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2319
        method.load(false);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2320
        method.label(afterLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2321
        method.store(unaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2322
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2323
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2324
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2325
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2326
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2327
    public boolean enterSUB(final UnaryNode unaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2328
        load(unaryNode.rhs()).neg().store(unaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2329
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2330
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2331
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2332
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2333
    private Node enterNumericAdd(final Node lhs, final Node rhs, final Type type, final Symbol symbol) {
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  2334
        assert lhs.getType().equals(rhs.getType()) && lhs.getType().equals(type) : lhs.getType() + " != " + rhs.getType() + " != " + type + " " + new ASTWriter(lhs) + " " + new ASTWriter(rhs);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2335
        load(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2336
        load(rhs);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2337
        method.add(); //if the symbol is optimistic, it always needs to be written, not on the stack?
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2338
        method.store(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2339
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2340
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2341
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2342
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2343
    public boolean enterADD(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2344
        final Node lhs = binaryNode.lhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2345
        final Node rhs = binaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2346
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2347
        final Type type = binaryNode.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2348
        if (type.isNumeric()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2349
            enterNumericAdd(lhs, rhs, type, binaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2350
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2351
            load(lhs).convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2352
            load(rhs).convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2353
            method.add();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2354
            method.store(binaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2355
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2356
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2357
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2358
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2359
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2360
    private boolean enterAND_OR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2361
        final Node lhs = binaryNode.lhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2362
        final Node rhs = binaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2363
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2364
        final Label skip = new Label("skip");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2365
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2366
        load(lhs).convert(Type.OBJECT).dup().convert(Type.BOOLEAN);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2367
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2368
        if (binaryNode.tokenType() == TokenType.AND) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2369
            method.ifeq(skip);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2370
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2371
            method.ifne(skip);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2372
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2373
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2374
        method.pop();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2375
        load(rhs).convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2376
        method.label(skip);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2377
        method.store(binaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2378
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2379
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2380
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2381
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2382
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2383
    public boolean enterAND(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2384
        return enterAND_OR(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2385
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2386
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2387
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2388
    public boolean enterASSIGN(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2389
        final Node lhs = binaryNode.lhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2390
        final Node rhs = binaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2391
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2392
        final Type lhsType = lhs.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2393
        final Type rhsType = rhs.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2394
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2395
        if (!lhsType.isEquivalentTo(rhsType)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2396
            //this is OK if scoped, only locals are wrong
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2397
            assert !(lhs instanceof IdentNode) || lhs.getSymbol().isScope() : new ASTWriter(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2398
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2399
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2400
        new Store<BinaryNode>(binaryNode, lhs) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2401
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2402
            protected void evaluate() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2403
                load(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2404
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2405
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2406
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2407
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2408
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2409
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2410
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2411
     * Helper class for assignment ops, e.g. *=, += and so on..
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2412
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2413
    private abstract class AssignOp extends SelfModifyingStore<BinaryNode> {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2414
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2415
        /** The type of the resulting operation */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2416
        private final Type opType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2417
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2418
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2419
         * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2420
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2421
         * @param node the assign op node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2422
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2423
        AssignOp(final BinaryNode node) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2424
            this(node.getType(), node);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2425
        }
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
         * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2429
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2430
         * @param opType type of the computation - overriding the type of the node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2431
         * @param node the assign op node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2432
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2433
        AssignOp(final Type opType, final BinaryNode node) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2434
            super(node, node.lhs());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2435
            this.opType = opType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2436
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2437
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2438
        protected abstract void op();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2439
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2440
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2441
        protected void evaluate() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2442
            load(assignNode.lhs(), true).convert(opType);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2443
            load(assignNode.rhs()).convert(opType);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2444
            op();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2445
            method.convert(assignNode.getType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2446
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2447
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2448
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2449
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2450
    public boolean enterASSIGN_ADD(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2451
        assert RuntimeNode.Request.ADD.canSpecialize();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2452
        final Type lhsType = binaryNode.lhs().getType();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2453
        final Type rhsType = binaryNode.rhs().getType();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2454
        final boolean specialize = binaryNode.getType() == Type.OBJECT;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2455
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2456
        new AssignOp(binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2457
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2458
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2459
            protected void op() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2460
                if (specialize) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2461
                    method.dynamicRuntimeCall(
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2462
                            new SpecializedRuntimeNode(
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2463
                                Request.ADD,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2464
                                new Type[] {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2465
                                    lhsType,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2466
                                    rhsType,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2467
                                },
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2468
                                Type.OBJECT).getInitialName(),
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2469
                            Type.OBJECT,
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2470
                            Request.ADD);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2471
                } else {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2472
                    method.add();
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2473
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2474
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2475
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2476
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2477
            protected void evaluate() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2478
                super.evaluate();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2479
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2480
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2481
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2482
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2483
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2484
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2485
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2486
    public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2487
        new AssignOp(Type.INT, binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2488
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2489
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2490
                method.and();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2491
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2492
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2493
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2494
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2495
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2496
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2497
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2498
    public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2499
        new AssignOp(Type.INT, binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2500
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2501
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2502
                method.or();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2503
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2504
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2505
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2506
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2507
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2508
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2509
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2510
    public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2511
        new AssignOp(Type.INT, binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2512
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2513
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2514
                method.xor();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2515
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2516
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2517
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2518
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2519
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2520
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2521
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2522
    public boolean enterASSIGN_DIV(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2523
        new AssignOp(binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2524
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2525
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2526
                method.div();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2527
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2528
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2529
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2530
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2531
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2532
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2533
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2534
    public boolean enterASSIGN_MOD(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2535
        new AssignOp(binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2536
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2537
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2538
                method.rem();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2539
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2540
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2541
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2542
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2543
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2544
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2545
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2546
    public boolean enterASSIGN_MUL(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2547
        new AssignOp(binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2548
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2549
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2550
                method.mul();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2551
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2552
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2553
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2554
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2555
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2556
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2557
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2558
    public boolean enterASSIGN_SAR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2559
        new AssignOp(Type.INT, binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2560
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2561
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2562
                method.sar();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2563
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2564
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2565
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2566
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2567
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2568
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2569
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2570
    public boolean enterASSIGN_SHL(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2571
        new AssignOp(Type.INT, binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2572
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2573
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2574
                method.shl();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2575
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2576
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2577
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2578
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2579
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2580
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2581
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2582
    public boolean enterASSIGN_SHR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2583
        new AssignOp(Type.INT, binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2584
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2585
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2586
                method.shr();
17241
c337fefb8c84 8012334: ToUint32, ToInt32, and ToUint16 don't conform to spec
hannesw
parents: 17239
diff changeset
  2587
                method.convert(Type.LONG).load(JSType.MAX_UINT).and();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2588
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2589
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2590
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2591
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2592
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2593
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2594
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2595
    public boolean enterASSIGN_SUB(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2596
        new AssignOp(binaryNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2597
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2598
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2599
                method.sub();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2600
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2601
        }.store();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2602
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2603
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2604
    }
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
     * Helper class for binary arithmetic ops
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2608
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2609
    private abstract class BinaryArith {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2610
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2611
        protected abstract void op();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2612
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2613
        protected void evaluate(final BinaryNode node) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2614
            load(node.lhs());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2615
            load(node.rhs());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2616
            op();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2617
            method.store(node.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2618
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2619
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2620
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2621
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2622
    public boolean enterBIT_AND(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2623
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2624
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2625
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2626
                method.and();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2627
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2628
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2629
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2630
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2631
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2632
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2633
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2634
    public boolean enterBIT_OR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2635
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2636
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2637
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2638
                method.or();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2639
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2640
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2641
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2642
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2643
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2644
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2645
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2646
    public boolean enterBIT_XOR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2647
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2648
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2649
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2650
                method.xor();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2651
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2652
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2653
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2654
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2655
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2656
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2657
    private boolean enterComma(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2658
        final Node lhs = binaryNode.lhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2659
        final Node rhs = binaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2660
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2661
        load(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2662
        load(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2663
        method.store(binaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2664
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2665
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2666
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2667
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2668
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2669
    public boolean enterCOMMARIGHT(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2670
        return enterComma(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2671
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2672
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2673
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2674
    public boolean enterCOMMALEFT(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2675
        return enterComma(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2676
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2677
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2678
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2679
    public boolean enterDIV(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2680
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2681
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2682
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2683
                method.div();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2684
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2685
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2686
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2687
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2688
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2689
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2690
    private boolean enterCmp(final Node lhs, final Node rhs, final Condition cond, final Type type, final Symbol symbol) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2691
        final Type lhsType = lhs.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2692
        final Type rhsType = rhs.getType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2693
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2694
        final Type widest = Type.widest(lhsType, rhsType);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2695
        assert widest.isNumeric() || widest.isBoolean() : widest;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2696
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2697
        load(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2698
        method.convert(widest);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2699
        load(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2700
        method.convert(widest);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2701
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2702
        final Label trueLabel  = new Label("trueLabel");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2703
        final Label afterLabel = new Label("skip");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2704
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2705
        method.conditionalJump(cond, trueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2706
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2707
        method.load(Boolean.FALSE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2708
        method._goto(afterLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2709
        method.label(trueLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2710
        method.load(Boolean.TRUE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2711
        method.label(afterLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2712
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2713
        method.convert(type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2714
        method.store(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2715
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2716
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2717
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2718
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2719
    private boolean enterCmp(final BinaryNode binaryNode, final Condition cond) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2720
        return enterCmp(binaryNode.lhs(), binaryNode.rhs(), cond, binaryNode.getType(), binaryNode.getSymbol());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2721
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2722
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2723
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2724
    public boolean enterEQ(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2725
        return enterCmp(binaryNode, Condition.EQ);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2726
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2727
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2728
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2729
    public boolean enterEQ_STRICT(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2730
        return enterCmp(binaryNode, Condition.EQ);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2731
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2732
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2733
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2734
    public boolean enterGE(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2735
        return enterCmp(binaryNode, Condition.GE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2736
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2737
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2738
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2739
    public boolean enterGT(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2740
        return enterCmp(binaryNode, Condition.GT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2741
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2742
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2743
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2744
    public boolean enterLE(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2745
        return enterCmp(binaryNode, Condition.LE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2746
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2747
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2748
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2749
    public boolean enterLT(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2750
        return enterCmp(binaryNode, Condition.LT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2751
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2752
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2753
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2754
    public boolean enterMOD(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2755
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2756
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2757
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2758
                method.rem();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2759
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2760
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2761
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2762
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2763
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2764
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2765
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2766
    public boolean enterMUL(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2767
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2768
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2769
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2770
                method.mul();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2771
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2772
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2773
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2774
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2775
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2776
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2777
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2778
    public boolean enterNE(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2779
        return enterCmp(binaryNode, Condition.NE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2780
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2781
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2782
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2783
    public boolean enterNE_STRICT(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2784
        return enterCmp(binaryNode, Condition.NE);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2785
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2786
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2787
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2788
    public boolean enterOR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2789
        return enterAND_OR(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2790
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2791
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2792
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2793
    public boolean enterSAR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2794
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2795
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2796
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2797
                method.sar();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2798
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2799
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2800
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2801
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2802
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2803
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2804
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2805
    public boolean enterSHL(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2806
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2807
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2808
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2809
                method.shl();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2810
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2811
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2812
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2813
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2814
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2815
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2816
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2817
    public boolean enterSHR(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2818
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2819
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2820
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2821
                method.shr();
17241
c337fefb8c84 8012334: ToUint32, ToInt32, and ToUint16 don't conform to spec
hannesw
parents: 17239
diff changeset
  2822
                method.convert(Type.LONG).load(JSType.MAX_UINT).and();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2823
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2824
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2825
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2826
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2827
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2828
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2829
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2830
    public boolean enterSUB(final BinaryNode binaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2831
        new BinaryArith() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2832
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2833
            protected void op() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2834
                method.sub();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2835
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2836
        }.evaluate(binaryNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2837
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2838
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2839
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2840
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2841
    @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2842
    public boolean enterTernaryNode(final TernaryNode ternaryNode) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2843
        final Node lhs   = ternaryNode.lhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2844
        final Node rhs   = ternaryNode.rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2845
        final Node third = ternaryNode.third();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2846
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2847
        final Symbol symbol     = ternaryNode.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2848
        final Label  falseLabel = new Label("ternary_false");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2849
        final Label  exitLabel  = new Label("ternary_exit");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2850
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
  2851
        Type widest = Type.widest(rhs.getType(), third.getType());
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
  2852
        if (rhs.getType().isArray() || third.getType().isArray()) { //loadArray creates a Java array type on the stack, calls global allocate, which creates a native array type
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
  2853
            widest = Type.OBJECT;
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
  2854
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2855
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2856
        load(lhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2857
        assert lhs.getType().isBoolean() : "lhs in ternary must be boolean";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2858
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2859
        // we still keep the conversion here as the AccessSpecializer can have separated the types, e.g. var y = x ? x=55 : 17
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2860
        // will left as (Object)x=55 : (Object)17 by Lower. Then the first term can be {I}x=55 of type int, which breaks the
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2861
        // symmetry for the temporary slot for this TernaryNode. This is evidence that we assign types and explicit conversions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2862
        // to early, or Apply the AccessSpecializer too late. We are mostly probably looking for a separate type pass to
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2863
        // do this property. Then we never need any conversions in CodeGenerator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2864
        method.ifeq(falseLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2865
        load(rhs);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2866
        method.convert(widest);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2867
        method._goto(exitLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2868
        method.label(falseLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2869
        load(third);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2870
        method.convert(widest);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2871
        method.label(exitLabel);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2872
        method.store(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2873
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2874
        return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2875
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2876
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2877
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2878
     * Generate all shared scope calls generated during codegen.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2879
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2880
    protected void generateScopeCalls() {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2881
        for (final SharedScopeCall scopeAccess : lc.getScopeCalls()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2882
            scopeAccess.generateScopeCall();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2883
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2884
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2885
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2886
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2887
     * Debug code used to print symbols
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2888
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2889
     * @param block the block we are in
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2890
     * @param ident identifier for block or function where applicable
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2891
     */
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
  2892
    @SuppressWarnings("resource")
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2893
    private void printSymbols(final Block block, final String ident) {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  2894
        if (!compiler.getEnv()._print_symbols) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2895
            return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2896
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2897
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16252
diff changeset
  2898
        final PrintWriter out = compiler.getEnv().getErr();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2899
        out.println("[BLOCK in '" + ident + "']");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2900
        if (!block.printSymbols(out)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2901
            out.println("<no symbols>");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2902
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2903
        out.println();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2904
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2905
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2906
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2907
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2908
     * The difference between a store and a self modifying store is that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2909
     * the latter may load part of the target on the stack, e.g. the base
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2910
     * of an AccessNode or the base and index of an IndexNode. These are used
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2911
     * both as target and as an extra source. Previously it was problematic
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2912
     * for self modifying stores if the target/lhs didn't belong to one
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2913
     * of three trivial categories: IdentNode, AcessNodes, IndexNodes. In that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2914
     * case it was evaluated and tagged as "resolved", which meant at the second
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2915
     * time the lhs of this store was read (e.g. in a = a (second) + b for a += b,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2916
     * it would be evaluated to a nop in the scope and cause stack underflow
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2917
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2918
     * see NASHORN-703
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2919
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2920
     * @param <T>
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2921
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2922
    private abstract class SelfModifyingStore<T extends Node> extends Store<T> {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2923
        protected SelfModifyingStore(final T assignNode, final Node target) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2924
            super(assignNode, target);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2925
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2926
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2927
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2928
        protected boolean isSelfModifying() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2929
            return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2930
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2931
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2932
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2933
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2934
     * Helper class to generate stores
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2935
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2936
    private abstract class Store<T extends Node> {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2937
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2938
        /** An assignment node, e.g. x += y */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2939
        protected final T assignNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2940
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2941
        /** The target node to store to, e.g. x */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2942
        private final Node target;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2943
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2944
        /** How deep on the stack do the arguments go if this generates an indy call */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2945
        private int depth;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2946
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2947
        /** If we have too many arguments, we need temporary storage, this is stored in 'quick' */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2948
        private Symbol quick;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2949
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2950
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2951
         * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2952
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2953
         * @param assignNode the node representing the whole assignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2954
         * @param target     the target node of the assignment (destination)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2955
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2956
        protected Store(final T assignNode, final Node target) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2957
            this.assignNode = assignNode;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2958
            this.target = target;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2959
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2960
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2961
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2962
         * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2963
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2964
         * @param assignNode the node representing the whole assignment
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2965
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2966
        protected Store(final T assignNode) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2967
            this(assignNode, assignNode);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2968
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2969
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2970
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2971
         * Is this a self modifying store operation, e.g. *= or ++
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2972
         * @return true if self modifying store
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2973
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2974
        protected boolean isSelfModifying() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2975
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2976
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2977
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2978
        private void prologue() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2979
            final Symbol targetSymbol = target.getSymbol();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2980
            final Symbol scopeSymbol  = lc.getCurrentFunction().compilerConstant(SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2981
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2982
            /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2983
             * This loads the parts of the target, e.g base and index. they are kept
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2984
             * on the stack throughout the store and used at the end to execute it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2985
             */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2986
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  2987
            target.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2988
                @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2989
                public boolean enterIdentNode(final IdentNode node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2990
                    if (targetSymbol.isScope()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2991
                        method.load(scopeSymbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2992
                        depth++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2993
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  2994
                    return false;
16147
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
                private void enterBaseNode() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2998
                    assert target instanceof BaseNode : "error - base node " + target + " must be instanceof BaseNode";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  2999
                    final BaseNode baseNode = (BaseNode)target;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3000
                    final Node     base     = baseNode.getBase();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3001
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3002
                    load(base);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3003
                    method.convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3004
                    depth += Type.OBJECT.getSlots();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3005
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3006
                    if (isSelfModifying()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3007
                        method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3008
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3009
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3010
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3011
                @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3012
                public boolean enterAccessNode(final AccessNode node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3013
                    enterBaseNode();
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3014
                    return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3015
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3016
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3017
                @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3018
                public boolean enterIndexNode(final IndexNode node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3019
                    enterBaseNode();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3020
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3021
                    final Node index = node.getIndex();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3022
                    // could be boolean here as well
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3023
                    load(index);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3024
                    if (!index.getType().isNumeric()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3025
                        method.convert(Type.OBJECT);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3026
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3027
                    depth += index.getType().getSlots();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3028
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3029
                    if (isSelfModifying()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3030
                        //convert "base base index" to "base index base index"
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3031
                        method.dup(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3032
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3033
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3034
                    return false;
16147
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
            });
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3038
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3039
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3040
        private Symbol quickSymbol(final Type type) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3041
            return quickSymbol(type, QUICK_PREFIX.symbolName());
16147
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
         * Quick symbol generates an extra local variable, always using the same
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3046
         * slot, one that is available after the end of the frame.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3047
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3048
         * @param type the type of the symbol
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3049
         * @param prefix the prefix for the variable name for the symbol
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3050
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3051
         * @return the quick symbol
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3052
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3053
        private Symbol quickSymbol(final Type type, final String prefix) {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  3054
            final String name = lc.getCurrentFunction().uniqueName(prefix);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3055
            final Symbol symbol = new Symbol(name, IS_TEMP | IS_INTERNAL);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3056
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3057
            symbol.setType(type);
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  3058
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  3059
            symbol.setSlot(lc.quickSlot(symbol));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3060
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3061
            return symbol;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3062
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3063
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3064
        // store the result that "lives on" after the op, e.g. "i" in i++ postfix.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3065
        protected void storeNonDiscard() {
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  3066
            if (lc.getCurrentDiscard() == assignNode) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3067
                assert assignNode.isAssignment();
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  3068
                lc.popDiscard();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3069
                return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3070
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3071
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3072
            final Symbol symbol = assignNode.getSymbol();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3073
            if (symbol.hasSlot()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3074
                method.dup().store(symbol);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3075
                return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3076
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3077
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3078
            if (method.dup(depth) == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3079
                method.dup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3080
                this.quick = quickSymbol(method.peekType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3081
                method.store(quick);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3082
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3083
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3084
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3085
        private void epilogue() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3086
            /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3087
             * Take the original target args from the stack and use them
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3088
             * together with the value to be stored to emit the store code
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  3089
             *
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  3090
             * The case that targetSymbol is in scope (!hasSlot) and we actually
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  3091
             * need to do a conversion on non-equivalent types exists, but is
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  3092
             * very rare. See for example test/script/basic/access-specializer.js
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3093
             */
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16190
diff changeset
  3094
            method.convert(target.getType());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3095
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17766
diff changeset
  3096
            target.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3097
                @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3098
                protected boolean enterDefault(Node node) {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3099
                    throw new AssertionError("Unexpected node " + node + " in store epilogue");
16210
8ad1381b69d0 8007215: Varargs broken for the case of passing more than the arg limit arguments.
lagergren
parents: 16209
diff changeset
  3100
                }
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3101
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3102
                @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3103
                public boolean enterUnaryNode(final UnaryNode node) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3104
                    if (node.tokenType() == TokenType.CONVERT && node.getSymbol() != null) {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3105
                        method.convert(node.rhs().getType());
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3106
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3107
                    return true;
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3108
                }
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3109
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3110
                @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3111
                public boolean enterIdentNode(final IdentNode node) {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3112
                    final Symbol symbol = node.getSymbol();
16226
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16225
diff changeset
  3113
                    assert symbol != null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3114
                    if (symbol.isScope()) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16525
diff changeset
  3115
                        if (isFastScope(symbol)) {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3116
                            storeFastScopeVar(node.getType(), symbol, CALLSITE_SCOPE | getCallSiteFlags());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3117
                        } else {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16201
diff changeset
  3118
                            method.dynamicSet(node.getType(), node.getName(), CALLSITE_SCOPE | getCallSiteFlags());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3119
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3120
                    } else {
16209
18e55b352d56 8007460: var assignment to a parameter in a varargs method causes compilation error
attila
parents: 16206
diff changeset
  3121
                        method.store(symbol);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3122
                    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3123
                    return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3124
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3125
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3126
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3127
                @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3128
                public boolean enterAccessNode(final AccessNode node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3129
                    method.dynamicSet(node.getProperty().getType(), node.getProperty().getName(), getCallSiteFlags());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3130
                    return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3131
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3132
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3133
                @Override
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3134
                public boolean enterIndexNode(final IndexNode node) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3135
                    method.dynamicSetIndex(getCallSiteFlags());
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3136
                    return false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3137
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3138
            });
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3139
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3140
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3141
            // whatever is on the stack now is the final answer
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3142
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3143
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3144
        protected abstract void evaluate();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3145
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3146
        void store() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3147
            prologue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3148
            evaluate(); // leaves an operation of whatever the operationType was on the stack
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3149
            storeNonDiscard();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3150
            epilogue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3151
            if (quick != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3152
                method.load(quick);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3153
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3154
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3155
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3156
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3157
    private void newFunctionObject(final FunctionNode functionNode, final FunctionNode originalFunctionNode) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3158
        assert lc.peek() == functionNode;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3159
        // We don't emit a ScriptFunction on stack for:
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3160
        // 1. the outermost compiled function (as there's no code being generated in its outer context that'd need it
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3161
        //    as a callee), and
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3162
        // 2. for functions that are immediately called upon definition and they don't need a callee, e.g. (function(){})().
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3163
        //    Such immediately-called functions are invoked using INVOKESTATIC (see enterFunctionNode() of the embedded
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3164
        //    visitor of enterCallNode() for details), and if they don't need a callee, they don't have it on their
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3165
        //    static method's parameter list.
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
  3166
        if (lc.getOutermostFunction() == functionNode ||
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3167
                (!functionNode.needsCallee()) && lc.isFunctionDefinedInCurrentCall(originalFunctionNode)) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3168
            return;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3169
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3170
16525
1409942e618e 8009982: Lazy execution bugfix. Added lazy sunspider unit test. Added mandreel to compile-octane test. Fixed warnings
lagergren
parents: 16523
diff changeset
  3171
        final boolean isLazy  = functionNode.isLazy();
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3172
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3173
        new ObjectCreator(this, new ArrayList<String>(), new ArrayList<Symbol>(), false, false) {
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3174
            @Override
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: 16268
diff changeset
  3175
            protected void makeObject(final MethodEmitter m) {
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: 16268
diff changeset
  3176
                final String className = SCRIPTFUNCTION_IMPL_OBJECT;
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: 16268
diff changeset
  3177
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: 16268
diff changeset
  3178
                m._new(className).dup();
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: 16268
diff changeset
  3179
                loadConstant(new RecompilableScriptFunctionData(functionNode, compiler.getCodeInstaller(), Compiler.binaryName(getClassName()), makeMap()));
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3180
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3181
                if (isLazy || functionNode.needsParentScope()) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
  3182
                    m.loadCompilerConstant(SCOPE);
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3183
                } else {
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: 16268
diff changeset
  3184
                    m.loadNull();
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3185
                }
16525
1409942e618e 8009982: Lazy execution bugfix. Added lazy sunspider unit test. Added mandreel to compile-octane test. Fixed warnings
lagergren
parents: 16523
diff changeset
  3186
                m.invoke(constructorNoLookup(className, RecompilableScriptFunctionData.class, ScriptObject.class));
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3187
            }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3188
        }.makeObject(method);
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3189
    }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16226
diff changeset
  3190
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3191
    /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3192
     * Globals are special. We cannot refer to any Global (or NativeObject) class by .class, as they are different
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3193
     * for different contexts. As far as I can tell, the only NativeObject that we need to deal with like this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3194
     * is from the code pipeline is Global
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3195
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3196
    private MethodEmitter globalInstance() {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  3197
        return method.invokestatic(GLOBAL_OBJECT, "instance", "()L" + GLOBAL_OBJECT + ';');
16147
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
    private MethodEmitter globalObjectPrototype() {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  3201
        return method.invokestatic(GLOBAL_OBJECT, "objectPrototype", methodDescriptor(ScriptObject.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3202
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3203
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3204
    private MethodEmitter globalAllocateArguments() {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  3205
        return method.invokestatic(GLOBAL_OBJECT, "allocateArguments", methodDescriptor(ScriptObject.class, Object[].class, Object.class, int.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3206
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3207
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3208
    private MethodEmitter globalNewRegExp() {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  3209
        return method.invokestatic(GLOBAL_OBJECT, "newRegExp", methodDescriptor(Object.class, String.class, String.class));
16147
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
    private MethodEmitter globalRegExpCopy() {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  3213
        return method.invokestatic(GLOBAL_OBJECT, "regExpCopy", methodDescriptor(Object.class, Object.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3214
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3215
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3216
    private MethodEmitter globalAllocateArray(final ArrayType type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3217
        //make sure the native array is treated as an array type
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  3218
        return method.invokestatic(GLOBAL_OBJECT, "allocate", "(" + type.getDescriptor() + ")Ljdk/nashorn/internal/objects/NativeArray;");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3219
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3220
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3221
    private MethodEmitter globalIsEval() {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  3222
        return method.invokestatic(GLOBAL_OBJECT, "isEval", methodDescriptor(boolean.class, Object.class));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3223
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3224
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3225
    private MethodEmitter globalDirectEval() {
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16235
diff changeset
  3226
        return method.invokestatic(GLOBAL_OBJECT, "directEval",
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3227
                methodDescriptor(Object.class, Object.class, Object.class, Object.class, Object.class, Object.class));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3228
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  3229
}