src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java
author attila
Wed, 20 Dec 2017 17:36:50 +0100
changeset 48354 c96d4c720995
parent 47216 71c04702a3d5
permissions -rw-r--r--
8193371: Use Dynalink REMOVE operation in Nashorn Reviewed-by: hannesw, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
44052
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
     2
 * Copyright (c) 2010, 2017, 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.runtime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
25250
b5a4e0ac31d1 8047359: large string size RangeError should be thrown rather than reporting negative length
sundar
parents: 25247
diff changeset
    30
import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import static jdk.nashorn.internal.runtime.ECMAErrors.syntaxError;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
29282
a8523237b66c 8074031: Canonicalize is-a-JS-string tests
attila
parents: 29281
diff changeset
    35
import static jdk.nashorn.internal.runtime.JSType.isString;
29133
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
    36
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import java.lang.invoke.MethodHandle;
19460
1b6d8e7b1cdf 8022782: publicLookup access failures in ScriptObject, ScriptFunction and ScriptFunction
sundar
parents: 19097
diff changeset
    38
import java.lang.invoke.MethodHandles;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
    39
import java.lang.invoke.SwitchPoint;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import java.lang.reflect.Array;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import java.util.Collections;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
import java.util.Iterator;
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
    43
import java.util.List;
17778
991ccffbeb13 8015459: Octane test run fails on Turkish locale
sundar
parents: 16272
diff changeset
    44
import java.util.Locale;
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
    45
import java.util.Map;
16226
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
    46
import java.util.NoSuchElementException;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    47
import java.util.Objects;
43352
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
    48
import jdk.dynalink.beans.BeansLinker;
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 34445
diff changeset
    49
import jdk.dynalink.beans.StaticClass;
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
    50
import jdk.nashorn.api.scripting.JSObject;
17978
750d0582d8e2 8015830: Javascript mapping of ScriptEngine bindings does not expose keys
sundar
parents: 17778
diff changeset
    51
import jdk.nashorn.api.scripting.ScriptObjectMirror;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
    52
import jdk.nashorn.internal.codegen.ApplySpecialization;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
    53
import jdk.nashorn.internal.codegen.CompilerConstants;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
16226
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
    55
import jdk.nashorn.internal.ir.debug.JSONWriter;
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
    56
import jdk.nashorn.internal.objects.AbstractIterator;
21446
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
    57
import jdk.nashorn.internal.objects.Global;
25247
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24762
diff changeset
    58
import jdk.nashorn.internal.objects.NativeObject;
44052
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
    59
import jdk.nashorn.internal.objects.NativeJava;
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
    60
import jdk.nashorn.internal.objects.NativeArray;
16226
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
    61
import jdk.nashorn.internal.parser.Lexer;
43352
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
    62
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
import jdk.nashorn.internal.runtime.linker.Bootstrap;
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
    64
import jdk.nashorn.internal.runtime.linker.InvokeByName;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    66
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    67
 * Utilities to be called by JavaScript runtime API and generated classes.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
