nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
author lagergren
Wed, 23 Apr 2014 17:37:41 +0200
changeset 24745 3a6e1477362b
parent 24744 5290da85fc3d
child 24753 675feda2f82d
permissions -rw-r--r--
8041434: Add synchronization to the common global constants structure Reviewed-by: attila, hannesw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 20946
diff changeset
    29
import static jdk.nashorn.internal.lookup.Lookup.MH;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    30
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    32
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import java.lang.invoke.MethodHandle;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
import java.lang.invoke.MethodHandles;
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;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16233
diff changeset
    38
import jdk.internal.dynalink.CallSiteDescriptor;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16233
diff changeset
    39
import jdk.internal.dynalink.linker.GuardedInvocation;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16233
diff changeset
    40
import jdk.internal.dynalink.linker.LinkRequest;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    41
import jdk.internal.dynalink.support.Guards;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
    42
import jdk.nashorn.internal.codegen.ApplySpecialization;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
    44
import jdk.nashorn.internal.objects.Global;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    45
import jdk.nashorn.internal.objects.NativeFunction;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    46
import jdk.nashorn.internal.runtime.linker.Bootstrap;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    47
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    48
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    49
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
 * Runtime representation of a JavaScript function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
public abstract class ScriptFunction extends ScriptObject {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
    /** Method handle for prototype getter for this ScriptFunction */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    55
    public static final MethodHandle G$PROTOTYPE = findOwnMH_S("G$prototype", Object.class, Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
    /** Method handle for prototype setter for this ScriptFunction */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    58
    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
    59
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    60
    /** Method handle for length getter for this ScriptFunction */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    61
    public static final MethodHandle G$LENGTH = findOwnMH_S("G$length", int.class, Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
    /** Method handle for name getter for this ScriptFunction */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    64
    public static final MethodHandle G$NAME = findOwnMH_S("G$name", Object.class, Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
20946
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
    66
    /** Method handle used for implementing sync() in mozilla_compat */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    67
    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
    68
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
    /** Method handle for allocate function for this ScriptFunction */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    70
    static final MethodHandle ALLOCATE = findOwnMH_V("allocate", Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    72
    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
    73
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
    74
    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
    75
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
    /** method handle to scope getter for this ScriptFunction */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
    public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    79
    private static final MethodHandle IS_FUNCTION_MH  = findOwnMH_S("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    80
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    81
    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
    82
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    83
    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
    84
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    85
    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
    86
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    87
    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
    88
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
    /** The parent scope. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
    private final ScriptObject scope;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    91
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
    92
    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
    93
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
    94
    /** The property map used for newly allocated object when function is used as constructor. */
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
    95
    protected PropertyMap allocatorMap;
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
    96
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
     *
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   100
     * @param name          function name
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   101
     * @param methodHandle  method handle to function (if specializations are present, assumed to be most generic)
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   102
     * @param map           property map
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   103
     * @param scope         scope
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   104
     * @param specs         specialized version of this function - other method handles
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   105
     * @param flags         {@link ScriptFunctionData} flags
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   106
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
    protected ScriptFunction(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
            final String name,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
            final MethodHandle methodHandle,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   110
            final PropertyMap map,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   111
            final ScriptObject scope,
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   112
            final MethodHandle[] specs,
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   113
            final int flags) {
16206
83069fa0935b 8006529: Methods always get callee - it should be conditional
attila
parents: 16202
diff changeset
   114
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   115
        this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   116
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   117
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   119
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
     *
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   121
     * @param data          static function data
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
     * @param map           property map
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
     * @param scope         scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   125
    protected ScriptFunction(
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   126
            final ScriptFunctionData data,
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   127
            final PropertyMap map,
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   128
            final ScriptObject scope) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   129
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   130
        super(map);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   131
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   132
        if (Context.DEBUG) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   133
            constructorCount++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   134
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   135
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
   136
        this.data  = 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
   137
        this.scope = scope;
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
   138
        this.allocatorMap = data.getAllocatorMap();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   139
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   140
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   141
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   142
    public String getClassName() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   143
        return "Function";
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   144
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   145
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   146
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   147
     * ECMA 15.3.5.3 [[HasInstance]] (V)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   148
     * Step 3 if "prototype" value is not an Object, throw TypeError
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   149
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   150
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   151
    public boolean isInstance(final ScriptObject instance) {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   152
        final Object basePrototype = getTargetFunction().getPrototype();
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   153
        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
   154
            throw typeError("prototype.not.an.object", ScriptRuntime.safeToString(getTargetFunction()), ScriptRuntime.safeToString(basePrototype));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   155
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   157
        for (ScriptObject proto = instance.getProto(); proto != null; proto = proto.getProto()) {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   158
            if (proto == basePrototype) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
                return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   160
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   161
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   163
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   164
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
    /**
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   167
     * Returns the target function for this function. If the function was not created using
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   168
     * {@link #makeBoundFunction(Object, Object[])}, its target function is itself. If it is bound, its target function
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   169
     * is the target function of the function it was made from (therefore, the target function is always the final,
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   170
     * unbound recipient of the calls).
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   171
     * @return the target function for this function.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   172
     */
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   173
    protected ScriptFunction getTargetFunction() {
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   174
        return this;
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   175
    }
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   176
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   177
    boolean isBoundFunction() {
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   178
        return getTargetFunction() != this;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   179
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   180
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   181
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   182
     * Set the arity of this ScriptFunction
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
     * @param arity arity
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
    public final void setArity(final int arity) {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   186
        data.setArity(arity);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   189
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   190
     * Is this a ECMAScript 'use strict' function?
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   191
     * @return true if function is in strict mode
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
     */
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   193
    public boolean isStrict() {
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   194
        return data.isStrict();
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   195
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   196
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   197
    /**
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   198
     * Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   199
     * according to ECMA 10.4.3.
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   200
     * @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
   201
     */
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   202
    public boolean needsWrappedThis() {
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   203
        return data.needsWrappedThis();
16186
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16173
diff changeset
   204
    }
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16173
diff changeset
   205
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
   206
    private static boolean needsWrappedThis(final Object fn) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   207
        return fn instanceof ScriptFunction ? ((ScriptFunction)fn).needsWrappedThis() : false;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   208
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   209
16186
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16173
diff changeset
   210
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   211
     * Execute this script function.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
     * @param self  Target object.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   213
     * @param arguments  Call arguments.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
     * @return ScriptFunction result.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
     * @throws Throwable if there is an exception/error with the invocation or thrown from it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   216
     */
16232
efd57dd90de6 8008197: Cross script engine function calls do not work as expected
sundar
parents: 16228
diff changeset
   217
    Object invoke(final Object self, final Object... arguments) throws Throwable {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   218
        if (Context.DEBUG) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
            invokes++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
        }
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   221
        return data.invoke(this, self, arguments);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   222
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   224
    /**
18614
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   225
     * Execute this script function as a constructor.
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   226
     * @param arguments  Call arguments.
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   227
     * @return Newly constructed result.
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   228
     * @throws Throwable if there is an exception/error with the invocation or thrown from it
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   229
     */
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   230
    Object construct(final Object... arguments) throws Throwable {
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   231
        return data.construct(this, arguments);
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   232
    }
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   233
addca7a10167 8015959: Can't call foreign constructor
sundar
parents: 17252
diff changeset
   234
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
     * Allocate function. Called from generated {@link ScriptObject} code
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   236
     * for allocation as a factory method
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
     * @return a new instance of the {@link ScriptObject} whose allocator this is
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   239
     */
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   240
    @SuppressWarnings("unused")
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   241
    private Object allocate() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
        if (Context.DEBUG) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   243
            allocations++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   244
        }
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24720
diff changeset
   245
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   246
        assert !isBoundFunction(); // allocate never invoked on bound functions
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   247
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
   248
        final ScriptObject object = data.allocate(allocatorMap);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   249
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   250
        if (object != null) {
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24720
diff changeset
   251
            final Object prototype = getPrototype();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   252
            if (prototype instanceof ScriptObject) {
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
   253
                object.setInitialProto((ScriptObject)prototype);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   254
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   255
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   256
            if (object.getProto() == null) {
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 22669
diff changeset
   257
                object.setInitialProto(getObjectPrototype());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   258
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   260
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   261
        return object;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   262
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   263
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   265
     * Return Object.prototype - used by "allocate"
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
     * @return Object.prototype
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   268
    protected abstract ScriptObject getObjectPrototype();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   269
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   270
    /**
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   271
     * Creates a version of this function bound to a specific "self" and other arguments, as per
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   272
     * {@code Function.prototype.bind} functionality in ECMAScript 5.1 section 15.3.4.5.
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   273
     * @param self the self to bind to this function. Can be null (in which case, null is bound as this).
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   274
     * @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments.
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   275
     * @return a function with the specified self and parameters bound.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   276
     */
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   277
    protected ScriptFunction makeBoundFunction(final Object self, final Object[] args) {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   278
        return makeBoundFunction(data.makeBoundFunctionData(this, self, args));
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   279
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   280
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   281
    /**
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   282
     * Create a version of this function as in {@link ScriptFunction#makeBoundFunction(Object, Object[])},
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   283
     * but using a {@link ScriptFunctionData} for the bound data.
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   284
     *
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   285
     * @param boundData ScriptFuntionData for the bound function
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   286
     * @return a function with the bindings performed according to the given data
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16232
diff changeset
   287
     */
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   288
    protected abstract ScriptFunction makeBoundFunction(ScriptFunctionData boundData);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   289
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   290
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   291
    public final String safeToString() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   292
        return toSource();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   293
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   294
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   295
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   296
    public String toString() {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   297
        return data.toString();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   298
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   299
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   300
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
     * Get this function as a String containing its source code. If no source code
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   302
     * exists in this ScriptFunction, its contents will be displayed as {@code [native code]}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   303
     * @return string representation of this function's source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   304
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
    public final String toSource() {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   306
        return data.toSource();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   308
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   310
     * Get the prototype object for this function
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
     * @return prototype
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   312
     */
17252
9aeb443c4740 8006559: Octane:pdfjs leaks memory, runs slower iteration to iteration
hannesw
parents: 16523
diff changeset
   313
    public abstract Object getPrototype();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   314
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   315
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   316
     * Set the prototype object for this function
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   317
     * @param prototype new prototype object
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   318
     */
17252
9aeb443c4740 8006559: Octane:pdfjs leaks memory, runs slower iteration to iteration
hannesw
parents: 16523
diff changeset
   319
    public abstract void setPrototype(Object prototype);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   320
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   321
    /**
20946
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   322
     * Create a function that invokes this function synchronized on {@code sync} or the self object
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   323
     * of the invocation.
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   324
     * @param sync the Object to synchronize on, or undefined
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   325
     * @return synchronized function
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   326
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   327
   public abstract ScriptFunction makeSynchronizedFunction(Object sync);
20946
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   328
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   329
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   330
     * Return the invoke handle bound to a given ScriptObject self reference.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   331
     * If callee parameter is required result is rebound to this.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
     * @param self self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
     * @return bound invoke handle
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
     */
20932
323bdf36c328 8026162: "this" in SAM adapter functions is wrong
sundar
parents: 19472
diff changeset
   336
    public final MethodHandle getBoundInvokeHandle(final Object self) {
24729
2b13051f2122 8037534: Use scope types to determine optimistic types
attila
parents: 24727
diff changeset
   337
        return MH.bindTo(bindToCalleeIfNeeded(data.getGenericInvoker(scope)), self);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   338
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   339
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   340
    /**
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   341
     * Bind the method handle to this {@code ScriptFunction} instance if it needs a callee parameter. If this function's
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   342
     * method handles don't have a callee parameter, the handle is returned unchanged.
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   343
     * @param methodHandle the method handle to potentially bind to this function instance.
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   344
     * @return the potentially bound method handle
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   345
     */
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   346
    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
   347
        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
   348
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   349
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   350
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   351
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   352
     * Get the name for this function
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   353
     * @return the name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   354
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   355
    public final String getName() {
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   356
        return data.getName();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   357
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   358
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   359
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   360
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   361
     * Get the scope for this function
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   362
     * @return the scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   363
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   364
    public final ScriptObject getScope() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   365
        return scope;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   366
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   367
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   368
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   369
     * Prototype getter for this ScriptFunction - follows the naming convention
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   370
     * used by Nasgen and the code generator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   371
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   372
     * @param self  self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   373
     * @return self's prototype
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   374
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   375
    public static Object G$prototype(final Object self) {
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24720
diff changeset
   376
        return self instanceof ScriptFunction ?
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   377
            ((ScriptFunction)self).getPrototype() :
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   378
            UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   379
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   380
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   381
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   382
     * Prototype setter for this ScriptFunction - follows the naming convention
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   383
     * used by Nasgen and the code generator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   384
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   385
     * @param self  self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   386
     * @param prototype prototype to set
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   387
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388
    public static void S$prototype(final Object self, final Object prototype) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   389
        if (self instanceof ScriptFunction) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   390
            ((ScriptFunction)self).setPrototype(prototype);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   391
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   392
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   393
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   394
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   395
     * Length getter - ECMA 15.3.3.2: Function.length
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   396
     * @param self self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   397
     * @return length
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   399
    public static int G$length(final Object self) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   400
        if (self instanceof ScriptFunction) {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   401
            return ((ScriptFunction)self).data.getArity();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   402
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   403
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   404
        return 0;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   405
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   406
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   407
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   408
     * Name getter - ECMA Function.name
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   409
     * @param self self refence
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   410
     * @return the name, or undefined if none
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   411
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   412
    public static Object G$name(final Object self) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   413
        if (self instanceof ScriptFunction) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   414
            return ((ScriptFunction)self).getName();
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
        return UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
     * Get the prototype for this ScriptFunction
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   422
     * @param constructor constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   423
     * @return prototype, or null if given constructor is not a ScriptFunction
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
    public static ScriptObject getPrototype(final Object constructor) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
        if (constructor instanceof ScriptFunction) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
            final Object proto = ((ScriptFunction)constructor).getPrototype();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   428
            if (proto instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   429
                return (ScriptObject)proto;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   430
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   433
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   434
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   435
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   436
    // These counters are updated only in debug mode.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   437
    private static int constructorCount;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
    private static int invokes;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   439
    private static int allocations;
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
     * @return the constructorCount
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   443
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   444
    public static int getConstructorCount() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   445
        return constructorCount;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
     * @return the invokes
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
    public static int getInvokes() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   452
        return invokes;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   454
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   456
     * @return the allocations
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
    public static int getAllocations() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
        return allocations;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   460
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   461
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
    @Override
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   463
    protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   464
        final MethodType type = desc.getMethodType();
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   465
        assert desc.getMethodType().returnType() == Object.class && !NashornCallSiteDescriptor.isOptimistic(desc);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   466
        final CompiledFunction cf = data.getBestConstructor(type, scope);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   467
        final GuardedInvocation bestCtorInv = new GuardedInvocation(cf.getConstructor(), cf.getOptimisticAssumptionsSwitchPoint());
24720
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   468
        //TODO - ClassCastException
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   469
        return new GuardedInvocation(pairArguments(bestCtorInv.getInvocation(), type), getFunctionGuard(this, cf.getFlags()), bestCtorInv.getSwitchPoints(), null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   470
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   472
    @SuppressWarnings("unused")
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   473
    private static Object wrapFilter(final Object obj) {
16228
df28320aa080 8007900: Function binding is inefficient
attila
parents: 16226
diff changeset
   474
        if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   475
            return obj;
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   476
        }
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23372
diff changeset
   477
        return Context.getGlobal().wrapAsObject(obj);
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   478
    }
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   479
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   480
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   481
    @SuppressWarnings("unused")
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   482
    private static Object globalFilter(final Object object) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   483
        // replace whatever we get with the current global object
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23372
diff changeset
   484
        return Context.getGlobal();
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   485
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   486
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   487
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   488
     * dyn:call call site signature: (callee, thiz, [args...])
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   489
     * generated method signature:   (callee, thiz, [args...])
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   490
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   491
     * cases:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   492
     * (a) method has callee parameter
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   493
     *   (1) for local/scope calls, we just bind thiz and drop the second argument.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   494
     *   (2) for normal this-calls, we have to swap thiz and callee to get matching signatures.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   495
     * (b) method doesn't have callee parameter (builtin functions)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   496
     *   (3) for local/scope calls, bind thiz and drop both callee and thiz.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   497
     *   (4) for normal this-calls, drop callee.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   498
     *
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   499
     * @return guarded invocation for call
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   500
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   501
    @Override
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16188
diff changeset
   502
    protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   503
        final MethodType type = desc.getMethodType();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   504
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   505
        final String  name       = getName();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   506
        final boolean isUnstable = request.isCallSiteUnstable();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   507
        final boolean scopeCall  = NashornCallSiteDescriptor.isScope(desc);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   508
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   509
        final boolean isCall     = !scopeCall && data.isBuiltin() && "call".equals(name);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   510
        final boolean isApply    = !scopeCall && data.isBuiltin() && "apply".equals(name);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   512
        if (isUnstable && !(isApply || isCall)) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   513
            //megamorphic - replace call with apply
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   514
            final MethodHandle handle;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   515
            //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
   516
            if (type.parameterCount() == 3 && type.parameterType(2) == Object[].class) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   517
                // Vararg call site
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   518
                handle = ScriptRuntime.APPLY.methodHandle();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   519
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   520
                // (callee, this, args...) => (callee, this, args[])
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   521
                handle = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   522
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   524
            // 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
   525
            // generic "is this a ScriptFunction?" guard.
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   526
            return new GuardedInvocation(
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   527
                    handle,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   528
                    null,
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   529
                    (SwitchPoint)null,
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   530
                    ClassCastException.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   531
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   532
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
        MethodHandle boundHandle;
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   534
        MethodHandle guard = null;
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16206
diff changeset
   535
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   536
        // Special handling of Function.apply and Function.call. Note we must be invoking
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   537
        if ((isApply || isCall) && !isUnstable) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   538
            final Object[] args = request.getArguments();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   539
            if (Bootstrap.isCallable(args[1])) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   540
                return createApplyOrCallCall(isApply, desc, request, args);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   541
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   542
        } //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
   543
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   544
        final int programPoint = NashornCallSiteDescriptor.isOptimistic(desc) ? NashornCallSiteDescriptor.getProgramPoint(desc) : INVALID_PROGRAM_POINT;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   545
        final CompiledFunction cf = data.getBestInvoker(type, programPoint, scope);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   546
        final GuardedInvocation bestInvoker =
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   547
                new GuardedInvocation(
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   548
                        cf.createInvoker(type.returnType(), programPoint),
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   549
                        cf.getOptimisticAssumptionsSwitchPoint());
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   550
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   551
        final MethodHandle callHandle = bestInvoker.getInvocation();
24727
attila
parents: 24725 23375
diff changeset
   552
16216
46ed48fd84d3 8007273: Creation of ScriptFunctions can be refactored
hannesw
parents: 16210
diff changeset
   553
        if (data.needsCallee()) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   554
            if (scopeCall && needsWrappedThis()) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
   555
                // (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
   556
                boundHandle = MH.filterArguments(callHandle, 1, SCRIPTFUNCTION_GLOBALFILTER);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   557
            } else {
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   558
                // 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
   559
                boundHandle = callHandle;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   560
            }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   561
        } else if (data.isBuiltin() && "extend".equals(data.getName())) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   562
            // NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   563
            // current lookup as its "this" so it can do security-sensitive creation of adapter classes.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   564
            boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, type.parameterType(0), type.parameterType(1));
24727
attila
parents: 24725 23375
diff changeset
   565
        } else if (scopeCall && needsWrappedThis()) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   566
            // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
24727
attila
parents: 24725 23375
diff changeset
   567
            // (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
   568
            boundHandle = MH.filterArguments(callHandle, 0, SCRIPTFUNCTION_GLOBALFILTER);
24727
attila
parents: 24725 23375
diff changeset
   569
            // ([this], args...) => ([callee], [this], args...)
attila
parents: 24725 23375
diff changeset
   570
            boundHandle = MH.dropArguments(boundHandle, 0, type.parameterType(0));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   571
        } else {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   572
            // (this, args...) => ([callee], this, args...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   573
            boundHandle = MH.dropArguments(callHandle, 0, type.parameterType(0));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
19456
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   576
        // 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
   577
        // 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
   578
        // 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
   579
        if (!scopeCall && needsWrappedThis()) {
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   580
            if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) {
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   581
                boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER);
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   582
            } else {
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   583
                guard = getNonStrictFunctionGuard(this);
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   584
            }
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   585
        }
8cc345d620c8 8022524: Memory leaks in nashorn sources and tests found by jhat analysis
sundar
parents: 18868
diff changeset
   586
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   587
        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
   588
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   589
        return new GuardedInvocation(boundHandle, guard == null ? getFunctionGuard(this, cf.getFlags()) : guard, bestInvoker.getSwitchPoints(), null);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   590
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   591
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   592
    private GuardedInvocation createApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc, final LinkRequest request, final Object[] args) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   593
        final MethodType descType = desc.getMethodType();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   594
        final int paramCount = descType.parameterCount();
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   595
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   596
        final boolean passesThis = paramCount > 2;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   597
        final boolean passesArgs = paramCount > 3;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   598
        final int realArgCount = passesArgs ? paramCount - 3 : 0;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   599
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   600
        final Object appliedFn = args[1];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   601
        final boolean appliedFnNeedsWrappedThis = needsWrappedThis(appliedFn);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   602
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   603
        //box call back to apply
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   604
        CallSiteDescriptor appliedDesc = desc;
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   605
        final SwitchPoint applyToCallSwitchPoint = Global.instance().getChangeCallback("apply");
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   606
        //enough to change the proto switchPoint here
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   607
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   608
        final boolean isApplyToCall = NashornCallSiteDescriptor.isApplyToCall(desc);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   609
        final boolean isFailedApplyToCall = isApplyToCall && applyToCallSwitchPoint.hasBeenInvalidated();
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   610
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   611
        // R(apply|call, ...) => R(...)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   612
        MethodType appliedType = descType.dropParameterTypes(0, 1);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   613
        if (!passesThis) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   614
            // R() => R(this)
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   615
            appliedType = appliedType.insertParameterTypes(1, Object.class);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   616
        } else if (appliedFnNeedsWrappedThis) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   617
            appliedType = appliedType.changeParameterType(1, Object.class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   618
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   619
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   620
        if (isApply || isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   621
            if (passesArgs) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   622
                // R(this, args) => R(this, Object[])
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   623
                appliedType = appliedType.changeParameterType(2, Object[].class);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   624
                // 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
   625
                if (isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   626
                    appliedType = appliedType.dropParameterTypes(3, paramCount - 1);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   627
                }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   628
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   629
                // R(this) => R(this, Object[])
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   630
                appliedType = appliedType.insertParameterTypes(2, Object[].class);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   631
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   632
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   633
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   634
        appliedDesc = appliedDesc.changeMethodType(appliedType);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   635
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   636
        // 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
   637
        final Object[] appliedArgs = new Object[isApply ? 3 : appliedType.parameterCount()];
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   638
        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
   639
        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
   640
        if (isApply && !isFailedApplyToCall) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   641
            appliedArgs[2] = passesArgs ? NativeFunction.toApplyArgs(args[3]) : ScriptRuntime.EMPTY_ARRAY;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   642
        } else {
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   643
            if (passesArgs) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   644
                if (isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   645
                    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
   646
                    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
   647
                    appliedArgs[2] = NativeFunction.toApplyArgs(tmp);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   648
                } else {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   649
                    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
   650
                }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   651
            } else if (isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   652
                appliedArgs[2] = ScriptRuntime.EMPTY_ARRAY;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   653
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   654
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   655
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   656
        // Ask the linker machinery for an invocation of the target function
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   657
        final LinkRequest appliedRequest = request.replaceArguments(appliedDesc, appliedArgs);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   658
        GuardedInvocation appliedInvocation;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   659
        try {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   660
            appliedInvocation = Bootstrap.getLinkerServices().getGuardedInvocation(appliedRequest);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   661
        } catch (final RuntimeException | Error e) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   662
            throw e;
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   663
        } catch (final Exception e) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   664
            throw new RuntimeException(e);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   665
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   666
        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
   667
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   668
        final Class<?> applyFnType = descType.parameterType(0);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   669
        MethodHandle inv = appliedInvocation.getInvocation(); //method handle from apply invocation. the applied function invocation
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   670
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   671
        if (isApply && !isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   672
            if (passesArgs) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   673
                // 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
   674
                inv = MH.filterArguments(inv, 2, NativeFunction.TO_APPLY_ARGS);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   675
            } else {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   676
                // If the original call site doesn't pass argArray, pass in an empty array
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   677
                inv = MH.insertArguments(inv, 2, (Object)ScriptRuntime.EMPTY_ARRAY);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   678
            }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   679
        }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   680
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   681
        if (isApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   682
            if (isFailedApplyToCall) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   683
                //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
   684
                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
   685
                inv = MH.asCollector(inv, Object[].class, realArgCount);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   686
            } else {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   687
                appliedInvocation = appliedInvocation.addSwitchPoint(applyToCallSwitchPoint);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   688
            }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   689
        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   690
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   691
        if (!passesThis) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   692
            // If the original call site doesn't pass in a thisArg, pass in Global/undefined as needed
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   693
            inv = bindImplicitThis(appliedFn, inv);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   694
        } else if (appliedFnNeedsWrappedThis) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   695
            // target function needs a wrapped this, so make sure we filter for that
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   696
            inv = MH.filterArguments(inv, 1, WRAP_THIS);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   697
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   698
        inv = MH.dropArguments(inv, 0, applyFnType);
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   699
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   700
        MethodHandle guard = appliedInvocation.getGuard();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   701
        // If the guard checks the value of "this" but we aren't passing thisArg, insert the default one
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   702
        if (!passesThis && guard.type().parameterCount() > 1) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   703
            guard = bindImplicitThis(appliedFn, guard);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   704
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   705
        final MethodType guardType = guard.type();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   706
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   707
        // Original function guard will expect the invoked function in parameter position 0, but we're passing it in
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   708
        // position 1.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   709
        guard = MH.dropArguments(guard, 0, descType.parameterType(0));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   710
        // Take the "isApplyFunction" guard, and bind it to this function.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   711
        MethodHandle applyFnGuard = MH.insertArguments(IS_APPLY_FUNCTION, 2, this);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   712
        // Adapt the guard to receive all the arguments that the original guard does.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   713
        applyFnGuard = MH.dropArguments(applyFnGuard, 2, guardType.parameterArray());
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   714
        // Fold the original function guard into our apply guard.
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   715
        guard = MH.foldArguments(applyFnGuard, guard);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   716
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   717
        return appliedInvocation.replaceMethods(inv, guard);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   718
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   720
     private static MethodHandle bindImplicitThis(final Object fn, final MethodHandle mh) {
24727
attila
parents: 24725 23375
diff changeset
   721
         final MethodHandle bound;
attila
parents: 24725 23375
diff changeset
   722
         if(fn instanceof ScriptFunction && ((ScriptFunction)fn).needsWrappedThis()) {
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
   723
             bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER);
24727
attila
parents: 24725 23375
diff changeset
   724
         } else {
attila
parents: 24725 23375
diff changeset
   725
             bound = mh;
attila
parents: 24725 23375
diff changeset
   726
         }
attila
parents: 24725 23375
diff changeset
   727
         return MH.insertArguments(bound, 1, ScriptRuntime.UNDEFINED);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   728
     }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   731
     * Used for noSuchMethod/noSuchProperty and JSAdapter hooks.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   732
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   733
     * These don't want a callee parameter, so bind that. Name binding is optional.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   734
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   735
    MethodHandle getCallMethodHandle(final MethodType type, final String bindName) {
24729
2b13051f2122 8037534: Use scope types to determine optimistic types
attila
parents: 24727
diff changeset
   736
        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
   737
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   738
16225
81d58c2b9fcf 8006943: Fix order of function method arguments to be (callee, thisObject)
attila
parents: 16216
diff changeset
   739
    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
   740
        if (bindName == null) {
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   741
            return methodHandle;
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
   742
        }
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   743
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
   744
        // 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
   745
        // 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
   746
        final MethodType methodType = methodHandle.type();
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
   747
        final int parameterCount = methodType.parameterCount();
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
   748
        final boolean isVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
   749
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
   750
        if (isVarArg) {
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
   751
            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
   752
        }
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 19456
diff changeset
   753
        return MH.insertArguments(methodHandle, 1, bindName);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   754
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   755
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
   756
    /**
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
   757
     * Get the guard that checks if a {@link ScriptFunction} is equal to
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
   758
     * a known ScriptFunction, using reference comparison
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
   759
     *
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
   760
     * @param function The ScriptFunction to check against. This will be bound to the guard method handle
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
   761
     *
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
   762
     * @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
   763
     */
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   764
    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
   765
        assert function.data != null;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   766
        // 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
   767
        // comparison for them.
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   768
        if (function.data.isBuiltin()) {
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   769
            return Guards.getIdentityGuard(function);
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   770
        }
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   771
        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
   772
    }
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
   773
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
   774
    /**
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
   775
     * Get a guard that checks if a {@link ScriptFunction} is equal to
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
   776
     * a known ScriptFunction using reference comparison, and whether the type of
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
   777
     * the second argument (this-object) is not a JavaScript primitive type.
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
   778
     *
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
   779
     * @param function The ScriptFunction to check against. This will be bound to the guard method handle
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
   780
     *
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
   781
     * @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
   782
     */
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
   783
    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
   784
        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
   785
        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
   786
    }
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
   787
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
   788
    @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
   789
    private static boolean isFunctionMH(final Object self, 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
   790
        return self instanceof ScriptFunction && ((ScriptFunction)self).data == 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
   791
    }
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
   792
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
   793
    @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
   794
    private static boolean isNonStrictFunction(final Object self, final Object arg, 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
   795
        return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject;
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
   796
    }
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
   797
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   798
    @SuppressWarnings("unused")
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   799
    private static boolean isApplyFunction(final boolean appliedFnCondition, final Object self, final Object expectedSelf) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   800
        // 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
   801
        return appliedFnCondition && self == expectedSelf;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   802
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   803
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   804
    @SuppressWarnings("unused")
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   805
    private static Object[] addZerothElement(final Object[] args, final Object value) {
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   806
        // extends input array with by adding new zeroth element
24721
81f70e23cd3b 8036127: Prototype filter needs to be applied to getter guard as well, not just getter
lagergren
parents: 24720
diff changeset
   807
        final Object[] src = args == null? ScriptRuntime.EMPTY_ARRAY : args;
18868
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   808
        final Object[] result = new Object[src.length + 1];
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   809
        System.arraycopy(src, 0, result, 1, src.length);
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   810
        result[0] = value;
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   811
        return result;
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   812
    }
f5359cad148c 8012191: noSuchProperty can't cope with vararg functions
sundar
parents: 18614
diff changeset
   813
20946
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   814
    @SuppressWarnings("unused")
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   815
    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
   816
            throws Throwable {
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   817
        final Object syncObj = sync == UNDEFINED ? self : sync;
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   818
        synchronized (syncObj) {
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   819
            return func.invoke(self, args);
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   820
        }
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   821
    }
bd3d6e87ec6b 8026367: Add a sync keyword to mozilla_compat
hannesw
parents: 20932
diff changeset
   822
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   823
    private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   824
        return MH.findStatic(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types));
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   825
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   826
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   827
    private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   828
        return MH.findVirtual(MethodHandles.lookup(), ScriptFunction.class, name, MH.type(rtype, types));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   829
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   830
}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   831