src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java
author hannesw
Wed, 21 Mar 2018 16:55:34 +0100
changeset 49275 c639a6b33c5c
parent 49257 82f763a9cc22
permissions -rw-r--r--
8199869: Missing copyright headers in nashorn source code Reviewed-by: sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
35407
204abe4d8cbc 8147591: Revisit Collection.toArray(new T[size]) calls in nashorn and dynalink code
mhaupt
parents: 35406
diff changeset
     2
 * Copyright (c) 2010, 2016, 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
package jdk.nashorn.internal.runtime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 20946
diff changeset
    28
import static jdk.nashorn.internal.lookup.Lookup.MH;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    30
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    31
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
36686
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
    32
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import java.lang.invoke.MethodHandle;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import java.lang.invoke.MethodHandles;
33331
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 32695
diff changeset
    35
import java.lang.invoke.MethodHandles.Lookup;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
import java.lang.invoke.MethodType;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
    37
import java.lang.invoke.SwitchPoint;
33341
cc9fa3638714 8139905: Add a convenience AccessControlContext factory
attila
parents: 33337
diff changeset
    38
import java.security.AccessControlContext;
33331
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 32695
diff changeset
    39
import java.security.AccessController;
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 32695
diff changeset
    40
import java.security.PrivilegedAction;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
    41
import java.util.ArrayList;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
    42
import java.util.Arrays;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
    43
import java.util.Collection;
25237
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
    44
import java.util.Collections;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
    45
import java.util.HashSet;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
    46
import java.util.List;
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    47
import java.util.concurrent.atomic.LongAdder;
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
    48
import jdk.dynalink.CallSiteDescriptor;
36686
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
    49
import jdk.dynalink.SecureLookupSupplier;
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
    50
import jdk.dynalink.linker.GuardedInvocation;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
    51
import jdk.dynalink.linker.LinkRequest;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33888
diff changeset
    52
import jdk.dynalink.linker.support.Guards;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
    53
import jdk.nashorn.internal.codegen.ApplySpecialization;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
    54
import jdk.nashorn.internal.codegen.Compiler;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
33888
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
    56
import jdk.nashorn.internal.ir.FunctionNode;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
    57
import jdk.nashorn.internal.objects.Global;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    58
import jdk.nashorn.internal.objects.NativeFunction;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
    59
import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    60
import jdk.nashorn.internal.runtime.linker.Bootstrap;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    61
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
    62
import jdk.nashorn.internal.runtime.logging.DebugLogger;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    64
/**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    65
 * Runtime representation of a JavaScript function. This class has only private
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    66
 * and protected constructors. There are no *public* constructors - but only
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    67
 * factory methods that follow the naming pattern "createXYZ".
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
 */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    69
