src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
Print this page
rev 758 : 8021350: Share script classes between threads/globals within context
Reviewed-by: lagergren, sundar
*** 33,42 ****
--- 33,43 ----
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
import jdk.internal.dynalink.support.Guards;
import jdk.nashorn.internal.lookup.Lookup;
+ import jdk.nashorn.internal.runtime.FindProperty;
import jdk.nashorn.internal.runtime.ScriptObject;
/**
* Implements lookup of methods to link for dynamic operations on JavaScript primitive values (booleans, strings, and
* numbers). This class is only public so it can be accessed by classes in the {@code jdk.nashorn.internal.objects}
*** 59,70 ****
* method - it will be combined into the returned invocation as an argument filter on the receiver.
* @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
* type {@code receiverClass}.
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
! final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
! return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter);
}
/**
* Returns a guarded invocation representing the linkage for a dynamic operation on a primitive Java value.
* @param request the link request for the dynamic call site.
--- 60,72 ----
* method - it will be combined into the returned invocation as an argument filter on the receiver.
* @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
* type {@code receiverClass}.
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
! final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
! final MethodHandle protoFilter) {
! return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter, protoFilter);
}
/**
* Returns a guarded invocation representing the linkage for a dynamic operation on a primitive Java value.
* @param request the link request for the dynamic call site.
*** 77,87 ****
* method - it will be combined into the returned invocation as an argument filter on the receiver.
* @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
* type (that is implied by both {@code guard} and {@code wrappedReceiver}).
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
! final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
final CallSiteDescriptor desc = request.getCallSiteDescriptor();
final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
if ("setProp".equals(operator) || "setElem".equals(operator)) {
MethodType type = desc.getMethodType();
MethodHandle method = MH.asType(Lookup.EMPTY_SETTER, MH.type(void.class, Object.class, type.parameterType(1)));
--- 79,90 ----
* method - it will be combined into the returned invocation as an argument filter on the receiver.
* @return a guarded invocation representing the operation at the call site when performed on a JavaScript primitive
* type (that is implied by both {@code guard} and {@code wrappedReceiver}).
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
! final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
! final MethodHandle protoFilter) {
final CallSiteDescriptor desc = request.getCallSiteDescriptor();
final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
if ("setProp".equals(operator) || "setElem".equals(operator)) {
MethodType type = desc.getMethodType();
MethodHandle method = MH.asType(Lookup.EMPTY_SETTER, MH.type(void.class, Object.class, type.parameterType(1)));
*** 91,103 ****
return new GuardedInvocation(method, guard);
}
if(desc.getNameTokenCount() > 2) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
! if(wrappedReceiver.findProperty(name, true) == null) {
// Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
return null;
}
}
final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
if (link != null) {
MethodHandle method = link.getInvocation();
--- 94,120 ----
return new GuardedInvocation(method, guard);
}
if(desc.getNameTokenCount() > 2) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
! final FindProperty find = wrappedReceiver.findProperty(name, true);
! if(find == null) {
// Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
return null;
+ } else if (find.isInherited() && !find.getProperty().hasGetterFunction(find.getOwner())) {
+ // If property is found in the prototype object bind the method handle directly to
+ // the proto filter instead of going through wrapper instantiation below.
+ final ScriptObject proto = wrappedReceiver.getProto();
+ final GuardedInvocation link = proto.lookup(desc, request);
+
+ if (link != null) {
+ final MethodHandle invocation = link.getInvocation();
+ final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class));
+ final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter);
+ final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter);
+ return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard));
+ }
}
}
final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
if (link != null) {
MethodHandle method = link.getInvocation();