author | hannesw |
Wed, 10 Sep 2014 15:19:26 +0200 | |
changeset 26508 | b40ef4386b01 |
parent 25865 | d38d876f1654 |
child 26768 | 751b0f427090 |
permissions | -rw-r--r-- |
16147 | 1 |
/* |
16151 | 2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
16147 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package jdk.nashorn.internal.runtime.linker; |
|
27 |
||
16277 | 28 |
import static jdk.nashorn.internal.lookup.Lookup.MH; |
16147 | 29 |
|
30 |
import java.lang.invoke.MethodHandle; |
|
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 | 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 | 39 |
|
40 |
/** |
|
41 |
* Implements lookup of methods to link for dynamic operations on JavaScript primitive values (booleans, strings, and |
|
42 |
* numbers). This class is only public so it can be accessed by classes in the {@code jdk.nashorn.internal.objects} |
|
43 |
* package. |
|
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 | 46 |
|
47 |
private PrimitiveLookup() { |
|
48 |
} |
|
49 |
||
50 |
/** |
|
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 | 53 |
* @param receiverClass the class of the receiver value (e.g., {@link java.lang.Boolean}, {@link java.lang.String} etc.) |
54 |
* @param wrappedReceiver a transient JavaScript native wrapper object created as the object proxy for the primitive |
|
55 |
* value; see ECMAScript 5.1, section 8.7.1 for discussion of using {@code [[Get]]} on a property reference with a |
|
56 |
* primitive base value. This instance will be used to delegate actual lookup. |
|
57 |
* @param wrapFilter A method handle that takes a primitive value of type specified in the {@code receiverClass} and |
|
58 |
* creates a transient native wrapper of the same type as {@code wrappedReceiver} for subsequent invocations of the |
|
59 |
* method - it will be combined into the returned invocation as an argument filter on the receiver. |
|
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 | 62 |
* type {@code receiverClass}. |
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 | 68 |
} |
69 |
||
70 |
/** |
|
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 | 73 |
* @param guard an explicit guard that will be used for the returned guarded invocation. |
74 |
* @param wrappedReceiver a transient JavaScript native wrapper object created as the object proxy for the primitive |
|
75 |
* value; see ECMAScript 5.1, section 8.7.1 for discussion of using {@code [[Get]]} on a property reference with a |
|
76 |
* primitive base value. This instance will be used to delegate actual lookup. |
|
77 |
* @param wrapFilter A method handle that takes a primitive value of type guarded by the {@code guard} and |
|
78 |
* creates a transient native wrapper of the same type as {@code wrappedReceiver} for subsequent invocations of the |
|
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 | 81 |
* @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive |
82 |
* type (that is implied by both {@code guard} and {@code wrappedReceiver}). |
|
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 | 88 |
|
89 |
if(desc.getNameTokenCount() > 2) { |
|
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 | 93 |
// Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it. |
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 | 108 |
} |
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 | 111 |
if (link != null) { |
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 | 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 | 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 | 120 |
} |
121 |
return null; |
|
122 |
} |
|
123 |
} |