public class ScriptFunction extends ScriptObject {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    71
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    72
     * Method handle for prototype getter for this ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    73
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    74
    public static final MethodHandle G$PROTOTYPE = findOwnMH_S("G$prototype", Object.class, Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    76
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    77
     * Method handle for prototype setter for this ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    78
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    79
    public static final MethodHandle S$PROTOTYPE = findOwnMH_S("S$prototype", void.class, Object.class, Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    81
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    82
     * Method handle for length getter for this ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    83
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    84
    public static final MethodHandle G$LENGTH = findOwnMH_S("G$length", int.class, Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    85
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    86
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    87
     * Method handle for name getter for this ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    88
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    89
    public static final MethodHandle G$NAME = findOwnMH_S("G$name", Object.class, Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    91
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    92
     * Method handle used for implementing sync() in mozilla_compat
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    93
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    94
    public static final MethodHandle INVOKE_SYNC = findOwnMH_S("invokeSync", Object.class, ScriptFunction.class, Object.class, Object.class, Object[].class);
20946
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
    95
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    96
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    97
     * Method handle for allocate function for this ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
    98
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    99
    static final MethodHandle ALLOCATE = findOwnMH_V("allocate", Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   101
    private static final MethodHandle WRAPFILTER = findOwnMH_S("wrapFilter", Object.class, Object.class);
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   102
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24729
diff changeset
   103
    private static final MethodHandle SCRIPTFUNCTION_GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class);
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   104
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   105
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   106
     * method handle to scope getter for this ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   107
     */
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
    public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   110
    private static final MethodHandle IS_FUNCTION_MH = findOwnMH_S("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   111
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   112
    private static final MethodHandle IS_APPLY_FUNCTION = findOwnMH_S("isApplyFunction", boolean.class, boolean.class, Object.class, Object.class);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
   113
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   114
    private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH_S("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   116
    private static final MethodHandle ADD_ZEROTH_ELEMENT = findOwnMH_S("addZerothElement", Object[].class, Object[].class, Object.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   117
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   118
    private static final MethodHandle WRAP_THIS = MH.findStatic(MethodHandles.lookup(), ScriptFunctionData.class, "wrapThis", MH.type(Object.class, Object.class));
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   119
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   120
    // various property maps used for different kinds of functions
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   121
    // property map for anonymous function that serves as Function.prototype
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   122
    private static final PropertyMap anonmap$;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   123
    // property map for strict mode functions
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   124
    private static final PropertyMap strictmodemap$;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   125
    // property map for bound functions
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   126
    private static final PropertyMap boundfunctionmap$;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   127
    // property map for non-strict, non-bound functions.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   128
    private static final PropertyMap map$;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   129
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   130
    // Marker object for lazily initialized prototype object
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   131
    private static final Object LAZY_PROTOTYPE = new Object();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   132
33341
cc9fa3638714 8139905: Add a convenience AccessControlContext factory
attila
parents: 33337
diff changeset
   133
    private static final AccessControlContext GET_LOOKUP_PERMISSION_CONTEXT =
36686
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
   134
            AccessControlContextFactory.createAccessControlContext(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
33341
cc9fa3638714 8139905: Add a convenience AccessControlContext factory
attila
parents: 33337
diff changeset
   135
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   136
    private static PropertyMap createStrictModeMap(final PropertyMap map) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   137
        final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   138
        PropertyMap newMap = map;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   139
        // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
49257
82f763a9cc22 8199443: Nashorn multithread bottleneck with "use strict"
hannesw
parents: 47216
diff changeset
   140
        newMap = newMap.addPropertyNoHistory(newMap.newUserAccessors("arguments", flags));
82f763a9cc22 8199443: Nashorn multithread bottleneck with "use strict"
hannesw
parents: 47216
diff changeset
   141
        newMap = newMap.addPropertyNoHistory(newMap.newUserAccessors("caller", flags));
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   142
        return newMap;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   143
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   144
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   145
    private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   146
        // Bound function map is same as strict function map, but additionally lacks the "prototype" property, see
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   147
        // ECMAScript 5.1 section 15.3.4.5
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   148
        return strictModeMap.deleteProperty(strictModeMap.findProperty("prototype"));
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   149
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   150
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   151
    static {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   152
        anonmap$ = PropertyMap.newMap();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   153
        final ArrayList<Property> properties = new ArrayList<>(3);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   154
        properties.add(AccessorProperty.create("prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE));
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   155
        properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null));
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   156
        properties.add(AccessorProperty.create("name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null));
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   157
        map$ = PropertyMap.newMap(properties);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   158
        strictmodemap$ = createStrictModeMap(map$);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   159
        boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   160
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   161
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   162
    private static boolean isStrict(final int flags) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   163
        return (flags & ScriptFunctionData.IS_STRICT) != 0;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   164
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   165
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   166
    // Choose the map based on strict mode!
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   167
    private static PropertyMap getMap(final boolean strict) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   168
        return strict ? strictmodemap$ : map$;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   169
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   170
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   171
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   172
     * The parent scope.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   173
     */
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   174
    private final ScriptObject scope;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   175
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
   176
    private final ScriptFunctionData data;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
   177
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   178
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   179
     * The property map used for newly allocated object when function is used as
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   180
     * constructor.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   181
     */
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
   182
    protected PropertyMap allocatorMap;
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
   183
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   185
     * Reference to constructor prototype.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   186
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   187
    protected Object prototype;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   188
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   189
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   190
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   191
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   192
     * @param data static function data
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   193
     * @param map property map
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   194
     * @param scope scope
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   195
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   196
    private ScriptFunction(
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   197
            final ScriptFunctionData data,
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   198
            final PropertyMap map,
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   199
            final ScriptObject scope,
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   200
            final Global global) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   201
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   202
        super(map);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   203
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   204
        if (Context.DEBUG) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   205
            constructorCount.increment();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   206
        }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   207
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   208
        this.data = data;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   209
        this.scope = scope;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   210
        this.setInitialProto(global.getFunctionPrototype());
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   211
        this.prototype = LAZY_PROTOTYPE;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   212
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   213
        // We have to fill user accessor functions late as these are stored
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   214
        // in this object rather than in the PropertyMap of this object.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   215
        assert objectSpill == null;
32533
47d3ca23ac91 8135332: ScriptFunction constructor should use is bound and is strict check rather than checking for 'arguments' and 'caller'
sundar
parents: 32527
diff changeset
   216
        if (isStrict() || isBoundFunction()) {
47d3ca23ac91 8135332: ScriptFunction constructor should use is bound and is strict check rather than checking for 'arguments' and 'caller'
sundar
parents: 32527
diff changeset
   217
            final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
49257
82f763a9cc22 8199443: Nashorn multithread bottleneck with "use strict"
hannesw
parents: 47216
diff changeset
   218
            initUserAccessors("arguments", typeErrorThrower, typeErrorThrower);
82f763a9cc22 8199443: Nashorn multithread bottleneck with "use strict"
hannesw
parents: 47216
diff changeset
   219
            initUserAccessors("caller", typeErrorThrower, typeErrorThrower);
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   220
        }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   221
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   222
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   223
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   224
     * Constructor
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   225
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   226
     * @param name function name
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   227
     * @param methodHandle method handle to function (if specializations are
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   228
     * present, assumed to be most generic)
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   229
     * @param map property map
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   230
     * @param scope scope
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   231
     * @param specs specialized version of this function - other method handles
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   232
     * @param flags {@link ScriptFunctionData} flags
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   233
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   234
    private ScriptFunction(
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
            final String name,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   236
            final MethodHandle methodHandle,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
            final PropertyMap map,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
            final ScriptObject scope,
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   239
            final Specialization[] specs,
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   240
            final int flags,
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   241
            final Global global) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   242
        this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope, global);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   243
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   244
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   245
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   246
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   247
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   248
     * @param name name of function
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   249
     * @param methodHandle handle for invocation
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   250
     * @param scope scope object
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   251
     * @param specs specialized versions of this method, if available, null
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   252
     * otherwise
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   253
     * @param flags {@link ScriptFunctionData} flags
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   254
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   255
    private ScriptFunction(
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   256
            final String name,
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   257
            final MethodHandle methodHandle,
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   258
            final ScriptObject scope,
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   259
            final Specialization[] specs,
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   260
            final int flags) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   261
        this(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags, Global.instance());
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   262
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   263
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   264
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   265
     * Constructor called by Nasgen generated code, zero added members, use the
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   266
     * default map. Creates builtin functions only.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   267
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   268
     * @param name name of function
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   269
     * @param invokeHandle handle for invocation
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   270
     * @param specs specialized versions of this method, if available, null
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   271
     * otherwise
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   272
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   273
    protected ScriptFunction(final String name, final MethodHandle invokeHandle, final Specialization[] specs) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   274
        this(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR, Global.instance());
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   275
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   276
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   277
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   278
     * Constructor called by Nasgen generated code, non zero member count, use
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   279
     * the map passed as argument. Creates builtin functions only.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   280
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   281
     * @param name name of function
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   282
     * @param invokeHandle handle for invocation
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   283
     * @param map initial property map
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   284
     * @param specs specialized versions of this method, if available, null
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   285
     * otherwise
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   286
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   287
    protected ScriptFunction(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   288
        this(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR, Global.instance());
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   289
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   290
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   291
    // Factory methods to create various functions
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   292
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   293
     * Factory method called by compiler generated code for functions that need
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   294
     * parent scope.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   295
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   296
     * @param constants the generated class' constant array
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   297
     * @param index the index of the {@code RecompilableScriptFunctionData}
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   298
     * object in the constants array.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   299
     * @param scope the parent scope object
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   300
     * @return a newly created function object
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   302
    public static ScriptFunction create(final Object[] constants, final int index, final ScriptObject scope) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   303
        final RecompilableScriptFunctionData data = (RecompilableScriptFunctionData) constants[index];
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   304
        return new ScriptFunction(data, getMap(data.isStrict()), scope, Global.instance());
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   305
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   306
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   307
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   308
     * Factory method called by compiler generated code for functions that don't
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   309
     * need parent scope.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   310
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   311
     * @param constants the generated class' constant array
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   312
     * @param index the index of the {@code RecompilableScriptFunctionData}
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   313
     * object in the constants array.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   314
     * @return a newly created function object
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   315
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   316
    public static ScriptFunction create(final Object[] constants, final int index) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   317
        return create(constants, index, null);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   318
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   319
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   320
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   321
     * Create anonymous function that serves as Function.prototype
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   322
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   323
     * @return anonymous function object
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   324
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   325
    public static ScriptFunction createAnonymous() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   326
        return new ScriptFunction("", GlobalFunctions.ANONYMOUS, anonmap$, null);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   327
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   328
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   329
    // builtin function create helper factory
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   330
    private static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle, final Specialization[] specs, final int flags) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   331
        final ScriptFunction func = new ScriptFunction(name, methodHandle, null, specs, flags);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   332
        func.setPrototype(UNDEFINED);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   333
        // Non-constructor built-in functions do not have "prototype" property
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   334
        func.deleteOwnProperty(func.getMap().findProperty("prototype"));
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   335
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   336
        return func;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   337
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   338
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   339
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   340
     * Factory method for non-constructor built-in functions
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   341
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   342
     * @param name function name
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   343
     * @param methodHandle handle for invocation
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   344
     * @param specs specialized versions of function if available, null
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   345
     * otherwise
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   346
     * @return new ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   347
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   348
    public static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle, final Specialization[] specs) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   349
        return ScriptFunction.createBuiltin(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   350
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   351
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   352
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   353
     * Factory method for non-constructor built-in functions
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   354
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   355
     * @param name function name
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   356
     * @param methodHandle handle for invocation
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   357
     * @return new ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   358
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   359
    public static ScriptFunction createBuiltin(final String name, final MethodHandle methodHandle) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   360
        return ScriptFunction.createBuiltin(name, methodHandle, null);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   361
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   362
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   363
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   364
     * Factory method for non-constructor built-in, strict functions
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   365
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   366
     * @param name function name
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   367
     * @param methodHandle handle for invocation
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   368
     * @return new ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   369
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   370
    public static ScriptFunction createStrictBuiltin(final String name, final MethodHandle methodHandle) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   371
        return ScriptFunction.createBuiltin(name, methodHandle, null, ScriptFunctionData.IS_BUILTIN | ScriptFunctionData.IS_STRICT);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   372
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   373
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   374
    // Subclass to represent bound functions
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   375
    private static class Bound extends ScriptFunction {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   376
        private final ScriptFunction target;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   377
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   378
        Bound(final ScriptFunctionData boundData, final ScriptFunction target) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   379
            super(boundData, boundfunctionmap$, null, Global.instance());
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   380
            setPrototype(ScriptRuntime.UNDEFINED);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   381
            this.target = target;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   382
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   383
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   384
        @Override
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   385
        protected ScriptFunction getTargetFunction() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   386
            return target;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   387
        }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   388
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   389
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   390
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   391
     * Creates a version of this function bound to a specific "self" and other
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   392
     * arguments, as per {@code Function.prototype.bind} functionality in
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   393
     * ECMAScript 5.1 section 15.3.4.5.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   394
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   395
     * @param self the self to bind to this function. Can be null (in which
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   396
     * case, null is bound as this).
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   397
     * @param args additional arguments to bind to this function. Can be null or
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   398
     * empty to not bind additional arguments.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   399
     * @return a function with the specified self and parameters bound.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   400
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   401
    public final ScriptFunction createBound(final Object self, final Object[] args) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   402
        return new Bound(data.makeBoundFunctionData(this, self, args), getTargetFunction());
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   403
    }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   404
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   405
    /**
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   406
     * Create a function that invokes this function synchronized on {@code sync}
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   407
     * or the self object of the invocation.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   408
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   409
     * @param sync the Object to synchronize on, or undefined
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   410
     * @return synchronized function
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   411
     */
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   412
    public final ScriptFunction createSynchronized(final Object sync) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   413
        final MethodHandle mh = MH.insertArguments(ScriptFunction.INVOKE_SYNC, 0, this, sync);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   414
        return createBuiltin(getName(), mh);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   417
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
    public String getClassName() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
        return "Function";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   422
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   423
     * ECMA 15.3.5.3 [[HasInstance]] (V) Step 3 if "prototype" value is not an
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   424
     * Object, throw TypeError
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
    public boolean isInstance(final ScriptObject instance) {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   428
        final Object basePrototype = getTargetFunction().getPrototype();
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   429
        if (!(basePrototype instanceof ScriptObject)) {
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16234
diff changeset
   430
            throw typeError("prototype.not.an.object", ScriptRuntime.safeToString(getTargetFunction()), ScriptRuntime.safeToString(basePrototype));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   433
        for (ScriptObject proto = instance.getProto(); proto != null; proto = proto.getProto()) {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   434
            if (proto == basePrototype) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   435
                return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   436
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   437
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   439
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   440
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   441
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   442
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   443
     * Returns the target function for this function. If the function was not
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   444
     * created using {@link #createBound(Object, Object[])}, its target
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   445
     * function is itself. If it is bound, its target function is the target
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   446
     * function of the function it was made from (therefore, the target function
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   447
     * is always the final, unbound recipient of the calls).
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   448
     *
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   449
     * @return the target function for this function.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
     */
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   451
    protected ScriptFunction getTargetFunction() {
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   452
        return this;
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   453
    }
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   454
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   455
    final boolean isBoundFunction() {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   456
        return getTargetFunction() != this;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   460
     * Set the arity of this ScriptFunction
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   461
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
     * @param arity arity
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   463
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   464
    public final void setArity(final int arity) {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   465
        data.setArity(arity);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   466
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   467
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   468
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   469
     * Is this a ECMAScript 'use strict' function?
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   470
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
     * @return true if function is in strict mode
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   472
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   473
    public final boolean isStrict() {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   474
        return data.isStrict();
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   475
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
    /**
33888
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   478
     * Is this is a function with all variables in scope?
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   479
     * @return true if function has all
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   480
     */
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   481
    public boolean hasAllVarsInScope() {
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   482
        return data instanceof RecompilableScriptFunctionData &&
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   483
                (((RecompilableScriptFunctionData) data).getFunctionFlags() & FunctionNode.HAS_ALL_VARS_IN_SCOPE) != 0;
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   484
    }
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   485
0c7b0ab328e0 8131929: Add option for debuggable scopes
hannesw
parents: 33343
diff changeset
   486
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   487
     * Returns true if this is a non-strict, non-built-in function that requires
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   488
     * non-primitive this argument according to ECMA 10.4.3.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   489
     *
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   490
     * @return true if this argument must be an object
16186
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16173
diff changeset
   491
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   492
    public final boolean needsWrappedThis() {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   493
        return data.needsWrappedThis();
16186
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16173
diff changeset
   494
    }
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16173
diff changeset
   495
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: 24721
diff changeset
   496
    private static boolean needsWrappedThis(final Object fn) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   497
        return fn instanceof ScriptFunction ? ((ScriptFunction) fn).needsWrappedThis() : false;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   498
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   499
16186
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16173
diff changeset
   500
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   501
     * Execute this script function.
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   502
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   503
     * @param self Target object.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   504
     * @param arguments Call arguments.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   505
     * @return ScriptFunction result.
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   506
     * @throws Throwable if there is an exception/error with the invocation or
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   507
     * thrown from it
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   508
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   509
    final Object invoke(final Object self, final Object... arguments) throws Throwable {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   510
        if (Context.DEBUG) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   511
            invokes.increment();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   512
        }
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   513
        return data.invoke(this, self, arguments);
16147
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
    /**
18614
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   517
     * Execute this script function as a constructor.
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   518
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   519
     * @param arguments Call arguments.
18614
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   520
     * @return Newly constructed result.
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   521
     * @throws Throwable if there is an exception/error with the invocation or
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   522
     * thrown from it
18614
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   523
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   524
    final Object construct(final Object... arguments) throws Throwable {
18614
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   525
        return data.construct(this, arguments);
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   526
    }
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   527
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   528
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   529
     * Allocate function. Called from generated {@link ScriptObject} code for
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   530
     * allocation as a factory method
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   531
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   532
     * @return a new instance of the {@link ScriptObject} whose allocator this
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   533
     * is
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
     */
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   535
    @SuppressWarnings("unused")
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   536
    private Object allocate() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   537
        if (Context.DEBUG) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   538
            allocations.increment();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
        }
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24720
diff changeset
   540
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   541
        assert !isBoundFunction(); // allocate never invoked on bound functions
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   542
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   543
        final ScriptObject prototype = getAllocatorPrototype();
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   544
        final ScriptObject object = data.allocate(getAllocatorMap(prototype));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
        if (object != null) {
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   547
            object.setInitialProto(prototype);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   548
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   549
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   550
        return object;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   551
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   552
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   553
    /**
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   554
     * Get the property map used by "allocate"
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   555
     * @param prototype actual prototype object
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   556
     * @return property map
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   557
     */
35406
b49d0656c449 8148214: Slow object allocation due to multiple synchronization
hannesw
parents: 34844
diff changeset
   558
    private PropertyMap getAllocatorMap(final ScriptObject prototype) {
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   559
        if (allocatorMap == null || allocatorMap.isInvalidSharedMapFor(prototype)) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   560
            // The prototype map has changed since this function was last used as constructor.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   561
            // Get a new allocator map.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   562
            allocatorMap = data.getAllocatorMap(prototype);
29411
79e9da5fffbc 8074693: Different instances of same function use same allocator map
hannesw
parents: 27525
diff changeset
   563
        }
79e9da5fffbc 8074693: Different instances of same function use same allocator map
hannesw
parents: 27525
diff changeset
   564
        return allocatorMap;
79e9da5fffbc 8074693: Different instances of same function use same allocator map
hannesw
parents: 27525
diff changeset
   565
    }
79e9da5fffbc 8074693: Different instances of same function use same allocator map
hannesw
parents: 27525
diff changeset
   566
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
    /**
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   568
     * Return the actual prototype used by "allocate"
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   569
     * @return allocator prototype
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   570
     */
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   571
    private ScriptObject getAllocatorPrototype() {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   572
        final Object prototype = getPrototype();
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   573
        if (prototype instanceof ScriptObject) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   574
            return (ScriptObject) prototype;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   575
        }
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   576
        return Global.objectPrototype();
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   577
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   578
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   579
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   580
    public final String safeToString() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   581
        return toSource();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   582
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   583
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   584
    @Override
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   585
    public final String toString() {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   586
        return data.toString();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   587
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   588
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   589
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   590
     * Get this function as a String containing its source code. If no source
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   591
     * code exists in this ScriptFunction, its contents will be displayed as
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   592
     * {@code [native code]}
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   593
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
     * @return string representation of this function's source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
    public final String toSource() {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   597
        return data.toSource();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   599
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
     * Get the prototype object for this function
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   602
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   603
     * @return prototype
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   604
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   605
    public final Object getPrototype() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   606
        if (prototype == LAZY_PROTOTYPE) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   607
            prototype = new PrototypeObject(this);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   608
        }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   609
        return prototype;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   610
    }
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
     * Set the prototype object for this function
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   614
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   615
     * @param newPrototype new prototype object
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   616
     */
36023
528cc67f1289 8147558: Add support for ES6 collections
hannesw
parents: 35407
diff changeset
   617
    public final void setPrototype(final Object newPrototype) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   618
        if (newPrototype instanceof ScriptObject && newPrototype != this.prototype && allocatorMap != null) {
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   619
            // Unset allocator map to be replaced with one matching the new prototype.
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32692
diff changeset
   620
            allocatorMap = null;
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   621
        }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   622
        this.prototype = newPrototype;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   623
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   624
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   625
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   626
     * Return the invoke handle bound to a given ScriptObject self reference. If
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   627
     * callee parameter is required result is rebound to this.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   628
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   629
     * @param self self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   630
     * @return bound invoke handle
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   631
     */
20932
323bdf36c328 8026162: "this" in SAM adapter functions is wrong
sundar
parents: 19472
diff changeset
   632
    public final MethodHandle getBoundInvokeHandle(final Object self) {
24729
2b13051f2122 8037534: Use scope types to determine optimistic types
attila
parents: 24727
diff changeset
   633
        return MH.bindTo(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), self);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   634
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   635
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   636
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   637
     * Bind the method handle to this {@code ScriptFunction} instance if it
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   638
     * needs a callee parameter. If this function's method handles don't have a
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   639
     * callee parameter, the handle is returned unchanged.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   640
     *
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   641
     * @param methodHandle the method handle to potentially bind to this
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   642
     * function instance.
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   643
     * @return the potentially bound method handle
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   644
     */
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   645
    private MethodHandle bindToCalleeIfNeeded(final MethodHandle methodHandle) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
   646
        return ScriptFunctionData.needsCallee(methodHandle) ? MH.bindTo(methodHandle, this) : methodHandle;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
   647
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   648
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   649
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   650
    /**
34735
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   651
     * Get the documentation for this function
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   652
     *
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   653
     * @return the documentation
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   654
     */
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   655
    public final String getDocumentation() {
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   656
        return data.getDocumentation();
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   657
    }
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   658
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   659
    /**
34844
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   660
     * Get the documentation key for this function
34735
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   661
     *
34844
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   662
     * @return the documentation key
34735
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   663
     */
34844
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   664
    public final String getDocumentationKey() {
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   665
        return data.getDocumentationKey();
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   666
    }
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   667
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   668
    /**
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   669
     * Set the documentation key for this function
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   670
     *
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   671
     * @param docKey documentation key String for this function
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   672
     */
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   673
    public final void setDocumentationKey(final String docKey) {
31c026e00569 8146251: Avoid annotation to specify documentation for JS builtin functions
sundar
parents: 34738
diff changeset
   674
        data.setDocumentationKey(docKey);
34735
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   675
    }
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   676
0f41d334aa24 8145486: jjs should support documentation key shortcut in interactive mode
sundar
parents: 34447
diff changeset
   677
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   678
     * Get the name for this function
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   679
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   680
     * @return the name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   681
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   682
    public final String getName() {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   683
        return data.getName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   684
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   685
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   686
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   687
     * Get the scope for this function
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   688
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   689
     * @return the scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   690
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   691
    public final ScriptObject getScope() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   692
        return scope;
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
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   696
     * Prototype getter for this ScriptFunction - follows the naming convention
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
     * used by Nasgen and the code generator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   699
     * @param self self reference
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   700
     * @return self's prototype
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   701
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   702
    public static Object G$prototype(final Object self) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   703
        return self instanceof ScriptFunction
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   704
                ? ((ScriptFunction) self).getPrototype()
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   705
                : UNDEFINED;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   706
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   707
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   708
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   709
     * Prototype setter for this ScriptFunction - follows the naming convention
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   710
     * used by Nasgen and the code generator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   711
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   712
     * @param self self reference
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
     * @param prototype prototype to set
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   714
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   715
    public static void S$prototype(final Object self, final Object prototype) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   716
        if (self instanceof ScriptFunction) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   717
            ((ScriptFunction) self).setPrototype(prototype);
16147
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
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
     * Length getter - ECMA 15.3.3.2: Function.length
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   723
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   724
     * @param self self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   725
     * @return length
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   727
    public static int G$length(final Object self) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   728
        if (self instanceof ScriptFunction) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   729
            return ((ScriptFunction) self).data.getArity();
16147
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
        return 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   733
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   735
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   736
     * Name getter - ECMA Function.name
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   737
     *
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
   738
     * @param self self reference
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   739
     * @return the name, or undefined if none
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   740
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   741
    public static Object G$name(final Object self) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   742
        if (self instanceof ScriptFunction) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   743
            return ((ScriptFunction) self).getName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   744
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   745
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   746
        return UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   747
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   748
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   749
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   750
     * Get the prototype for this ScriptFunction
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   751
     *
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   752
     * @param constructor constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   753
     * @return prototype, or null if given constructor is not a ScriptFunction
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   754
     */
26056
a64f0cd60e66 8054651: Global.initConstructor and ScriptFunction.getPrototype(Object) can have stricter types
sundar
parents: 26053
diff changeset
   755
    public static ScriptObject getPrototype(final ScriptFunction constructor) {
a64f0cd60e66 8054651: Global.initConstructor and ScriptFunction.getPrototype(Object) can have stricter types
sundar
parents: 26053
diff changeset
   756
        if (constructor != null) {
a64f0cd60e66 8054651: Global.initConstructor and ScriptFunction.getPrototype(Object) can have stricter types
sundar
parents: 26053
diff changeset
   757
            final Object proto = constructor.getPrototype();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   758
            if (proto instanceof ScriptObject) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   759
                return (ScriptObject) proto;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   760
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   761
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   762
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   763
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   764
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   765
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   766
    // These counters are updated only in debug mode.
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   767
    private static LongAdder constructorCount;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   768
    private static LongAdder invokes;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   769
    private static LongAdder allocations;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   770
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   771
    static {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   772
        if (Context.DEBUG) {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   773
            constructorCount = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   774
            invokes = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   775
            allocations = new LongAdder();
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   776
        }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   777
    }
16147
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
     * @return the constructorCount
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   781
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   782
    public static long getConstructorCount() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   783
        return constructorCount.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   784
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   785
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   786
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   787
     * @return the invokes
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   788
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   789
    public static long getInvokes() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   790
        return invokes.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   791
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   792
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   793
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   794
     * @return the allocations
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   795
     */
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   796
    public static long getAllocations() {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   797
        return allocations.longValue();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   798
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   799
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   800
    @Override
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   801
    protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   802
        final MethodType type = desc.getMethodType();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   803
        assert desc.getMethodType().returnType() == Object.class && !NashornCallSiteDescriptor.isOptimistic(desc);
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   804
        final CompiledFunction cf = data.getBestConstructor(type, scope, CompiledFunction.NO_FUNCTIONS);
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25237
diff changeset
   805
        final GuardedInvocation bestCtorInv = cf.createConstructorInvocation();
24720
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   806
        //TODO - ClassCastException
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   807
        return new GuardedInvocation(pairArguments(bestCtorInv.getInvocation(), type), getFunctionGuard(this, cf.getFlags()), bestCtorInv.getSwitchPoints(), null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   808
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   809
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   810
    private static Object wrapFilter(final Object obj) {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   811
        if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   812
            return obj;
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   813
        }
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23372
diff changeset
   814
        return Context.getGlobal().wrapAsObject(obj);
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   815
    }
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   816
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   817
    @SuppressWarnings("unused")
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   818
    private static Object globalFilter(final Object object) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   819
        // replace whatever we get with the current global object
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23372
diff changeset
   820
        return Context.getGlobal();
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   821
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   822
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   823
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   824
     * Some receivers are primitive, in that case, according to the Spec we
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   825
     * create a new native object per callsite with the wrap filter. We can only
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   826
     * apply optimistic builtins if there is no per instance state saved for
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   827
     * these wrapped objects (e.g. currently NativeStrings), otherwise we can't
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   828
     * create optimistic versions
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   829
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   830
     * @param self receiver
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   831
     * @param linkLogicClass linkLogicClass, or null if no link logic exists
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   832
     * @return link logic instance, or null if one could not be constructed for
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   833
     * this receiver
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   834
     */
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
   835
    private static LinkLogic getLinkLogic(final Object self, final Class<? extends LinkLogic> linkLogicClass) {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   836
        if (linkLogicClass == null) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   837
            return LinkLogic.EMPTY_INSTANCE; //always OK to link this, specialization but without special linking logic
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   838
        }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   839
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   840
        if (!Context.getContextTrusted().getEnv()._optimistic_types) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   841
            return null; //if optimistic types are off, optimistic builtins are too
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   842
        }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   843
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   844
        final Object wrappedSelf = wrapFilter(self);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   845
        if (wrappedSelf instanceof OptimisticBuiltins) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   846
            if (wrappedSelf != self && ((OptimisticBuiltins) wrappedSelf).hasPerInstanceAssumptions()) {
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   847
                return null; //pessimistic - we created a wrapped object different from the primitive, but the assumptions have instance state
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   848
            }
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   849
            return ((OptimisticBuiltins) wrappedSelf).getLinkLogic(linkLogicClass);
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   850
        }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   851
        return null;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   852
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   853
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   854
    /**
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33342
diff changeset
   855
     * StandardOperation.CALL call site signature: (callee, thiz, [args...]) generated method
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   856
     * signature: (callee, thiz, [args...])
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   857
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   858
     * cases:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   859
     * (a) method has callee parameter
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   860
     *     (1) for local/scope calls, we just bind thiz and drop the second argument.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   861
     *     (2) for normal this-calls, we have to swap thiz and callee to get matching signatures.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   862
     * (b) method doesn't have callee parameter (builtin functions)
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   863
     *     (3) for local/scope calls, bind thiz and drop both callee and thiz.
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   864
     *     (4) for normal this-calls, drop callee.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   865
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   866
     * @return guarded invocation for call
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   867
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   868
    @Override
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16188
diff changeset
   869
    protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   870
        final MethodType type = desc.getMethodType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   871
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   872
        final String name = getName();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   873
        final boolean isUnstable = request.isCallSiteUnstable();
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   874
        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   875
        final boolean isCall = !scopeCall && data.isBuiltin() && "call".equals(name);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   876
        final boolean isApply = !scopeCall && data.isBuiltin() && "apply".equals(name);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   877
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24753
diff changeset
   878
        final boolean isApplyOrCall = isCall | isApply;
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24753
diff changeset
   879
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24753
diff changeset
   880
        if (isUnstable && !isApplyOrCall) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   881
            //megamorphic - replace call with apply
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   882
            final MethodHandle handle;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   883
            //ensure that the callsite is vararg so apply can consume it
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   884
            if (type.parameterCount() == 3 && type.parameterType(2) == Object[].class) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   885
                // Vararg call site
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   886
                handle = ScriptRuntime.APPLY.methodHandle();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   887
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   888
                // (callee, this, args...) => (callee, this, args[])
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   889
                handle = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   890
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   891
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   892
            // If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   893
            // generic "is this a ScriptFunction?" guard.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   894
            return new GuardedInvocation(
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   895
                    handle,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   896
                    null,
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
   897
                    (SwitchPoint) null,
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   898
                    ClassCastException.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   900
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   901
        MethodHandle boundHandle;
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   902
        MethodHandle guard = null;
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   903
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   904
        // Special handling of Function.apply and Function.call. Note we must be invoking
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24753
diff changeset
   905
        if (isApplyOrCall && !isUnstable) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   906
            final Object[] args = request.getArguments();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   907
            if (Bootstrap.isCallable(args[1])) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   908
                return createApplyOrCallCall(isApply, desc, request, args);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   909
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   910
        } //else just fall through and link as ordinary function or unstable apply
19456
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   911
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   912
        int programPoint = INVALID_PROGRAM_POINT;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   913
        if (NashornCallSiteDescriptor.isOptimistic(desc)) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   914
            programPoint = NashornCallSiteDescriptor.getProgramPoint(desc);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   915
        }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   916
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   917
        CompiledFunction cf = data.getBestInvoker(type, scope, CompiledFunction.NO_FUNCTIONS);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   918
        final Object self = request.getArguments()[1];
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   919
        final Collection<CompiledFunction> forbidden = new HashSet<>();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   920
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   921
        //check for special fast versions of the compiled function
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   922
        final List<SwitchPoint> sps = new ArrayList<>();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   923
        Class<? extends Throwable> exceptionGuard = null;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   924
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   925
        while (cf.isSpecialization()) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   926
            final Class<? extends LinkLogic> linkLogicClass = cf.getLinkLogicClass();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   927
            //if linklogic is null, we can always link with the standard mechanism, it's still a specialization
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   928
            final LinkLogic linkLogic = getLinkLogic(self, linkLogicClass);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   929
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   930
            if (linkLogic != null && linkLogic.checkLinkable(self, desc, request)) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   931
                final DebugLogger log = Context.getContextTrusted().getLogger(Compiler.class);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   932
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   933
                if (log.isEnabled()) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   934
                    log.info("Linking optimistic builtin function: '", name, "' args=", Arrays.toString(request.getArguments()), " desc=", desc);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   935
                }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   936
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   937
                exceptionGuard = linkLogic.getRelinkException();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   938
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   939
                break;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   940
            }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   941
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   942
            //could not link this specialization because link check failed
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   943
            forbidden.add(cf);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   944
            final CompiledFunction oldCf = cf;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   945
            cf = data.getBestInvoker(type, scope, forbidden);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   946
            assert oldCf != cf;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   947
        }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   948
26053
8137f95db5e8 8046026: CompiledFunction.relinkComposableInvoker assert is being hit
attila
parents: 25237
diff changeset
   949
        final GuardedInvocation bestInvoker = cf.createFunctionInvocation(type.returnType(), programPoint);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   950
        final MethodHandle callHandle = bestInvoker.getInvocation();
24727
attila
parents: 24725 23375
diff changeset
   951
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   952
        if (data.needsCallee()) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   953
            if (scopeCall && needsWrappedThis()) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   954
                // (callee, this, args...) => (callee, [this], args...)
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24729
diff changeset
   955
                boundHandle = MH.filterArguments(callHandle, 1, SCRIPTFUNCTION_GLOBALFILTER);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   956
            } else {
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   957
                // It's already (callee, this, args...), just what we need
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   958
                boundHandle = callHandle;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   959
            }
36686
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
   960
        } else if (data.isBuiltin() && Global.isBuiltInJavaExtend(this)) {
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
   961
            // We're binding the current lookup as "self" so the function can do
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
   962
            // security-sensitive creation of adapter classes.
33331
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 32695
diff changeset
   963
            boundHandle = MH.dropArguments(MH.bindTo(callHandle, getLookupPrivileged(desc)), 0, type.parameterType(0), type.parameterType(1));
36686
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
   964
        } else if (data.isBuiltin() && Global.isBuiltInJavaTo(this)) {
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
   965
            // We're binding the current call site descriptor as "self" so the function can do
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
   966
            // security-sensitive creation of adapter classes.
a351eacd4c42 8150218: Autoconversion SAM adapters sometimes don't get privileges
attila
parents: 36023
diff changeset
   967
            boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc), 0, type.parameterType(0), type.parameterType(1));
24727
attila
parents: 24725 23375
diff changeset
   968
        } else if (scopeCall && needsWrappedThis()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   969
            // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
24727
attila
parents: 24725 23375
diff changeset
   970
            // (this, args...) => ([this], args...)
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24729
diff changeset
   971
            boundHandle = MH.filterArguments(callHandle, 0, SCRIPTFUNCTION_GLOBALFILTER);
24727
attila
parents: 24725 23375
diff changeset
   972
            // ([this], args...) => ([callee], [this], args...)
attila
parents: 24725 23375
diff changeset
   973
            boundHandle = MH.dropArguments(boundHandle, 0, type.parameterType(0));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   974
        } else {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   975
            // (this, args...) => ([callee], this, args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   976
            boundHandle = MH.dropArguments(callHandle, 0, type.parameterType(0));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   977
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   978
19456
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   979
        // For non-strict functions, check whether this-object is primitive type.
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   980
        // If so add a to-object-wrapper argument filter.
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   981
        // Else install a guard that will trigger a relink when the argument becomes primitive.
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   982
        if (!scopeCall && needsWrappedThis()) {
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   983
            if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) {
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   984
                boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER);
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   985
            } else {
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   986
                guard = getNonStrictFunctionGuard(this);
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   987
            }
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   988
        }
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   989
34738
6a2c8f68a2c2 8145669: apply2call optimized callsite fails after becoming megamorphic
sundar
parents: 34735
diff changeset
   990
        // Is this an unstable callsite which was earlier apply-to-call optimized?
6a2c8f68a2c2 8145669: apply2call optimized callsite fails after becoming megamorphic
sundar
parents: 34735
diff changeset
   991
        // If so, earlier apply2call would have exploded arguments. We have to convert
6a2c8f68a2c2 8145669: apply2call optimized callsite fails after becoming megamorphic
sundar
parents: 34735
diff changeset
   992
        // that as an array again!
6a2c8f68a2c2 8145669: apply2call optimized callsite fails after becoming megamorphic
sundar
parents: 34735
diff changeset
   993
        if (isUnstable && NashornCallSiteDescriptor.isApplyToCall(desc)) {
6a2c8f68a2c2 8145669: apply2call optimized callsite fails after becoming megamorphic
sundar
parents: 34735
diff changeset
   994
            boundHandle = MH.asCollector(boundHandle, Object[].class, type.parameterCount() - 2);
6a2c8f68a2c2 8145669: apply2call optimized callsite fails after becoming megamorphic
sundar
parents: 34735
diff changeset
   995
        }
6a2c8f68a2c2 8145669: apply2call optimized callsite fails after becoming megamorphic
sundar
parents: 34735
diff changeset
   996
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   997
        boundHandle = pairArguments(boundHandle, type);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
   998
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
   999
        if (bestInvoker.getSwitchPoints() != null) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1000
            sps.addAll(Arrays.asList(bestInvoker.getSwitchPoints()));
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1001
        }
35407
204abe4d8cbc 8147591: Revisit Collection.toArray(new T[size]) calls in nashorn and dynalink code
mhaupt
parents: 35406
diff changeset
  1002
        final SwitchPoint[] spsArray = sps.isEmpty() ? null : sps.toArray(new SwitchPoint[0]);
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1003
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1004
        return new GuardedInvocation(
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1005
                boundHandle,
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1006
                guard == null ?
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1007
                        getFunctionGuard(
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1008
                                this,
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1009
                                cf.getFlags()) :
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1010
                        guard,
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1011
                spsArray,
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1012
                exceptionGuard);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1013
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1014
33331
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 32695
diff changeset
  1015
    private static Lookup getLookupPrivileged(final CallSiteDescriptor desc) {
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 32695
diff changeset
  1016
        // NOTE: we'd rather not make NashornCallSiteDescriptor.getLookupPrivileged public.
33341
cc9fa3638714 8139905: Add a convenience AccessControlContext factory
attila
parents: 33337
diff changeset
  1017
        return AccessController.doPrivileged((PrivilegedAction<Lookup>)()->desc.getLookup(),
cc9fa3638714 8139905: Add a convenience AccessControlContext factory
attila
parents: 33337
diff changeset
  1018
                GET_LOOKUP_PERMISSION_CONTEXT);
33331
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 32695
diff changeset
  1019
    }
273e6a10de22 8139435: Make sure CallSiteDescriptor.getLookup is subject to a security check
attila
parents: 32695
diff changeset
  1020
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1021
    private GuardedInvocation createApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc, final LinkRequest request, final Object[] args) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1022
        final MethodType descType = desc.getMethodType();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1023
        final int paramCount = descType.parameterCount();
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1024
        if (descType.parameterType(paramCount - 1).isArray()) {
25237
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1025
            // This is vararg invocation of apply or call. This can normally only happen when we do a recursive
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1026
            // invocation of createApplyOrCallCall (because we're doing apply-of-apply). In this case, create delegate
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1027
            // linkage by unpacking the vararg invocation and use pairArguments to introduce the necessary spreader.
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1028
            return createVarArgApplyOrCallCall(isApply, desc, request, args);
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1029
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1030
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1031
        final boolean passesThis = paramCount > 2;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1032
        final boolean passesArgs = paramCount > 3;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1033
        final int realArgCount = passesArgs ? paramCount - 3 : 0;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1034
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1035
        final Object appliedFn = args[1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1036
        final boolean appliedFnNeedsWrappedThis = needsWrappedThis(appliedFn);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1037
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1038
        //box call back to apply
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1039
        CallSiteDescriptor appliedDesc = desc;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1040
        final SwitchPoint applyToCallSwitchPoint = Global.getBuiltinFunctionApplySwitchPoint();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1041
        //enough to change the proto switchPoint here
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1042
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1043
        final boolean isApplyToCall = NashornCallSiteDescriptor.isApplyToCall(desc);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1044
        final boolean isFailedApplyToCall = isApplyToCall && applyToCallSwitchPoint.hasBeenInvalidated();
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1045
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1046
        // R(apply|call, ...) => R(...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1047
        MethodType appliedType = descType.dropParameterTypes(0, 1);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1048
        if (!passesThis) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1049
            // R() => R(this)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1050
            appliedType = appliedType.insertParameterTypes(1, Object.class);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1051
        } else if (appliedFnNeedsWrappedThis) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1052
            appliedType = appliedType.changeParameterType(1, Object.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1053
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1054
26375
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1055
        /*
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1056
         * dropArgs is a synthetic method handle that contains any args that we need to
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1057
         * get rid of that come after the arguments array in the apply case. We adapt
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1058
         * the callsite to ask for 3 args only and then dropArguments on the method handle
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1059
         * to make it fit the extraneous args.
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1060
         */
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1061
        MethodType dropArgs = MH.type(void.class);
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1062
        if (isApply && !isFailedApplyToCall) {
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1063
            final int pc = appliedType.parameterCount();
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1064
            for (int i = 3; i < pc; i++) {
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1065
                dropArgs = dropArgs.appendParameterTypes(appliedType.parameterType(i));
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1066
            }
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1067
            if (pc > 3) {
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1068
                appliedType = appliedType.dropParameterTypes(3, pc);
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1069
            }
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1070
        }
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1071
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1072
        if (isApply || isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1073
            if (passesArgs) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1074
                // R(this, args) => R(this, Object[])
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1075
                appliedType = appliedType.changeParameterType(2, Object[].class);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1076
                // drop any extraneous arguments for the apply fail case
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1077
                if (isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1078
                    appliedType = appliedType.dropParameterTypes(3, paramCount - 1);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1079
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1080
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1081
                // R(this) => R(this, Object[])
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1082
                appliedType = appliedType.insertParameterTypes(2, Object[].class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1083
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1084
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1085
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1086
        appliedDesc = appliedDesc.changeMethodType(appliedType); //no extra args
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1087
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1088
        // Create the same arguments for the delegate linking request that would be passed in an actual apply'd invocation
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1089
        final Object[] appliedArgs = new Object[isApply ? 3 : appliedType.parameterCount()];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1090
        appliedArgs[0] = appliedFn;
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24720
diff changeset
  1091
        appliedArgs[1] = passesThis ? appliedFnNeedsWrappedThis ? ScriptFunctionData.wrapThis(args[2]) : args[2] : ScriptRuntime.UNDEFINED;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1092
        if (isApply && !isFailedApplyToCall) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1093
            appliedArgs[2] = passesArgs ? NativeFunction.toApplyArgs(args[3]) : ScriptRuntime.EMPTY_ARRAY;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1094
        } else {
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1095
            if (passesArgs) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1096
                if (isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1097
                    final Object[] tmp = new Object[args.length - 3];
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1098
                    System.arraycopy(args, 3, tmp, 0, tmp.length);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1099
                    appliedArgs[2] = NativeFunction.toApplyArgs(tmp);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1100
                } else {
25237
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1101
                    assert !isApply;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1102
                    System.arraycopy(args, 3, appliedArgs, 2, args.length - 3);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1103
                }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1104
            } else if (isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1105
                appliedArgs[2] = ScriptRuntime.EMPTY_ARRAY;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1106
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1107
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1108
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1109
        // Ask the linker machinery for an invocation of the target function
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1110
        final LinkRequest appliedRequest = request.replaceArguments(appliedDesc, appliedArgs);
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1111
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1112
        GuardedInvocation appliedInvocation;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1113
        try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1114
            appliedInvocation = Bootstrap.getLinkerServices().getGuardedInvocation(appliedRequest);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1115
        } catch (final RuntimeException | Error e) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1116
            throw e;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1117
        } catch (final Exception e) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1118
            throw new RuntimeException(e);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1119
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1120
        assert appliedRequest != null; // Bootstrap.isCallable() returned true for args[1], so it must produce a linkage.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1121
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1122
        final Class<?> applyFnType = descType.parameterType(0);
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1123
        // Invocation and guard handles from apply invocation.
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1124
        MethodHandle inv = appliedInvocation.getInvocation();
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1125
        MethodHandle guard = appliedInvocation.getGuard();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1126
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1127
        if (isApply && !isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1128
            if (passesArgs) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1129
                // Make sure that the passed argArray is converted to Object[] the same way NativeFunction.apply() would do it.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1130
                inv = MH.filterArguments(inv, 2, NativeFunction.TO_APPLY_ARGS);
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1131
                // Some guards (non-strict functions with non-primitive this) have a this-object parameter, so we
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1132
                // need to apply this transformations to them as well.
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1133
                if (guard.type().parameterCount() > 2) {
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1134
                    guard = MH.filterArguments(guard, 2, NativeFunction.TO_APPLY_ARGS);
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1135
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1136
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1137
                // If the original call site doesn't pass argArray, pass in an empty array
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1138
                inv = MH.insertArguments(inv, 2, (Object) ScriptRuntime.EMPTY_ARRAY);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1139
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1140
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1141
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1142
        if (isApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1143
            if (isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1144
                //take the real arguments that were passed to a call and force them into the apply instead
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1145
                Context.getContextTrusted().getLogger(ApplySpecialization.class).info("Collection arguments to revert call to apply in " + appliedFn);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1146
                inv = MH.asCollector(inv, Object[].class, realArgCount);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1147
            } else {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1148
                appliedInvocation = appliedInvocation.addSwitchPoint(applyToCallSwitchPoint);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1149
            }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1150
        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1151
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1152
        if (!passesThis) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1153
            // If the original call site doesn't pass in a thisArg, pass in Global/undefined as needed
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1154
            inv = bindImplicitThis(appliedFnNeedsWrappedThis, inv);
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1155
            // guard may have this-parameter that needs to be inserted
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1156
            if (guard.type().parameterCount() > 1) {
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1157
                guard = bindImplicitThis(appliedFnNeedsWrappedThis, guard);
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1158
            }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1159
        } else if (appliedFnNeedsWrappedThis) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1160
            // target function needs a wrapped this, so make sure we filter for that
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1161
            inv = MH.filterArguments(inv, 1, WRAP_THIS);
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1162
            // guard may have this-parameter that needs to be wrapped
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1163
            if (guard.type().parameterCount() > 1) {
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1164
                guard = MH.filterArguments(guard, 1, WRAP_THIS);
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1165
            }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1166
        }
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1167
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1168
        final MethodType guardType = guard.type(); // Needed for combining guards below
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1169
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1170
        // We need to account for the dropped (apply|call) function argument.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1171
        inv = MH.dropArguments(inv, 0, applyFnType);
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1172
        guard = MH.dropArguments(guard, 0, applyFnType);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1173
26375
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1174
        /*
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1175
         * Dropargs can only be non-()V in the case of isApply && !isFailedApplyToCall, which
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1176
         * is when we need to add arguments to the callsite to catch and ignore the synthetic
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1177
         * extra args that someone has added to the command line.
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1178
         */
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1179
        for (int i = 0; i < dropArgs.parameterCount(); i++) {
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1180
            inv = MH.dropArguments(inv, 4 + i, dropArgs.parameterType(i));
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1181
        }
a741f7808507 8057019: Various problems with extra arguments to applies
lagergren
parents: 26068
diff changeset
  1182
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1183
        // Take the "isApplyFunction" guard, and bind it to this function.
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1184
        MethodHandle applyFnGuard = MH.insertArguments(IS_APPLY_FUNCTION, 2, this); //TODO replace this with switchpoint
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1185
        // Adapt the guard to receive all the arguments that the original guard does.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1186
        applyFnGuard = MH.dropArguments(applyFnGuard, 2, guardType.parameterArray());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1187
        // Fold the original function guard into our apply guard.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1188
        guard = MH.foldArguments(applyFnGuard, guard);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1189
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1190
        return appliedInvocation.replaceMethods(inv, guard);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1191
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1192
25237
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1193
    /*
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1194
     * This method is used for linking nested apply. Specialized apply and call linking will create a variable arity
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1195
     * call site for an apply call; when createApplyOrCallCall sees a linking request for apply or call with
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1196
     * Nashorn-style variable arity call site (last argument type is Object[]) it'll delegate to this method.
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1197
     * This method converts the link request from a vararg to a non-vararg one (unpacks the array), then delegates back
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1198
     * to createApplyOrCallCall (with which it is thus mutually recursive), and adds appropriate argument spreaders to
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1199
     * invocation and the guard of whatever createApplyOrCallCall returned to adapt it back into a variable arity
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1200
     * invocation. It basically reduces the problem of vararg call site linking of apply and call back to the (already
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1201
     * solved by createApplyOrCallCall) non-vararg call site linking.
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1202
     */
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1203
    private GuardedInvocation createVarArgApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc,
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1204
            final LinkRequest request, final Object[] args) {
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1205
        final MethodType descType = desc.getMethodType();
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1206
        final int paramCount = descType.parameterCount();
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1207
        final Object[] varArgs = (Object[]) args[paramCount - 1];
25237
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1208
        // -1 'cause we're not passing the vararg array itself
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1209
        final int copiedArgCount = args.length - 1;
26067
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26056
diff changeset
  1210
        final int varArgCount = varArgs.length;
25237
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1211
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1212
        // Spread arguments for the delegate createApplyOrCallCall invocation.
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1213
        final Object[] spreadArgs = new Object[copiedArgCount + varArgCount];
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1214
        System.arraycopy(args, 0, spreadArgs, 0, copiedArgCount);
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1215
        System.arraycopy(varArgs, 0, spreadArgs, copiedArgCount, varArgCount);
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1216
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1217
        // Spread call site descriptor for the delegate createApplyOrCallCall invocation. We drop vararg array and
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1218
        // replace it with a list of Object.class.
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1219
        final MethodType spreadType = descType.dropParameterTypes(paramCount - 1, paramCount).appendParameterTypes(
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1220
                Collections.<Class<?>>nCopies(varArgCount, Object.class));
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1221
        final CallSiteDescriptor spreadDesc = desc.changeMethodType(spreadType);
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1222
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1223
        // Delegate back to createApplyOrCallCall with the spread (that is, reverted to non-vararg) request/
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1224
        final LinkRequest spreadRequest = request.replaceArguments(spreadDesc, spreadArgs);
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1225
        final GuardedInvocation spreadInvocation = createApplyOrCallCall(isApply, spreadDesc, spreadRequest, spreadArgs);
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1226
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1227
        // Add spreader combinators to returned invocation and guard.
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1228
        return spreadInvocation.replaceMethods(
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1229
                // Use standard ScriptObject.pairArguments on the invocation
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1230
                pairArguments(spreadInvocation.getInvocation(), descType),
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1231
                // Use our specialized spreadGuardArguments on the guard (see below).
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1232
                spreadGuardArguments(spreadInvocation.getGuard(), descType));
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1233
    }
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1234
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1235
    private static MethodHandle spreadGuardArguments(final MethodHandle guard, final MethodType descType) {
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1236
        final MethodType guardType = guard.type();
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1237
        final int guardParamCount = guardType.parameterCount();
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1238
        final int descParamCount = descType.parameterCount();
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1239
        final int spreadCount = guardParamCount - descParamCount + 1;
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1240
        if (spreadCount <= 0) {
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1241
            // Guard doesn't dip into the varargs
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1242
            return guard;
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1243
        }
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1244
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1245
        final MethodHandle arrayConvertingGuard;
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1246
        // If the last parameter type of the guard is an array, then it is already itself a guard for a vararg apply
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1247
        // invocation. We must filter the last argument with toApplyArgs otherwise deeper levels of nesting will fail
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1248
        // with ClassCastException of NativeArray to Object[].
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1249
        if (guardType.parameterType(guardParamCount - 1).isArray()) {
25237
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1250
            arrayConvertingGuard = MH.filterArguments(guard, guardParamCount - 1, NativeFunction.TO_APPLY_ARGS);
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1251
        } else {
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1252
            arrayConvertingGuard = guard;
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1253
        }
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1254
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1255
        return ScriptObject.adaptHandleToVarArgCallSite(arrayConvertingGuard, descParamCount);
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1256
    }
bf5efe0a93ba 8046905: apply on apply is broken
attila
parents: 24759
diff changeset
  1257
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1258
    private static MethodHandle bindImplicitThis(final boolean needsWrappedThis, final MethodHandle mh) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1259
        final MethodHandle bound;
43349
be6e40f785d7 8166186: ClassCastException with arguments usage
hannesw
parents: 40824
diff changeset
  1260
        if (needsWrappedThis) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1261
            bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1262
        } else {
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1263
            bound = mh;
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1264
        }
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1265
        return MH.insertArguments(bound, 1, ScriptRuntime.UNDEFINED);
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1266
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1267
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1268
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1269
     * Used for noSuchMethod/noSuchProperty and JSAdapter hooks.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1270
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1271
     * These don't want a callee parameter, so bind that. Name binding is
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1272
     * optional.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1273
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1274
    MethodHandle getCallMethodHandle(final MethodType type, final String bindName) {
24729
2b13051f2122 8037534: Use scope types to determine optimistic types
attila
parents: 24727
diff changeset
  1275
        return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), bindName), type);
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
  1276
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1277
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
  1278
    private static MethodHandle bindToNameIfNeeded(final MethodHandle methodHandle, final String bindName) {
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1279
        if (bindName == null) {
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1280
            return methodHandle;
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1281
        }
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1282
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1283
        // if it is vararg method, we need to extend argument array with
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1284
        // a new zeroth element that is set to bindName value.
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1285
        final MethodType methodType = methodHandle.type();
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1286
        final int parameterCount = methodType.parameterCount();
40824
c24d212a8733 8077149: __noSuchProperty__ and __noSuchMethod__ invocations are not properly guarded
hannesw
parents: 36686
diff changeset
  1287
c24d212a8733 8077149: __noSuchProperty__ and __noSuchMethod__ invocations are not properly guarded
hannesw
parents: 36686
diff changeset
  1288
        if (parameterCount < 2) {
c24d212a8733 8077149: __noSuchProperty__ and __noSuchMethod__ invocations are not properly guarded
hannesw
parents: 36686
diff changeset
  1289
            return methodHandle; // method does not have enough parameters
c24d212a8733 8077149: __noSuchProperty__ and __noSuchMethod__ invocations are not properly guarded
hannesw
parents: 36686
diff changeset
  1290
        }
c24d212a8733 8077149: __noSuchProperty__ and __noSuchMethod__ invocations are not properly guarded
hannesw
parents: 36686
diff changeset
  1291
        final boolean isVarArg = methodType.parameterType(parameterCount - 1).isArray();
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1292
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1293
        if (isVarArg) {
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1294
            return MH.filterArguments(methodHandle, 1, MH.insertArguments(ADD_ZEROTH_ELEMENT, 1, bindName));
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1295
        }
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
  1296
        return MH.insertArguments(methodHandle, 1, bindName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1297
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1298
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1299
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1300
     * Get the guard that checks if a {@link ScriptFunction} is equal to a known
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1301
     * ScriptFunction, using reference comparison
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1302
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1303
     * @param function The ScriptFunction to check against. This will be bound
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1304
     * to the guard method handle
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1305
     *
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1306
     * @return method handle for guard
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1307
     */
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1308
    private static MethodHandle getFunctionGuard(final ScriptFunction function, final int flags) {
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1309
        assert function.data != null;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1310
        // Built-in functions have a 1-1 correspondence to their ScriptFunctionData, so we can use a cheaper identity
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1311
        // comparison for them.
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1312
        if (function.data.isBuiltin()) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1313
            return Guards.getIdentityGuard(function);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1314
        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
  1315
        return MH.insertArguments(IS_FUNCTION_MH, 1, function.data);
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1316
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1317
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1318
    /**
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1319
     * Get a guard that checks if a {@link ScriptFunction} is equal to a known
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1320
     * ScriptFunction using reference comparison, and whether the type of the
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1321
     * second argument (this-object) is not a JavaScript primitive type.
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1322
     *
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1323
     * @param function The ScriptFunction to check against. This will be bound
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1324
     * to the guard method handle
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1325
     *
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1326
     * @return method handle for guard
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1327
     */
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1328
    private static MethodHandle getNonStrictFunctionGuard(final ScriptFunction function) {
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1329
        assert function.data != null;
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1330
        return MH.insertArguments(IS_NONSTRICT_FUNCTION, 2, function.data);
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1331
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1332
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1333
    @SuppressWarnings("unused")
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1334
    private static boolean isFunctionMH(final Object self, final ScriptFunctionData data) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1335
        return self instanceof ScriptFunction && ((ScriptFunction) self).data == data;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1336
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1337
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1338
    @SuppressWarnings("unused")
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1339
    private static boolean isNonStrictFunction(final Object self, final Object arg, final ScriptFunctionData data) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1340
        return self instanceof ScriptFunction && ((ScriptFunction) self).data == data && arg instanceof ScriptObject;
16523
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1341
    }
af8b30edebce 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents: 16277
diff changeset
  1342
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26375
diff changeset
  1343
    //TODO this can probably be removed given that we have builtin switchpoints in the context
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1344
    @SuppressWarnings("unused")
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1345
    private static boolean isApplyFunction(final boolean appliedFnCondition, final Object self, final Object expectedSelf) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1346
        // NOTE: we're using self == expectedSelf as we're only using this with built-in functions apply() and call()
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1347
        return appliedFnCondition && self == expectedSelf;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1348
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1349
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1350
    @SuppressWarnings("unused")
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1351
    private static Object[] addZerothElement(final Object[] args, final Object value) {
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1352
        // extends input array with by adding new zeroth element
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 29411
diff changeset
  1353
        final Object[] src = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1354
        final Object[] result = new Object[src.length + 1];
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1355
        System.arraycopy(src, 0, result, 1, src.length);
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1356
        result[0] = value;
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1357
        return result;
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1358
    }
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
  1359
20946
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1360
    @SuppressWarnings("unused")
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1361
    private static Object invokeSync(final ScriptFunction func, final Object sync, final Object self, final Object... args)
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1362
            throws Throwable {
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1363
        final Object syncObj = sync == UNDEFINED ? self : sync;
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1364
        synchronized (syncObj) {
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1365
            return func.invoke(self, args);
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1366
        }
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1367
    }
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
  1368
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1369
    private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1370
        return MH.findStatic(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1371
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1372
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1373
    private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
  1374
        return MH.findVirtual(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1375
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1376
}