public final class ScriptRuntime {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
    private ScriptRuntime() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
    /** Singleton representing the empty array object '[]' */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
    public static final Object[] EMPTY_ARRAY = new Object[0];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
    /** Unique instance of undefined. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
    public static final Undefined UNDEFINED = Undefined.getUndefined();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
     * Unique instance of undefined used to mark empty array slots.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
     * Can't escape the array.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    84
    public static final Undefined EMPTY = Undefined.getEmpty();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    85
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    86
    /** Method handle to generic + operator, operating on objects */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    87
    public static final Call ADD = staticCallNoLookup(ScriptRuntime.class, "ADD", Object.class, Object.class, Object.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    88
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
    /** Method handle to generic === operator, operating on objects */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
    public static final Call EQ_STRICT = staticCallNoLookup(ScriptRuntime.class, "EQ_STRICT", boolean.class, Object.class, Object.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    91
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16234
diff changeset
    92
    /** Method handle used to enter a {@code with} scope at runtime. */
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
    public static final Call OPEN_WITH = staticCallNoLookup(ScriptRuntime.class, "openWith", ScriptObject.class, ScriptObject.class, Object.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    94
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
     * Method used to place a scope's variable into the Global scope, which has to be done for the
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16234
diff changeset
    97
     * properties declared at outermost script level.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
    public static final Call MERGE_SCOPE = staticCallNoLookup(ScriptRuntime.class, "mergeScope", ScriptObject.class, ScriptObject.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
     * Return an appropriate iterator for the elements in a for-in construct
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   103
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   104
    public static final Call TO_PROPERTY_ITERATOR = staticCallNoLookup(ScriptRuntime.class, "toPropertyIterator", Iterator.class, Object.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   105
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   106
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
     * Return an appropriate iterator for the elements in a for-each construct
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
    public static final Call TO_VALUE_ITERATOR = staticCallNoLookup(ScriptRuntime.class, "toValueIterator", Iterator.class, Object.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   110
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   111
    /**
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   112
     * Return an appropriate iterator for the elements in a ES6 for-of loop
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   113
     */
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   114
    public static final Call TO_ES6_ITERATOR = staticCallNoLookup(ScriptRuntime.class, "toES6Iterator", Iterator.class, Object.class);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   115
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   116
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   117
      * Method handle for apply. Used from {@link ScriptFunction} for looking up calls to
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
      * call sites that are known to be megamorphic. Using an invoke dynamic here would
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   119
      * lead to the JVM deoptimizing itself to death
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
      */
19460
1b6d8e7b1cdf 8022782: publicLookup access failures in ScriptObject, ScriptFunction and ScriptFunction
sundar
parents: 19097
diff changeset
   121
    public static final Call APPLY = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
    /**
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   124
     * Throws a reference error for an undefined variable.
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   125
     */
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   126
    public static final Call THROW_REFERENCE_ERROR = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "throwReferenceError", void.class, String.class);
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   127
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   128
    /**
29281
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   129
     * Throws a reference error for an undefined variable.
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   130
     */
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   131
    public static final Call THROW_CONST_TYPE_ERROR = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "throwConstTypeError", void.class, String.class);
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   132
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   133
    /**
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
   134
     * Used to invalidate builtin names, e.g "Function" mapping to all properties in Function.prototype and Function.prototype itself.
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
   135
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
   136
    public static final Call INVALIDATE_RESERVED_BUILTIN_NAME = staticCallNoLookup(ScriptRuntime.class, "invalidateReservedBuiltinName", void.class, String.class);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
   137
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
   138
    /**
48354
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   139
     * Used to perform failed delete under strict mode
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   140
     */
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   141
    public static final Call STRICT_FAIL_DELETE = staticCallNoLookup(ScriptRuntime.class, "strictFailDelete", boolean.class, String.class);
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   142
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   143
    /**
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   144
     * Used to find the scope for slow delete
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   145
     */
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   146
    public static final Call SLOW_DELETE = staticCallNoLookup(ScriptRuntime.class, "slowDelete", boolean.class, ScriptObject.class, String.class);
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   147
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   148
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   149
     * Converts a switch tag value to a simple integer. deflt value if it can't.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   150
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   151
     * @param tag   Switch statement tag value.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   152
     * @param deflt default to use if not convertible.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   153
     * @return int tag value (or deflt.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   154
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   155
    public static int switchTagAsInt(final Object tag, final int deflt) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
        if (tag instanceof Number) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   157
            final double d = ((Number)tag).doubleValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
            if (isRepresentableAsInt(d)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
                return (int)d;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   160
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   161
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
        return deflt;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   163
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   164
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
     * Converts a switch tag value to a simple integer. deflt value if it can't.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   167
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
     * @param tag   Switch statement tag value.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   169
     * @param deflt default to use if not convertible.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   170
     * @return int tag value (or deflt.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   171
     */
18628
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   172
    public static int switchTagAsInt(final boolean tag, final int deflt) {
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   173
        return deflt;
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   174
    }
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   175
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   176
    /**
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   177
     * Converts a switch tag value to a simple integer. deflt value if it can't.
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   178
     *
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   179
     * @param tag   Switch statement tag value.
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   180
     * @param deflt default to use if not convertible.
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   181
     * @return int tag value (or deflt.)
012cd852f881 8019488: switch on literals result in NoSuchMethodError or VerifyError
sundar
parents: 18614
diff changeset
   182
     */
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
    public static int switchTagAsInt(final long tag, final int deflt) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
        return isRepresentableAsInt(tag) ? (int)tag : deflt;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
     * Converts a switch tag value to a simple integer. deflt value if it can't.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   189
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   190
     * @param tag   Switch statement tag value.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   191
     * @param deflt default to use if not convertible.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
     * @return int tag value (or deflt.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   194
    public static int switchTagAsInt(final double tag, final int deflt) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   195
        return isRepresentableAsInt(tag) ? (int)tag : deflt;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   196
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   197
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   198
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   199
     * This is the builtin implementation of {@code Object.prototype.toString}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   200
     * @param self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   201
     * @return string representation as object
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   202
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   203
    public static String builtinObjectToString(final Object self) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
        String className;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   205
        // Spec tells us to convert primitives by ToObject..
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
        // But we don't need to -- all we need is the right class name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   207
        // of the corresponding primitive wrapper type.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   208
24752
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
   209
        final JSType type = JSType.ofNoFunction(self);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   210
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   211
        switch (type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
        case BOOLEAN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   213
            className = "Boolean";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
        case NUMBER:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   216
            className = "Number";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   217
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   218
        case STRING:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
            className = "String";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
        // special case of null and undefined
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   222
        case NULL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
            className = "Null";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   224
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   225
        case UNDEFINED:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   226
            className = "Undefined";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   227
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
        case OBJECT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   229
            if (self instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   230
                className = ((ScriptObject)self).getClassName();
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   231
            } else if (self instanceof JSObject) {
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   232
                className = ((JSObject)self).getClassName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   233
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   234
                className = self.getClass().getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   236
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
            // Nashorn extension: use Java class name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   239
            className = self.getClass().getName();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   240
            break;
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
        final StringBuilder sb = new StringBuilder();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   244
        sb.append("[object ");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   245
        sb.append(className);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   246
        sb.append(']');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   247
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   248
        return sb.toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   249
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   250
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   251
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   252
     * This is called whenever runtime wants to throw an error and wants to provide
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   253
     * meaningful information about an object. We don't want to call toString which
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   254
     * ends up calling "toString" from script world which may itself throw error.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   255
     * When we want to throw an error, we don't additional error from script land
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   256
     * -- which may sometimes lead to infinite recursion.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   257
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   258
     * @param obj Object to converted to String safely (without calling user script)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
     * @return safe String representation of the given object
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   260
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   261
    public static String safeToString(final Object obj) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   262
        return JSType.toStringImpl(obj, true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   263
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   265
    /**
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   266
     * Returns an iterator over property identifiers used in the {@code for...in} statement. Note that the ECMAScript
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   267
     * 5.1 specification, chapter 12.6.4. uses the terminology "property names", which seems to imply that the property
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   268
     * identifiers are expected to be strings, but this is not actually spelled out anywhere, and Nashorn will in some
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   269
     * cases deviate from this. Namely, we guarantee to always return an iterator over {@link String} values for any
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   270
     * built-in JavaScript object. We will however return an iterator over {@link Integer} objects for native Java
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   271
     * arrays and {@link List} objects, as well as arbitrary objects representing keys of a {@link Map}. Therefore, the
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   272
     * expression {@code typeof i} within a {@code for(i in obj)} statement can return something other than
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   273
     * {@code string} when iterating over native Java arrays, {@code List}, and {@code Map} objects.
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   274
     * @param obj object to iterate on.
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   275
     * @return iterator over the object's property names.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   276
     */
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   277
    public static Iterator<?> toPropertyIterator(final Object obj) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   278
        if (obj instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   279
            return ((ScriptObject)obj).propertyIterator();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   280
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   281
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   282
        if (obj != null && obj.getClass().isArray()) {
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   283
            return new RangeIterator(Array.getLength(obj));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   284
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   285
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   286
        if (obj instanceof JSObject) {
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   287
            return ((JSObject)obj).keySet().iterator();
17978
750d0582d8e2 8015830: Javascript mapping of ScriptEngine bindings does not expose keys
sundar
parents: 17778
diff changeset
   288
        }
750d0582d8e2 8015830: Javascript mapping of ScriptEngine bindings does not expose keys
sundar
parents: 17778
diff changeset
   289
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   290
        if (obj instanceof List) {
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   291
            return new RangeIterator(((List<?>)obj).size());
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   292
        }
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   293
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   294
        if (obj instanceof Map) {
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   295
            return ((Map<?,?>)obj).keySet().iterator();
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   296
        }
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   297
21446
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   298
        final Object wrapped = Global.instance().wrapAsObject(obj);
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   299
        if (wrapped instanceof ScriptObject) {
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   300
            return ((ScriptObject)wrapped).propertyIterator();
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   301
        }
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   302
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   303
        return Collections.emptyIterator();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   304
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   306
    private static final class RangeIterator implements Iterator<Integer> {
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   307
        private final int length;
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   308
        private int index;
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   309
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   310
        RangeIterator(final int length) {
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   311
            this.length = length;
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   312
        }
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   313
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   314
        @Override
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   315
        public boolean hasNext() {
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   316
            return index < length;
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   317
        }
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   318
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   319
        @Override
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   320
        public Integer next() {
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   321
            return index++;
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   322
        }
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   323
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   324
        @Override
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   325
        public void remove() {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
   326
            throw new UnsupportedOperationException("remove");
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   327
        }
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   328
    }
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   329
37918
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   330
    // value Iterator for important Java objects - arrays, maps, iterables.
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   331
    private static Iterator<?> iteratorForJavaArrayOrList(final Object obj) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
        if (obj != null && obj.getClass().isArray()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
            final Object array  = obj;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
            final int    length = Array.getLength(obj);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   336
            return new Iterator<Object>() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   337
                private int index = 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   338
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   339
                @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   340
                public boolean hasNext() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   341
                    return index < length;
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
                @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   345
                public Object next() {
16226
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   346
                    if (index >= length) {
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   347
                        throw new NoSuchElementException();
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   348
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   349
                    return Array.get(array, index++);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   350
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   351
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   352
                @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   353
                public void remove() {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
   354
                    throw new UnsupportedOperationException("remove");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   355
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   356
            };
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   357
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   358
37918
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   359
        if (obj instanceof Iterable) {
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   360
            return ((Iterable<?>)obj).iterator();
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   361
        }
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   362
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   363
        return null;
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   364
    }
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   365
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   366
    /**
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   367
     * Returns an iterator over property values used in the {@code for each...in} statement. Aside from built-in JS
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   368
     * objects, it also operates on Java arrays, any {@link Iterable}, as well as on {@link Map} objects, iterating over
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   369
     * map values.
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   370
     * @param obj object to iterate on.
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   371
     * @return iterator over the object's property values.
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   372
     */
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   373
    public static Iterator<?> toValueIterator(final Object obj) {
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   374
        if (obj instanceof ScriptObject) {
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   375
            return ((ScriptObject)obj).valueIterator();
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   376
        }
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   377
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   378
        if (obj instanceof JSObject) {
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   379
            return ((JSObject)obj).values().iterator();
17978
750d0582d8e2 8015830: Javascript mapping of ScriptEngine bindings does not expose keys
sundar
parents: 17778
diff changeset
   380
        }
750d0582d8e2 8015830: Javascript mapping of ScriptEngine bindings does not expose keys
sundar
parents: 17778
diff changeset
   381
37918
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   382
        final Iterator<?> itr = iteratorForJavaArrayOrList(obj);
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   383
        if (itr != null) {
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   384
            return itr;
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   385
        }
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   386
19618
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   387
        if (obj instanceof Map) {
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   388
            return ((Map<?,?>)obj).values().iterator();
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   389
        }
6b73157185e0 8022903: Enhance for-in and for-each for Lists and Maps
attila
parents: 19460
diff changeset
   390
21446
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   391
        final Object wrapped = Global.instance().wrapAsObject(obj);
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   392
        if (wrapped instanceof ScriptObject) {
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   393
            return ((ScriptObject)wrapped).valueIterator();
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   394
        }
2fcb0f7e407f 8026955: for-in should convert primitive values to object
hannesw
parents: 19889
diff changeset
   395
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   396
        return Collections.emptyIterator();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   397
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   399
    /**
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   400
     * Returns an iterator over property values used in the {@code for ... of} statement. The iterator uses the
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   401
     * Iterator interface defined in version 6 of the ECMAScript specification.
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   402
     *
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   403
     * @param obj object to iterate on.
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   404
     * @return iterator based on the ECMA 6 Iterator interface.
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   405
     */
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   406
    public static Iterator<?> toES6Iterator(final Object obj) {
37918
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   407
        // if not a ScriptObject, try convenience iterator for Java objects!
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   408
        if (!(obj instanceof ScriptObject)) {
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   409
            final Iterator<?> itr = iteratorForJavaArrayOrList(obj);
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   410
            if (itr != null) {
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   411
                return itr;
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   412
            }
44052
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   413
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   414
        if (obj instanceof Map) {
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   415
            return new Iterator<Object>() {
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   416
                private Iterator<?> iter = ((Map<?,?>)obj).entrySet().iterator();
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   417
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   418
                @Override
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   419
                public boolean hasNext() {
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   420
                    return iter.hasNext();
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   421
                }
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   422
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   423
                @Override
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   424
                public Object next() {
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   425
                    Map.Entry<?,?> next = (Map.Entry)iter.next();
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   426
                    Object[] keyvalue = new Object[]{next.getKey(), next.getValue()};
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   427
                    NativeArray array = NativeJava.from(null, keyvalue);
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   428
                    return array;
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   429
                }
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   430
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   431
                @Override
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   432
                public void remove() {
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   433
                    iter.remove();
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   434
                }
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   435
            };
874212484a4e 8156743: ES6 for..of should work for Java Maps and Sets
sdama
parents: 43352
diff changeset
   436
        }
37918
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   437
        }
21f72dc38a96 8156665: ES6 for..of should work on Java Iterables and Java arrays
sundar
parents: 36696
diff changeset
   438
36696
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   439
        final Global global = Global.instance();
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   440
        final Object iterator = AbstractIterator.getIterator(Global.toObject(obj), global);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   441
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   442
        final InvokeByName nextInvoker = AbstractIterator.getNextInvoker(global);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   443
        final MethodHandle doneInvoker = AbstractIterator.getDoneInvoker(global);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   444
        final MethodHandle valueInvoker = AbstractIterator.getValueInvoker(global);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   445
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   446
        return new Iterator<Object>() {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   447
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   448
            private Object nextResult = nextResult();
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   449
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   450
            private Object nextResult() {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   451
                try {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   452
                    final Object next = nextInvoker.getGetter().invokeExact(iterator);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   453
                    if (Bootstrap.isCallable(next)) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   454
                        return nextInvoker.getInvoker().invokeExact(next, iterator, (Object) null);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   455
                    }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   456
                } catch (final RuntimeException|Error r) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   457
                    throw r;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   458
                } catch (final Throwable t) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   459
                    throw new RuntimeException(t);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   460
                }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   461
                return null;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   462
            }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   463
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   464
            @Override
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   465
            public boolean hasNext() {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   466
                if (nextResult == null) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   467
                    return false;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   468
                }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   469
                try {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   470
                    final Object done = doneInvoker.invokeExact(nextResult);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   471
                    return !JSType.toBoolean(done);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   472
                } catch (final RuntimeException|Error r) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   473
                    throw r;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   474
                } catch (final Throwable t) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   475
                    throw new RuntimeException(t);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   476
                }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   477
            }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   478
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   479
            @Override
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   480
            public Object next() {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   481
                if (nextResult == null) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   482
                    return Undefined.getUndefined();
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   483
                }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   484
                try {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   485
                    final Object result = nextResult;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   486
                    nextResult = nextResult();
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   487
                    return valueInvoker.invokeExact(result);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   488
                } catch (final RuntimeException|Error r) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   489
                    throw r;
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   490
                } catch (final Throwable t) {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   491
                    throw new RuntimeException(t);
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   492
                }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   493
            }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   494
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   495
            @Override
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   496
            public void remove() {
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   497
                throw new UnsupportedOperationException("remove");
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   498
            }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   499
        };
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   500
    }
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   501
39ff39c8e396 8151700: Add support for ES6 for-of
hannesw
parents: 34447
diff changeset
   502
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   503
     * Merge a scope into its prototype's map.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   504
     * Merge a scope into its prototype.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   505
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   506
     * @param scope Scope to merge.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   507
     * @return prototype object after merge
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   508
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   509
    public static ScriptObject mergeScope(final ScriptObject scope) {
31194
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29283
diff changeset
   510
        final ScriptObject parentScope = scope.getProto();
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29283
diff changeset
   511
        parentScope.addBoundProperties(scope);
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29283
diff changeset
   512
        return parentScope;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   514
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   516
     * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 31828
diff changeset
   517
     * better performance by creating a dynamic invoker using {@link Bootstrap#createDynamicCallInvoker(Class, Class...)}
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 31828
diff changeset
   518
     * then using its {@link MethodHandle#invokeExact(Object...)} method instead.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   519
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   520
     * @param target ScriptFunction object.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   521
     * @param self   Receiver in call.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
     * @param args   Call arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
     * @return Call result.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   524
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
    public static Object apply(final ScriptFunction target, final Object self, final Object... args) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   526
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   527
            return target.invoke(self, args);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   528
        } catch (final RuntimeException | Error e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   529
            throw e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
        } catch (final Throwable t) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   531
            throw new RuntimeException(t);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   532
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   535
    /**
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   536
     * Throws a reference error for an undefined variable.
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   537
     *
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   538
     * @param name the variable name
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   539
     */
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   540
    public static void throwReferenceError(final String name) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   541
        throw referenceError("not.defined", name);
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   542
    }
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   543
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26068
diff changeset
   544
    /**
29281
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   545
     * Throws a type error for an assignment to a const.
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   546
     *
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   547
     * @param name the const name
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   548
     */
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   549
    public static void throwConstTypeError(final String name) {
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   550
        throw typeError("assign.constant", name);
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   551
    }
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   552
8cc2618a07aa 8073707: const re-assignment should not reported as a early error
hannesw
parents: 29133
diff changeset
   553
    /**
18614
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   554
     * Call a script function as a constructor with given args.
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   555
     *
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   556
     * @param target ScriptFunction object.
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   557
     * @param args   Call arguments.
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   558
     * @return Constructor call result.
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   559
     */
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   560
    public static Object construct(final ScriptFunction target, final Object... args) {
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   561
        try {
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   562
            return target.construct(args);
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   563
        } catch (final RuntimeException | Error e) {
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   564
            throw e;
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   565
        } catch (final Throwable t) {
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   566
            throw new RuntimeException(t);
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   567
        }
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   568
    }
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   569
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 18334
diff changeset
   570
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   571
     * Generic implementation of ECMA 9.12 - SameValue algorithm
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   572
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   573
     * @param x first value to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
     * @param y second value to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   576
     * @return true if both objects have the same value
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   577
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   578
    public static boolean sameValue(final Object x, final Object y) {
24752
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
   579
        final JSType xType = JSType.ofNoFunction(x);
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
   580
        final JSType yType = JSType.ofNoFunction(y);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   581
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   582
        if (xType != yType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   583
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   584
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   585
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   586
        if (xType == JSType.UNDEFINED || xType == JSType.NULL) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   587
            return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   588
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   589
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   590
        if (xType == JSType.NUMBER) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   591
            final double xVal = ((Number)x).doubleValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   592
            final double yVal = ((Number)y).doubleValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
            if (Double.isNaN(xVal) && Double.isNaN(yVal)) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
                return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
            // checking for xVal == -0.0 and yVal == +0.0 or vice versa
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   599
            if (xVal == 0.0 && Double.doubleToLongBits(xVal) != Double.doubleToLongBits(yVal)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
                return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   602
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   603
            return xVal == yVal;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   604
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   605
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   606
        if (xType == JSType.STRING || yType == JSType.BOOLEAN) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   607
            return x.equals(y);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   608
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   609
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   610
        return x == y;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   611
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   612
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   613
    /**
16226
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   614
     * Returns AST as JSON compatible string. This is used to
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   615
     * implement "parse" function in resources/parse.js script.
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   616
     *
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   617
     * @param code code to be parsed
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   618
     * @param name name of the code source (used for location)
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   619
     * @param includeLoc tells whether to include location information for nodes or not
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   620
     * @return JSON string representation of AST of the supplied code
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   621
     */
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   622
    public static String parse(final String code, final String name, final boolean includeLoc) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24733
diff changeset
   623
        return JSONWriter.parse(Context.getContextTrusted(), code, name, includeLoc);
16226
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   624
    }
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   625
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   626
    /**
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   627
     * Test whether a char is valid JavaScript whitespace
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   628
     * @param ch a char
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   629
     * @return true if valid JavaScript whitespace
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   630
     */
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   631
    public static boolean isJSWhitespace(final char ch) {
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   632
        return Lexer.isJSWhitespace(ch);
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   633
    }
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   634
0e4f37e6cc40 8007915: Nashorn IR, codegen, parser packages and Context instance should be inaccessible to user code
sundar
parents: 16206
diff changeset
   635
    /**
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
   636
     * Entering a {@code with} node requires new scope. This is the implementation. When exiting the with statement,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
   637
     * use {@link ScriptObject#getProto()} on the scope.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   638
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   639
     * @param scope      existing scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   640
     * @param expression expression in with
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   641
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   642
     * @return {@link WithObject} that is the new scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   643
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   644
    public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 21446
diff changeset
   645
        final Global global = Context.getGlobal();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   646
        if (expression == UNDEFINED) {
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16240
diff changeset
   647
            throw typeError(global, "cant.apply.with.to.undefined");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   648
        } else if (expression == null) {
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16240
diff changeset
   649
            throw typeError(global, "cant.apply.with.to.null");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   650
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   651
25247
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24762
diff changeset
   652
        if (expression instanceof ScriptObjectMirror) {
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24762
diff changeset
   653
            final Object unwrapped = ScriptObjectMirror.unwrap(expression, global);
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24762
diff changeset
   654
            if (unwrapped instanceof ScriptObject) {
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24762
diff changeset
   655
                return new WithObject(scope, (ScriptObject)unwrapped);
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24762
diff changeset
   656
            }
25821
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   657
            // foreign ScriptObjectMirror
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   658
            final ScriptObject exprObj = global.newObject();
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   659
            NativeObject.bindAllProperties(exprObj, (ScriptObjectMirror)expression);
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   660
            return new WithObject(scope, exprObj);
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   661
        }
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   662
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   663
        final Object wrappedExpr = JSType.toScriptObject(global, expression);
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   664
        if (wrappedExpr instanceof ScriptObject) {
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25250
diff changeset
   665
            return new WithObject(scope, (ScriptObject)wrappedExpr);
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19638
diff changeset
   666
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   667
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19638
diff changeset
   668
        throw typeError(global, "cant.apply.with.to.non.scriptobject");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   669
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   670
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   671
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   672
     * ECMA 11.6.1 - The addition operator (+) - generic implementation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   673
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   674
     * @param x  first term
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   675
     * @param y  second term
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   676
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   677
     * @return result of addition
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   678
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   679
    public static Object ADD(final Object x, final Object y) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   680
        // This prefix code to handle Number special is for optimization.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   681
        final boolean xIsNumber = x instanceof Number;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   682
        final boolean yIsNumber = y instanceof Number;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   683
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   684
        if (xIsNumber && yIsNumber) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   685
             return ((Number)x).doubleValue() + ((Number)y).doubleValue();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   686
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   687
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   688
        final boolean xIsUndefined = x == UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   689
        final boolean yIsUndefined = y == UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   690
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   691
        if (xIsNumber && yIsUndefined || xIsUndefined && yIsNumber || xIsUndefined && yIsUndefined) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   692
            return Double.NaN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   693
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   694
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   695
        // code below is as per the spec.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   696
        final Object xPrim = JSType.toPrimitive(x);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
        final Object yPrim = JSType.toPrimitive(y);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
29282
a8523237b66c 8074031: Canonicalize is-a-JS-string tests
attila
parents: 29281
diff changeset
   699
        if (isString(xPrim) || isString(yPrim)) {
25250
b5a4e0ac31d1 8047359: large string size RangeError should be thrown rather than reporting negative length
sundar
parents: 25247
diff changeset
   700
            try {
b5a4e0ac31d1 8047359: large string size RangeError should be thrown rather than reporting negative length
sundar
parents: 25247
diff changeset
   701
                return new ConsString(JSType.toCharSequence(xPrim), JSType.toCharSequence(yPrim));
b5a4e0ac31d1 8047359: large string size RangeError should be thrown rather than reporting negative length
sundar
parents: 25247
diff changeset
   702
            } catch (final IllegalArgumentException iae) {
b5a4e0ac31d1 8047359: large string size RangeError should be thrown rather than reporting negative length
sundar
parents: 25247
diff changeset
   703
                throw rangeError(iae, "concat.string.too.big");
b5a4e0ac31d1 8047359: large string size RangeError should be thrown rather than reporting negative length
sundar
parents: 25247
diff changeset
   704
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   705
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   706
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   707
        return JSType.toNumber(xPrim) + JSType.toNumber(yPrim);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   708
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   709
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   710
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   711
     * Debugger hook.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   712
     * TODO: currently unimplemented
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   714
     * @return undefined
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   715
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   716
    public static Object DEBUGGER() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   717
        return UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   718
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   720
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   721
     * New hook
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   723
     * @param clazz type for the clss
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   724
     * @param args  constructor arguments
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   725
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
     * @return undefined
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   727
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   728
    public static Object NEW(final Object clazz, final Object... args) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
        return UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   731
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   732
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   733
     * ECMA 11.4.3 The typeof Operator - generic implementation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   735
     * @param object   the object from which to retrieve property to type check
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   736
     * @param property property in object to check
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   737
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   738
     * @return type name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   739
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   740
    public static Object TYPEOF(final Object object, final Object property) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   741
        Object obj = object;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   742
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   743
        if (property != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   744
            if (obj instanceof ScriptObject) {
39164
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   745
                // this is a scope identifier
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   746
                assert property instanceof String;
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   747
                final ScriptObject sobj = (ScriptObject) obj;
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   748
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   749
                final FindProperty find = sobj.findProperty(property, true, true, sobj);
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   750
                if (find != null) {
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   751
                    obj = find.getObjectValue();
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   752
                } else {
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   753
                    obj = sobj.invokeNoSuchProperty(property, false, UnwarrantedOptimismException.INVALID_PROGRAM_POINT);
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   754
                }
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 37918
diff changeset
   755
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
   756
                if(Global.isLocationPropertyPlaceholder(obj)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
   757
                    if(CompilerConstants.__LINE__.name().equals(property)) {
31549
b627094c5649 8130734: Apply transformations found by netbeans Refactor->Inspect and transform menu
sundar
parents: 31194
diff changeset
   758
                        obj = 0;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
   759
                    } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
   760
                        obj = "";
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
   761
                    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21446
diff changeset
   762
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   763
            } else if (object instanceof Undefined) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   764
                obj = ((Undefined)obj).get(property);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   765
            } else if (object == null) {
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16240
diff changeset
   766
                throw typeError("cant.get.property", safeToString(property), "null");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   767
            } else if (JSType.isPrimitive(obj)) {
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16151
diff changeset
   768
                obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property);
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   769
            } else if (obj instanceof JSObject) {
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   770
                obj = ((JSObject)obj).getMember(property.toString());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   771
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   772
                obj = UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   773
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   774
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   775
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   776
        return JSType.of(obj).typeName();
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
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   780
     * Throw ReferenceError when LHS of assignment or increment/decrement
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   781
     * operator is not an assignable node (say a literal)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   782
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   783
     * @param lhs Evaluated LHS
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   784
     * @param rhs Evaluated RHS
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   785
     * @param msg Additional LHS info for error message
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   786
     * @return undefined
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   787
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   788
    public static Object REFERENCE_ERROR(final Object lhs, final Object rhs, final Object msg) {
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16240
diff changeset
   789
        throw referenceError("cant.be.used.as.lhs", Objects.toString(msg));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   790
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   791
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   792
    /**
48354
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   793
     * ECMA 11.4.1 - delete operator, implementation for slow scopes
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   794
     *
48354
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   795
     * This implementation of 'delete' walks the scope chain to find the scope that contains the
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   796
     * property to be deleted, then invokes delete on it. Always used on scopes, never strict.
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   797
     *
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   798
     * @param obj       top scope object
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   799
     * @param property  property to delete
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   800
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   801
     * @return true if property was successfully found and deleted
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   802
     */
48354
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   803
    public static boolean slowDelete(final ScriptObject obj, final String property) {
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   804
        ScriptObject sobj = obj;
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   805
        while (sobj != null && sobj.isScope()) {
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   806
            final FindProperty find = sobj.findProperty(property, false);
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   807
            if (find != null) {
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   808
                return sobj.delete(property, false);
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   809
            }
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   810
            sobj = sobj.getProto();
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   811
        }
48354
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   812
        return obj.delete(property, false);
31828
50189d0dacb0 8131683: Delete fails over multiple scopes
hannesw
parents: 31549
diff changeset
   813
    }
50189d0dacb0 8131683: Delete fails over multiple scopes
hannesw
parents: 31549
diff changeset
   814
50189d0dacb0 8131683: Delete fails over multiple scopes
hannesw
parents: 31549
diff changeset
   815
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   816
     * ECMA 11.4.1 - delete operator, special case
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   817
     *
48354
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   818
     * This is 'delete' on a scope; it always fails under strict mode.
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   819
     * It always throws an exception, but is declared to return a boolean
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   820
     * to be compatible with the delete operator type.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   821
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   822
     * @param property  property to delete
48354
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   823
     * @return nothing, always throws an exception.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   824
     */
48354
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   825
    public static boolean strictFailDelete(final String property) {
c96d4c720995 8193371: Use Dynalink REMOVE operation in Nashorn
attila
parents: 47216
diff changeset
   826
        throw syntaxError("strict.cant.delete", property);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   827
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   828
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   829
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   830
     * ECMA 11.9.1 - The equals operator (==) - generic implementation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   831
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   832
     * @param x first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   833
     * @param y second object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   834
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   835
     * @return true if type coerced versions of objects are equal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   836
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   837
    public static boolean EQ(final Object x, final Object y) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   838
        return equals(x, y);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   839
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   840
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   841
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   842
     * ECMA 11.9.2 - The does-not-equal operator (==) - generic implementation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   843
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   844
     * @param x first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   845
     * @param y second object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   846
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   847
     * @return true if type coerced versions of objects are not equal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   848
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   849
    public static boolean NE(final Object x, final Object y) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   850
        return !EQ(x, y);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   851
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   852
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   853
    /** ECMA 11.9.3 The Abstract Equality Comparison Algorithm */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   854
    private static boolean equals(final Object x, final Object y) {
34445
2637e398e0a4 8141407: Wrong evaluation of a != a when a = NaN
hannesw
parents: 33695
diff changeset
   855
        // We want to keep this method small so we skip reference equality check for numbers
2637e398e0a4 8141407: Wrong evaluation of a != a when a = NaN
hannesw
parents: 33695
diff changeset
   856
        // as NaN should return false when compared to itself (JDK-8043608).
2637e398e0a4 8141407: Wrong evaluation of a != a when a = NaN
hannesw
parents: 33695
diff changeset
   857
        if (x == y && !(x instanceof Number)) {
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   858
            return true;
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   859
        }
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   860
        if (x instanceof ScriptObject && y instanceof ScriptObject) {
29133
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   861
            return false; // x != y
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   862
        }
26052
41d18e9e45a4 8053910: ScriptObjectMirror causing havoc with Invocation interface
sundar
parents: 25828
diff changeset
   863
        if (x instanceof ScriptObjectMirror || y instanceof ScriptObjectMirror) {
41d18e9e45a4 8053910: ScriptObjectMirror causing havoc with Invocation interface
sundar
parents: 25828
diff changeset
   864
            return ScriptObjectMirror.identical(x, y);
41d18e9e45a4 8053910: ScriptObjectMirror causing havoc with Invocation interface
sundar
parents: 25828
diff changeset
   865
        }
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   866
        return equalValues(x, y);
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   867
    }
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   868
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   869
    /**
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   870
     * Extracted portion of {@code equals()} that compares objects by value (or by reference, if no known value
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   871
     * comparison applies).
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   872
     * @param x one value
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   873
     * @param y another value
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   874
     * @return true if they're equal according to 11.9.3
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   875
     */
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   876
    private static boolean equalValues(final Object x, final Object y) {
24752
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
   877
        final JSType xType = JSType.ofNoFunction(x);
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
   878
        final JSType yType = JSType.ofNoFunction(y);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   879
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   880
        if (xType == yType) {
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   881
            return equalSameTypeValues(x, y, xType);
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   882
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   883
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   884
        return equalDifferentTypeValues(x, y, xType, yType);
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   885
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   886
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   887
    /**
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   888
     * Extracted portion of {@link #equals(Object, Object)} and {@link #strictEquals(Object, Object)} that compares
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   889
     * values belonging to the same JSType.
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   890
     * @param x one value
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   891
     * @param y another value
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   892
     * @param type the common type for the values
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   893
     * @return true if they're equal
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   894
     */
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   895
    private static boolean equalSameTypeValues(final Object x, final Object y, final JSType type) {
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   896
        if (type == JSType.UNDEFINED || type == JSType.NULL) {
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   897
            return true;
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   898
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   900
        if (type == JSType.NUMBER) {
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   901
            return ((Number)x).doubleValue() == ((Number)y).doubleValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   902
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   903
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   904
        if (type == JSType.STRING) {
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   905
            // String may be represented by ConsString
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   906
            return x.toString().equals(y.toString());
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   907
        }
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   908
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   909
        if (type == JSType.BOOLEAN) {
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   910
            return ((Boolean)x).booleanValue() == ((Boolean)y).booleanValue();
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   911
        }
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   912
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   913
        return x == y;
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   914
    }
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   915
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   916
    /**
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   917
     * Extracted portion of {@link #equals(Object, Object)} that compares values belonging to different JSTypes.
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   918
     * @param x one value
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   919
     * @param y another value
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   920
     * @param xType the type for the value x
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   921
     * @param yType the type for the value y
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   922
     * @return true if they're equal
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   923
     */
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
   924
    private static boolean equalDifferentTypeValues(final Object x, final Object y, final JSType xType, final JSType yType) {
29133
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   925
        if (isUndefinedAndNull(xType, yType) || isUndefinedAndNull(yType, xType)) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   926
            return true;
29133
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   927
        } else if (isNumberAndString(xType, yType)) {
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   928
            return equalNumberToString(x, y);
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   929
        } else if (isNumberAndString(yType, xType)) {
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   930
            // Can reverse order as both are primitives
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   931
            return equalNumberToString(y, x);
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   932
        } else if (xType == JSType.BOOLEAN) {
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   933
            return equalBooleanToAny(x, y);
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   934
        } else if (yType == JSType.BOOLEAN) {
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   935
            // Can reverse order as y is primitive
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   936
            return equalBooleanToAny(y, x);
33695
f3f1bd0f638e 8142864: Raw types warning in WeakValueCache
hannesw
parents: 33690
diff changeset
   937
        } else if (isPrimitiveAndObject(xType, yType)) {
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33414
diff changeset
   938
            return equalWrappedPrimitiveToObject(x, y);
33695
f3f1bd0f638e 8142864: Raw types warning in WeakValueCache
hannesw
parents: 33690
diff changeset
   939
        } else if (isPrimitiveAndObject(yType, xType)) {
29133
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   940
            // Can reverse order as y is primitive
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33414
diff changeset
   941
            return equalWrappedPrimitiveToObject(y, x);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   942
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   943
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   944
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   945
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   946
29133
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   947
    private static boolean isUndefinedAndNull(final JSType xType, final JSType yType) {
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   948
        return xType == JSType.UNDEFINED && yType == JSType.NULL;
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   949
    }
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   950
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   951
    private static boolean isNumberAndString(final JSType xType, final JSType yType) {
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   952
        return xType == JSType.NUMBER && yType == JSType.STRING;
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   953
    }
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   954
33695
f3f1bd0f638e 8142864: Raw types warning in WeakValueCache
hannesw
parents: 33690
diff changeset
   955
    private static boolean isPrimitiveAndObject(final JSType xType, final JSType yType) {
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33414
diff changeset
   956
        return (xType == JSType.NUMBER || xType == JSType.STRING || xType == JSType.SYMBOL) && yType == JSType.OBJECT;
29133
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   957
    }
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   958
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   959
    private static boolean equalNumberToString(final Object num, final Object str) {
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   960
        // Specification says comparing a number to string should be done as "equals(num, JSType.toNumber(str))". We
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   961
        // can short circuit it to this as we know that "num" is a number, so it'll end up being a number-number
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   962
        // comparison.
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   963
        return ((Number)num).doubleValue() == JSType.toNumber(str.toString());
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   964
    }
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   965
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   966
    private static boolean equalBooleanToAny(final Object bool, final Object any) {
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   967
        return equals(JSType.toNumber((Boolean)bool), any);
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   968
    }
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   969
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33414
diff changeset
   970
    private static boolean equalWrappedPrimitiveToObject(final Object numOrStr, final Object any) {
29133
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   971
        return equals(numOrStr, JSType.toPrimitive(any));
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   972
    }
1cd7d8af99ba 8072426: Can't compare Java objects to strings or numbers
attila
parents: 26768
diff changeset
   973
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   974
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   975
     * ECMA 11.9.4 - The strict equal operator (===) - generic implementation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   976
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   977
     * @param x first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   978
     * @param y second object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   979
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   980
     * @return true if objects are equal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   981
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   982
    public static boolean EQ_STRICT(final Object x, final Object y) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   983
        return strictEquals(x, y);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   984
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   985
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   986
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   987
     * ECMA 11.9.5 - The strict non equal operator (!==) - generic implementation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   988
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   989
     * @param x first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   990
     * @param y second object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   991
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   992
     * @return true if objects are not equal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   993
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   994
    public static boolean NE_STRICT(final Object x, final Object y) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   995
        return !EQ_STRICT(x, y);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   996
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   997
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   998
    /** ECMA 11.9.6 The Strict Equality Comparison Algorithm */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   999
    private static boolean strictEquals(final Object x, final Object y) {
25828
077046a5d726 8044786: Some tests fail with non-optimistic compilation
attila
parents: 25821
diff changeset
  1000
        // NOTE: you might be tempted to do a quick x == y comparison. Remember, though, that any Double object having
077046a5d726 8044786: Some tests fail with non-optimistic compilation
attila
parents: 25821
diff changeset
  1001
        // NaN value is not equal to itself by value even though it is referentially.
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
  1002
24752
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
  1003
        final JSType xType = JSType.ofNoFunction(x);
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
  1004
        final JSType yType = JSType.ofNoFunction(y);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1005
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1006
        if (xType != yType) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1007
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1008
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1009
24762
96a251e57232 8043608: Make equality tests inline better
attila
parents: 24752
diff changeset
  1010
        return equalSameTypeValues(x, y, xType);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1011
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1012
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1013
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1014
     * ECMA 11.8.6 - The in operator - generic implementation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1015
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1016
     * @param property property to check for
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1017
     * @param obj object in which to check for property
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1018
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1019
     * @return true if objects are equal
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1020
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1021
    public static boolean IN(final Object property, final Object obj) {
24752
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
  1022
        final JSType rvalType = JSType.ofNoFunction(obj);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1023
24752
c835f368e8e0 8043002: Improve performance of Nashorn equality operators
attila
parents: 24745
diff changeset
  1024
        if (rvalType == JSType.OBJECT) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1025
            if (obj instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1026
                return ((ScriptObject)obj).has(property);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1027
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1028
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1029
            if (obj instanceof JSObject) {
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1030
                return ((JSObject)obj).hasMember(Objects.toString(property));
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1031
            }
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1032
43352
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1033
            final Object key = JSType.toPropertyKey(property);
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1034
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1035
            if (obj instanceof StaticClass) {
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1036
                final Class<?> clazz = ((StaticClass) obj).getRepresentedClass();
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1037
                return BeansLinker.getReadableStaticPropertyNames(clazz).contains(Objects.toString(key))
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1038
                    || BeansLinker.getStaticMethodNames(clazz).contains(Objects.toString(key));
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1039
            } else {
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1040
                if (obj instanceof Map && ((Map) obj).containsKey(key)) {
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1041
                    return true;
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1042
                }
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1043
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1044
                final int index = ArrayIndex.getArrayIndex(key);
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1045
                if (index >= 0) {
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1046
                    if (obj instanceof List && index < ((List) obj).size()) {
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1047
                        return true;
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1048
                    }
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1049
                    if (obj.getClass().isArray() && index < Array.getLength(obj)) {
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1050
                        return true;
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1051
                    }
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1052
                }
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1053
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1054
                return BeansLinker.getReadableInstancePropertyNames(obj.getClass()).contains(Objects.toString(key))
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1055
                    || BeansLinker.getInstanceMethodNames(obj.getClass()).contains(Objects.toString(key));
1e536b9ddf07 8173480: in operator should work on java objects and classes
hannesw
parents: 39164
diff changeset
  1056
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1057
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1058
17778
991ccffbeb13 8015459: Octane test run fails on Turkish locale
sundar
parents: 16272
diff changeset
  1059
        throw typeError("in.with.non.object", rvalType.toString().toLowerCase(Locale.ENGLISH));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1060
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1061
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1062
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1063
     * ECMA 11.8.6 - The strict instanceof operator - generic implementation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1064
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1065
     * @param obj first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1066
     * @param clazz type to check against
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1067
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1068
     * @return true if {@code obj} is an instanceof {@code clazz}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1069
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1070
    public static boolean INSTANCEOF(final Object obj, final Object clazz) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1071
        if (clazz instanceof ScriptFunction) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1072
            if (obj instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1073
                return ((ScriptObject)clazz).isInstance((ScriptObject)obj);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1074
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1075
            return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1076
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1077
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1078
        if (clazz instanceof StaticClass) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1079
            return ((StaticClass)clazz).getRepresentedClass().isInstance(obj);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1080
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1081
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1082
        if (clazz instanceof JSObject) {
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1083
            return ((JSObject)clazz).isInstance(obj);
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1084
        }
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1085
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1086
        // provide for reverse hook
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1087
        if (obj instanceof JSObject) {
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
  1088
            return ((JSObject)obj).isInstanceOf(clazz);
18334
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 17978
diff changeset
  1089
        }
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 17978
diff changeset
  1090
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16240
diff changeset
  1091
        throw typeError("instanceof.on.non.object");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1092
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1093
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1094
    /**
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16262
diff changeset
  1095
     * ECMA 11.8.1 - The less than operator ({@literal <}) - generic implementation
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1096
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1097
     * @param x first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1098
     * @param y second object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1099
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1100
     * @return true if x is less than y
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1101
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1102
    public static boolean LT(final Object x, final Object y) {
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1103
        final Object px = JSType.toPrimitive(x, Number.class);
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1104
        final Object py = JSType.toPrimitive(y, Number.class);
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1105
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1106
        return areBothString(px, py) ? px.toString().compareTo(py.toString()) < 0 :
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1107
            JSType.toNumber(px) < JSType.toNumber(py);
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1108
    }
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1109
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1110
    private static boolean areBothString(final Object x, final Object y) {
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1111
        return isString(x) && isString(y);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1112
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1113
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1114
    /**
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16262
diff changeset
  1115
     * ECMA 11.8.2 - The greater than operator ({@literal >}) - generic implementation
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1116
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1117
     * @param x first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1118
     * @param y second object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1119
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1120
     * @return true if x is greater than y
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1121
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1122
    public static boolean GT(final Object x, final Object y) {
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1123
        final Object px = JSType.toPrimitive(x, Number.class);
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1124
        final Object py = JSType.toPrimitive(y, Number.class);
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1125
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1126
        return areBothString(px, py) ? px.toString().compareTo(py.toString()) > 0 :
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1127
            JSType.toNumber(px) > JSType.toNumber(py);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1128
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1129
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1130
    /**
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16262
diff changeset
  1131
     * ECMA 11.8.3 - The less than or equal operator ({@literal <=}) - generic implementation
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1132
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1133
     * @param x first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1134
     * @param y second object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1135
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1136
     * @return true if x is less than or equal to y
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1137
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1138
    public static boolean LE(final Object x, final Object y) {
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1139
        final Object px = JSType.toPrimitive(x, Number.class);
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1140
        final Object py = JSType.toPrimitive(y, Number.class);
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1141
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1142
        return areBothString(px, py) ? px.toString().compareTo(py.toString()) <= 0 :
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1143
            JSType.toNumber(px) <= JSType.toNumber(py);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1144
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1145
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1146
    /**
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16262
diff changeset
  1147
     * ECMA 11.8.4 - The greater than or equal operator ({@literal >=}) - generic implementation
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1148
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1149
     * @param x first object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1150
     * @param y second object to compare
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1151
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1152
     * @return true if x is greater than or equal to y
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1153
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1154
    public static boolean GE(final Object x, final Object y) {
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1155
        final Object px = JSType.toPrimitive(x, Number.class);
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1156
        final Object py = JSType.toPrimitive(y, Number.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1157
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1158
        return areBothString(px, py) ? px.toString().compareTo(py.toString()) >= 0 :
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1159
            JSType.toNumber(px) >= JSType.toNumber(py);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1160
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1161
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1162
    /**
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1163
     * Tag a reserved name as invalidated - used when someone writes
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1164
     * to a property with this name - overly conservative, but link time
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1165
     * is too late to apply e.g. apply-&gt;call specialization
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1166
     * @param name property name
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1167
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1168
    public static void invalidateReservedBuiltinName(final String name) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1169
        final Context context = Context.getContextTrusted();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1170
        final SwitchPoint sp = context.getBuiltinSwitchPoint(name);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1171
        assert sp != null;
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1172
        context.getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 29282
diff changeset
  1173
        SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26377
diff changeset
  1174
    }
33414
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1175
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1176
    /**
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1177
     * ES6 12.2.9.3 Runtime Semantics: GetTemplateObject(templateLiteral).
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1178
     *
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1179
     * @param rawStrings array of template raw values
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1180
     * @param cookedStrings array of template values
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1181
     * @return template object
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1182
     */
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1183
    public static ScriptObject GET_TEMPLATE_OBJECT(final Object rawStrings, final Object cookedStrings) {
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1184
        final ScriptObject template = (ScriptObject)cookedStrings;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1185
        final ScriptObject rawObj = (ScriptObject)rawStrings;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1186
        assert rawObj.getArray().length() == template.getArray().length();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1187
        template.addOwnProperty("raw", Property.NOT_WRITABLE | Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, rawObj.freeze());
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1188
        template.freeze();
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1189
        return template;
2e284c36d51f 8134941: Implement ES6 template literal support
mhaupt
parents: 33343
diff changeset
  1190
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1191
}