nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
author hannesw
Wed, 10 Sep 2014 15:19:26 +0200
changeset 26508 b40ef4386b01
parent 25865 d38d876f1654
child 26768 751b0f427090
permissions -rw-r--r--
8057021: UserAccessorProperty guards fail with multiple globals Reviewed-by: attila, lagergren
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime.linker;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
16277
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents: 16234
diff changeset
    28
import static jdk.nashorn.internal.lookup.Lookup.MH;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    30
import java.lang.invoke.MethodHandle;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import java.lang.invoke.MethodType;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16207
diff changeset
    32
import jdk.internal.dynalink.CallSiteDescriptor;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16207
diff changeset
    33
import jdk.internal.dynalink.linker.GuardedInvocation;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16207
diff changeset
    34
import jdk.internal.dynalink.linker.LinkRequest;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16207
diff changeset
    35
import jdk.internal.dynalink.support.Guards;
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    36
import jdk.nashorn.internal.runtime.FindProperty;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import jdk.nashorn.internal.runtime.ScriptObject;
26508
b40ef4386b01 8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents: 25865
diff changeset
    38
import jdk.nashorn.internal.runtime.UserAccessorProperty;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    39
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
 * Implements lookup of methods to link for dynamic operations on JavaScript primitive values (booleans, strings, and
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
 * numbers). This class is only public so it can be accessed by classes in the {@code jdk.nashorn.internal.objects}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
 * package.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
 */
19105
a01ba9d17eab 8021571: @fork tests should use VM options passed from project.properties
sundar
parents: 16534
diff changeset
    45
public final class PrimitiveLookup {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    47
    private PrimitiveLookup() {
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
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
     * Returns a guarded invocation representing the linkage for a dynamic operation on a primitive Java value.
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16186
diff changeset
    52
     * @param request the link request for the dynamic call site.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
     * @param receiverClass the class of the receiver value (e.g., {@link java.lang.Boolean}, {@link java.lang.String} etc.)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
     * @param wrappedReceiver a transient JavaScript native wrapper object created as the object proxy for the primitive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
     * value; see ECMAScript 5.1, section 8.7.1 for discussion of using {@code [[Get]]} on a property reference with a
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
     * primitive base value. This instance will be used to delegate actual lookup.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
     * @param wrapFilter A method handle that takes a primitive value of type specified in the {@code receiverClass} and
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
     * creates a transient native wrapper of the same type as {@code wrappedReceiver} for subsequent invocations of the
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
     * method - it will be combined into the returned invocation as an argument filter on the receiver.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    60
     * @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
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: 23372
diff changeset
    61
     * @param protoFilter A method handle that walks up the proto chain of this receiver object
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
     * type {@code receiverClass}.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
     */
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16186
diff changeset
    64
    public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    65
                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    66
                                                    final MethodHandle protoFilter) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    67
        return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter, protoFilter);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
     * Returns a guarded invocation representing the linkage for a dynamic operation on a primitive Java value.
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16186
diff changeset
    72
     * @param request the link request for the dynamic call site.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
     * @param guard an explicit guard that will be used for the returned guarded invocation.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
     * @param wrappedReceiver a transient JavaScript native wrapper object created as the object proxy for the primitive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
     * value; see ECMAScript 5.1, section 8.7.1 for discussion of using {@code [[Get]]} on a property reference with a
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
     * primitive base value. This instance will be used to delegate actual lookup.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
     * @param wrapFilter A method handle that takes a primitive value of type guarded by the {@code guard} and
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
     * creates a transient native wrapper of the same type as {@code wrappedReceiver} for subsequent invocations of the
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
     * method - it will be combined into the returned invocation as an argument filter on the receiver.
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: 23372
diff changeset
    80
     * @param protoFilter A method handle that walks up the proto chain of this receiver object
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
     * @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
     * type (that is implied by both {@code guard} and {@code wrappedReceiver}).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
     */
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16186
diff changeset
    84
    public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    85
                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    86
                                                    final MethodHandle protoFilter) {
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16186
diff changeset
    87
        final CallSiteDescriptor desc = request.getCallSiteDescriptor();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    88
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
        if(desc.getNameTokenCount() > 2) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
            final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    91
            final FindProperty find = wrappedReceiver.findProperty(name, true);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    92
            if(find == null) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
                // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    94
                return null;
26508
b40ef4386b01 8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents: 25865
diff changeset
    95
            } else if (find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    96
                // If property is found in the prototype object bind the method handle directly to
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    97
                // the proto filter instead of going through wrapper instantiation below.
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    98
                final ScriptObject proto = wrappedReceiver.getProto();
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
    99
                final GuardedInvocation link = proto.lookup(desc, request);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
   100
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
   101
                if (link != null) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
   102
                    final MethodHandle invocation = link.getInvocation();
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
   103
                    final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class));
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
   104
                    final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
   105
                    final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
   106
                    return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard));
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 19105
diff changeset
   107
                }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
        }
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16186
diff changeset
   110
        final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   111
        if (link != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   112
            MethodHandle method = link.getInvocation();
16186
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16151
diff changeset
   113
            final Class<?> receiverType = method.type().parameterType(0);
16207
ed4aec2d599c 8007060: Primitive wrap filter throws ClassCastException in test262parallel
hannesw
parents: 16195
diff changeset
   114
            if (receiverType != Object.class) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
                final MethodType wrapType = wrapFilter.type();
16186
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16151
diff changeset
   116
                assert receiverType.isAssignableFrom(wrapType.returnType());
91bd9d2aa2f5 8006570: This-value for non-strict functions should be converted to object
hannesw
parents: 16151
diff changeset
   117
                method = MH.filterArguments(method, 0, MH.asType(wrapFilter, wrapType.changeReturnType(receiverType)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
            }
24738
be2026c9717c 8039746: Transform applies to calls wherever possible, for ScriptFunctions and JSObjects.
lagergren
parents: 24731
diff changeset
   119
            return new GuardedInvocation(method, guard, link.getSwitchPoints(), null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   121
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
}