Merge
This commit is contained in:
commit
b5c0480f54
@ -87,7 +87,6 @@ import java.lang.invoke.MethodHandles.Lookup;
|
|||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
|
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An immutable descriptor of a call site. It is an immutable object that contains all the information about a call
|
* An immutable descriptor of a call site. It is an immutable object that contains all the information about a call
|
||||||
* site: the class performing the lookups, the name of the method being invoked, and the method signature. The library
|
* site: the class performing the lookups, the name of the method being invoked, and the method signature. The library
|
||||||
|
@ -92,7 +92,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
import jdk.internal.dynalink.support.AbstractRelinkableCallSite;
|
import jdk.internal.dynalink.support.AbstractRelinkableCallSite;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A relinkable call site that maintains a chain of linked method handles. In the default implementation, up to 8 method
|
* A relinkable call site that maintains a chain of linked method handles. In the default implementation, up to 8 method
|
||||||
* handles can be chained, cascading from one to the other through
|
* handles can be chained, cascading from one to the other through
|
||||||
|
@ -88,7 +88,6 @@ import java.lang.invoke.MethodHandles;
|
|||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
|
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenience default bootstrapper that exposes static bootstrap methods which language runtimes that need the very
|
* A convenience default bootstrapper that exposes static bootstrap methods which language runtimes that need the very
|
||||||
* default behavior can use with minimal setup. When first referenced, it will create a dynamic linker with default
|
* default behavior can use with minimal setup. When first referenced, it will create a dynamic linker with default
|
||||||
|
@ -97,7 +97,6 @@ import jdk.internal.dynalink.support.LinkRequestImpl;
|
|||||||
import jdk.internal.dynalink.support.Lookup;
|
import jdk.internal.dynalink.support.Lookup;
|
||||||
import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
|
import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The linker for {@link RelinkableCallSite} objects. Users of it (scripting frameworks and language runtimes) have to
|
* The linker for {@link RelinkableCallSite} objects. Users of it (scripting frameworks and language runtimes) have to
|
||||||
* create a linker using the {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic bootstrap
|
* create a linker using the {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic bootstrap
|
||||||
@ -246,14 +245,15 @@ public class DynamicLinker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unstableDetectionEnabled && relinkCount <= unstableRelinkThreshold && relinkCount++ == unstableRelinkThreshold) {
|
int newRelinkCount = relinkCount;
|
||||||
// Note that we'll increase the relinkCount until threshold+1 and not increase it beyond that. Threshold+1
|
// Note that the short-circuited "&&" evaluation below ensures we'll increment the relinkCount until
|
||||||
// is treated as a special value to signal that resetAndRelink has already executed once for the unstable
|
// threshold + 1 but not beyond that. Threshold + 1 is treated as a special value to signal that resetAndRelink
|
||||||
// call site; we only want the call site to throw away its current linkage once, when it transitions to
|
// has already executed once for the unstable call site; we only want the call site to throw away its current
|
||||||
// unstable.
|
// linkage once, when it transitions to unstable.
|
||||||
callSite.resetAndRelink(guardedInvocation, createRelinkAndInvokeMethod(callSite, relinkCount));
|
if(unstableDetectionEnabled && newRelinkCount <= unstableRelinkThreshold && newRelinkCount++ == unstableRelinkThreshold) {
|
||||||
|
callSite.resetAndRelink(guardedInvocation, createRelinkAndInvokeMethod(callSite, newRelinkCount));
|
||||||
} else {
|
} else {
|
||||||
callSite.relink(guardedInvocation, createRelinkAndInvokeMethod(callSite, relinkCount));
|
callSite.relink(guardedInvocation, createRelinkAndInvokeMethod(callSite, newRelinkCount));
|
||||||
}
|
}
|
||||||
if(syncOnRelink) {
|
if(syncOnRelink) {
|
||||||
MutableCallSite.syncAll(new MutableCallSite[] { (MutableCallSite)callSite });
|
MutableCallSite.syncAll(new MutableCallSite[] { (MutableCallSite)callSite });
|
||||||
|
@ -102,7 +102,6 @@ import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker;
|
|||||||
import jdk.internal.dynalink.support.LinkerServicesImpl;
|
import jdk.internal.dynalink.support.LinkerServicesImpl;
|
||||||
import jdk.internal.dynalink.support.TypeConverterFactory;
|
import jdk.internal.dynalink.support.TypeConverterFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory class for creating {@link DynamicLinker}s. The most usual dynamic linker is a linker that is a composition
|
* A factory class for creating {@link DynamicLinker}s. The most usual dynamic linker is a linker that is a composition
|
||||||
* of all {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any
|
* of all {@link GuardingDynamicLinker}s known and pre-created by the caller as well as any
|
||||||
@ -256,13 +255,15 @@ public class DynamicLinkerFactory {
|
|||||||
|
|
||||||
// Gather classes of all precreated (prioritized and fallback) linkers.
|
// Gather classes of all precreated (prioritized and fallback) linkers.
|
||||||
// We'll filter out any discovered linkers of the same class.
|
// We'll filter out any discovered linkers of the same class.
|
||||||
final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses = new HashSet<>();
|
final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses =
|
||||||
|
new HashSet<>();
|
||||||
addClasses(knownLinkerClasses, prioritizedLinkers);
|
addClasses(knownLinkerClasses, prioritizedLinkers);
|
||||||
addClasses(knownLinkerClasses, fallbackLinkers);
|
addClasses(knownLinkerClasses, fallbackLinkers);
|
||||||
|
|
||||||
final List<GuardingDynamicLinker> discovered = AutoDiscovery.loadLinkers(classLoader);
|
final List<GuardingDynamicLinker> discovered = AutoDiscovery.loadLinkers(classLoader);
|
||||||
// Now, concatenate ...
|
// Now, concatenate ...
|
||||||
final List<GuardingDynamicLinker> linkers = new ArrayList<>(prioritizedLinkers.size() + discovered.size()
|
final List<GuardingDynamicLinker> linkers =
|
||||||
|
new ArrayList<>(prioritizedLinkers.size() + discovered.size()
|
||||||
+ fallbackLinkers.size());
|
+ fallbackLinkers.size());
|
||||||
// ... prioritized linkers, ...
|
// ... prioritized linkers, ...
|
||||||
linkers.addAll(prioritizedLinkers);
|
linkers.addAll(prioritizedLinkers);
|
||||||
|
@ -87,7 +87,6 @@ import java.lang.invoke.MethodHandle;
|
|||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
import jdk.internal.dynalink.support.AbstractRelinkableCallSite;
|
import jdk.internal.dynalink.support.AbstractRelinkableCallSite;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A relinkable call site that implements monomorphic inline caching strategy. After it linked a method, it will keep it
|
* A relinkable call site that implements monomorphic inline caching strategy. After it linked a method, it will keep it
|
||||||
* until either its guard evaluates to false, or its switchpoint is invalidated, at which time it will throw away the
|
* until either its guard evaluates to false, or its switchpoint is invalidated, at which time it will throw away the
|
||||||
|
@ -89,7 +89,6 @@ import java.lang.invoke.MutableCallSite;
|
|||||||
import java.lang.invoke.VolatileCallSite;
|
import java.lang.invoke.VolatileCallSite;
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for relinkable call sites. Language runtimes wishing to use this framework must use subclasses of
|
* Interface for relinkable call sites. Language runtimes wishing to use this framework must use subclasses of
|
||||||
* {@link CallSite} that also implement this interface as their call sites. There is a readily usable
|
* {@link CallSite} that also implement this interface as their call sites. There is a readily usable
|
||||||
|
@ -103,7 +103,6 @@ import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
|
|||||||
import jdk.internal.dynalink.support.Guards;
|
import jdk.internal.dynalink.support.Guards;
|
||||||
import jdk.internal.dynalink.support.Lookup;
|
import jdk.internal.dynalink.support.Lookup;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for both {@link StaticClassLinker} and {@link BeanLinker}. Deals with common aspects of property
|
* A base class for both {@link StaticClassLinker} and {@link BeanLinker}. Deals with common aspects of property
|
||||||
* exposure and method calls for both static and instance facets of a class.
|
* exposure and method calls for both static and instance facets of a class.
|
||||||
@ -128,7 +127,6 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
|||||||
this.assignableGuard = assignableGuard;
|
this.assignableGuard = assignableGuard;
|
||||||
|
|
||||||
final FacetIntrospector introspector = createFacetIntrospector();
|
final FacetIntrospector introspector = createFacetIntrospector();
|
||||||
try {
|
|
||||||
// Add methods and properties
|
// Add methods and properties
|
||||||
for(Method method: introspector.getMethods()) {
|
for(Method method: introspector.getMethods()) {
|
||||||
final String name = method.getName();
|
final String name = method.getName();
|
||||||
@ -170,9 +168,6 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
|||||||
setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS);
|
setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
introspector.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract FacetIntrospector createFacetIntrospector();
|
abstract FacetIntrospector createFacetIntrospector();
|
||||||
@ -394,10 +389,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
|||||||
IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
|
IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
|
||||||
if(nextComponent == null) {
|
if(nextComponent == null) {
|
||||||
return getClassGuardedInvocationComponent(compositeSetter, type);
|
return getClassGuardedInvocationComponent(compositeSetter, type);
|
||||||
} else {
|
|
||||||
return nextComponent.compose(compositeSetter, getClassGuard(type), clazz,
|
|
||||||
ValidationType.EXACT_CLASS);
|
|
||||||
}
|
}
|
||||||
|
return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
// Must have two arguments: target object and property value
|
// Must have two arguments: target object and property value
|
||||||
@ -474,10 +467,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
|||||||
IS_ANNOTATED_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
|
IS_ANNOTATED_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
|
||||||
if(nextComponent == null) {
|
if(nextComponent == null) {
|
||||||
return getClassGuardedInvocationComponent(compositeGetter, type);
|
return getClassGuardedInvocationComponent(compositeGetter, type);
|
||||||
} else {
|
|
||||||
return nextComponent.compose(compositeGetter, getClassGuard(type), clazz,
|
|
||||||
ValidationType.EXACT_CLASS);
|
|
||||||
}
|
}
|
||||||
|
return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
// Must have exactly one argument: receiver
|
// Must have exactly one argument: receiver
|
||||||
@ -521,9 +512,11 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
|||||||
case NONE: {
|
case NONE: {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
default: {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final MethodHandle IS_DYNAMIC_METHOD_NOT_NULL = Guards.asType(Guards.isNotNull(),
|
private static final MethodHandle IS_DYNAMIC_METHOD_NOT_NULL = Guards.asType(Guards.isNotNull(),
|
||||||
MethodType.methodType(boolean.class, DynamicMethod.class));
|
MethodType.methodType(boolean.class, DynamicMethod.class));
|
||||||
@ -541,12 +534,12 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
|||||||
if(nextComponent == null) {
|
if(nextComponent == null) {
|
||||||
// No next component operation; just return a component for this operation.
|
// No next component operation; just return a component for this operation.
|
||||||
return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type);
|
return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
// What's below is basically:
|
// What's below is basically:
|
||||||
// foldArguments(guardWithTest(isNotNull, identity, nextComponent.invocation), getter)
|
// foldArguments(guardWithTest(isNotNull, identity, nextComponent.invocation), getter) only with a
|
||||||
// only with a bunch of method signature adjustments. Basically, execute method getter; if
|
// bunch of method signature adjustments. Basically, execute method getter; if it returns a non-null
|
||||||
// it returns a non-null DynamicMethod, use identity to return it, otherwise delegate to
|
// DynamicMethod, use identity to return it, otherwise delegate to nextComponent's invocation.
|
||||||
// nextComponent's invocation.
|
|
||||||
|
|
||||||
final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type.changeReturnType(
|
final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type.changeReturnType(
|
||||||
DynamicMethod.class));
|
DynamicMethod.class));
|
||||||
@ -564,9 +557,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
|||||||
final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
|
final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
|
||||||
IS_DYNAMIC_METHOD_NOT_NULL, returnMethodHandle, nextCombinedInvocation), typedGetter);
|
IS_DYNAMIC_METHOD_NOT_NULL, returnMethodHandle, nextCombinedInvocation), typedGetter);
|
||||||
|
|
||||||
return nextComponent.compose(compositeGetter, getClassGuard(type), clazz,
|
return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
|
||||||
ValidationType.EXACT_CLASS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
// Must have exactly one argument: receiver
|
// Must have exactly one argument: receiver
|
||||||
@ -638,7 +629,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
|||||||
* @return the dynamic method (either {@link SimpleDynamicMethod} or {@link OverloadedDynamicMethod}, or null if the
|
* @return the dynamic method (either {@link SimpleDynamicMethod} or {@link OverloadedDynamicMethod}, or null if the
|
||||||
* method with the specified name does not exist.
|
* method with the specified name does not exist.
|
||||||
*/
|
*/
|
||||||
public DynamicMethod getDynamicMethod(String name) {
|
DynamicMethod getDynamicMethod(String name) {
|
||||||
return getDynamicMethod(name, methods);
|
return getDynamicMethod(name, methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,6 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import jdk.internal.dynalink.support.TypeUtilities;
|
import jdk.internal.dynalink.support.TypeUtilities;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents overloaded methods applicable to a specific call site signature.
|
* Represents overloaded methods applicable to a specific call site signature.
|
||||||
*
|
*
|
||||||
|
@ -99,7 +99,6 @@ import jdk.internal.dynalink.support.Guards;
|
|||||||
import jdk.internal.dynalink.support.Lookup;
|
import jdk.internal.dynalink.support.Lookup;
|
||||||
import jdk.internal.dynalink.support.TypeUtilities;
|
import jdk.internal.dynalink.support.TypeUtilities;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that provides linking capabilities for a single POJO class. Normally not used directly, but managed by
|
* A class that provides linking capabilities for a single POJO class. Normally not used directly, but managed by
|
||||||
* {@link BeansLinker}.
|
* {@link BeansLinker}.
|
||||||
@ -176,7 +175,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
|||||||
// dealing with an array, or a list or map, but hey...
|
// dealing with an array, or a list or map, but hey...
|
||||||
// Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
|
// Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
|
||||||
// in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
|
// in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
|
||||||
final GuardedInvocationComponent gic;;
|
final GuardedInvocationComponent gic;
|
||||||
final boolean isMap;
|
final boolean isMap;
|
||||||
if(declaredType.isArray()) {
|
if(declaredType.isArray()) {
|
||||||
gic = new GuardedInvocationComponent(MethodHandles.arrayElementGetter(declaredType));
|
gic = new GuardedInvocationComponent(MethodHandles.arrayElementGetter(declaredType));
|
||||||
@ -223,7 +222,8 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
|||||||
|
|
||||||
if(nextComponent == null) {
|
if(nextComponent == null) {
|
||||||
return gic.replaceInvocation(binder.bind(invocation));
|
return gic.replaceInvocation(binder.bind(invocation));
|
||||||
} else {
|
}
|
||||||
|
|
||||||
final MethodHandle checkGuard;
|
final MethodHandle checkGuard;
|
||||||
if(invocation == GET_LIST_ELEMENT) {
|
if(invocation == GET_LIST_ELEMENT) {
|
||||||
checkGuard = convertArgToInt(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
|
checkGuard = convertArgToInt(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
|
||||||
@ -239,7 +239,6 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
|||||||
binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
|
binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
|
||||||
gic.getValidatorClass(), gic.getValidationType());
|
gic.getValidatorClass(), gic.getValidationType());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static String getFixedKey(final CallSiteDescriptor callSiteDescriptor) {
|
private static String getFixedKey(final CallSiteDescriptor callSiteDescriptor) {
|
||||||
return callSiteDescriptor.getNameTokenCount() == 2 ? null : callSiteDescriptor.getNameToken(
|
return callSiteDescriptor.getNameTokenCount() == 2 ? null : callSiteDescriptor.getNameToken(
|
||||||
@ -435,14 +434,14 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
|||||||
|
|
||||||
if(nextComponent == null) {
|
if(nextComponent == null) {
|
||||||
return gic.replaceInvocation(binder.bind(invocation));
|
return gic.replaceInvocation(binder.bind(invocation));
|
||||||
} else {
|
}
|
||||||
|
|
||||||
final MethodHandle checkGuard = convertArgToInt(invocation == SET_LIST_ELEMENT ? RANGE_CHECK_LIST :
|
final MethodHandle checkGuard = convertArgToInt(invocation == SET_LIST_ELEMENT ? RANGE_CHECK_LIST :
|
||||||
RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
|
RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
|
||||||
return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard),
|
return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard),
|
||||||
binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
|
binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
|
||||||
gic.getValidatorClass(), gic.getValidationType());
|
gic.getValidatorClass(), gic.getValidationType());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static MethodHandle GET_ARRAY_LENGTH = Lookup.PUBLIC.findStatic(Array.class, "getLength",
|
private static MethodHandle GET_ARRAY_LENGTH = Lookup.PUBLIC.findStatic(Array.class, "getLength",
|
||||||
MethodType.methodType(int.class, Object.class));
|
MethodType.methodType(int.class, Object.class));
|
||||||
|
@ -93,7 +93,6 @@ import jdk.internal.dynalink.linker.LinkRequest;
|
|||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A linker for POJOs. Normally used as the ultimate fallback linker by the {@link DynamicLinkerFactory} so it is given
|
* A linker for POJOs. Normally used as the ultimate fallback linker by the {@link DynamicLinkerFactory} so it is given
|
||||||
* the chance to link calls to all objects that no other language runtime recognizes. Specifically, this linker will:
|
* the chance to link calls to all objects that no other language runtime recognizes. Specifically, this linker will:
|
||||||
@ -160,6 +159,16 @@ public class BeansLinker implements GuardingDynamicLinker {
|
|||||||
return linkers.get(clazz);
|
return linkers.get(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if the object is a Dynalink Java dynamic method.
|
||||||
|
*
|
||||||
|
* @param obj the object we want to test for being a dynamic method
|
||||||
|
* @return true if it is a dynamic method, false otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean isDynamicMethod(final Object obj) {
|
||||||
|
return obj instanceof DynamicMethod;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices)
|
public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
@ -222,14 +222,14 @@ class CheckRestrictedPackageInternal {
|
|||||||
resolveClass(clazz);
|
resolveClass(clazz);
|
||||||
}
|
}
|
||||||
return clazz;
|
return clazz;
|
||||||
} else {
|
|
||||||
return super.loadClass(name, resolve);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return super.loadClass(name, resolve);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] getTesterClassBytes() {
|
static byte[] getTesterClassBytes() {
|
||||||
try {
|
try {
|
||||||
final InputStream in = CheckRestrictedPackage.class.getResourceAsStream("RestrictedPackageTester.class");
|
final InputStream in = CheckRestrictedPackage.class.getResourceAsStream("RestrictedPackageTester.class");
|
||||||
try {
|
try {
|
||||||
|
@ -89,7 +89,6 @@ import java.lang.invoke.MethodType;
|
|||||||
import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
|
import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
|
||||||
import jdk.internal.dynalink.support.Lookup;
|
import jdk.internal.dynalink.support.Lookup;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A linker for java.lang.Class objects. Provides a synthetic property "static" that allows access to static fields and
|
* A linker for java.lang.Class objects. Provides a synthetic property "static" that allows access to static fields and
|
||||||
* methods on the class (respecting property getter/setter conventions). Note that Class objects are not recognized by
|
* methods on the class (respecting property getter/setter conventions). Note that Class objects are not recognized by
|
||||||
|
@ -91,7 +91,6 @@ import jdk.internal.dynalink.linker.LinkerServices;
|
|||||||
import jdk.internal.dynalink.support.Guards;
|
import jdk.internal.dynalink.support.Guards;
|
||||||
import jdk.internal.dynalink.support.TypeUtilities;
|
import jdk.internal.dynalink.support.TypeUtilities;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Attila Szegedi
|
* @author Attila Szegedi
|
||||||
|
@ -88,7 +88,6 @@ import java.lang.invoke.MethodType;
|
|||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a single dynamic method. A "dynamic" method can be bound to a single Java method, or can be bound to all
|
* Represents a single dynamic method. A "dynamic" method can be bound to a single Java method, or can be bound to all
|
||||||
* overloaded methods of the same name on a class. Getting an invocation of a dynamic method bound to multiple
|
* overloaded methods of the same name on a class. Getting an invocation of a dynamic method bound to multiple
|
||||||
|
@ -93,7 +93,6 @@ import jdk.internal.dynalink.linker.LinkerServices;
|
|||||||
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||||
import jdk.internal.dynalink.support.Guards;
|
import jdk.internal.dynalink.support.Guards;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple linker that implements the "dyn:call" operation for {@link DynamicMethod} objects - the objects returned by
|
* Simple linker that implements the "dyn:call" operation for {@link DynamicMethod} objects - the objects returned by
|
||||||
* "dyn:getMethod" from {@link AbstractJavaLinker}.
|
* "dyn:getMethod" from {@link AbstractJavaLinker}.
|
||||||
@ -102,7 +101,7 @@ class DynamicMethodLinker implements TypeBasedGuardingDynamicLinker {
|
|||||||
@Override
|
@Override
|
||||||
public boolean canLinkType(Class<?> type) {
|
public boolean canLinkType(Class<?> type) {
|
||||||
return DynamicMethod.class.isAssignableFrom(type);
|
return DynamicMethod.class.isAssignableFrom(type);
|
||||||
};
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) {
|
public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) {
|
||||||
|
@ -94,13 +94,12 @@ import java.util.Collections;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import jdk.internal.dynalink.support.Lookup;
|
import jdk.internal.dynalink.support.Lookup;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base for classes that expose class field and method information to an {@link AbstractJavaLinker}. There are
|
* Base for classes that expose class field and method information to an {@link AbstractJavaLinker}. There are
|
||||||
* subclasses for instance (bean) and static facet of a class.
|
* subclasses for instance (bean) and static facet of a class.
|
||||||
* @author Attila Szegedi
|
* @author Attila Szegedi
|
||||||
*/
|
*/
|
||||||
abstract class FacetIntrospector implements AutoCloseable {
|
abstract class FacetIntrospector {
|
||||||
private final Class<?> clazz;
|
private final Class<?> clazz;
|
||||||
private final boolean instance;
|
private final boolean instance;
|
||||||
private final boolean isRestricted;
|
private final boolean isRestricted;
|
||||||
@ -181,8 +180,4 @@ abstract class FacetIntrospector implements AutoCloseable {
|
|||||||
* @return the edited method handle.
|
* @return the edited method handle.
|
||||||
*/
|
*/
|
||||||
abstract MethodHandle editMethodHandle(MethodHandle mh);
|
abstract MethodHandle editMethodHandle(MethodHandle mh);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -86,7 +86,6 @@ package jdk.internal.dynalink.beans;
|
|||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents one component for a GuardedInvocation of a potentially composite operation of an
|
* Represents one component for a GuardedInvocation of a potentially composite operation of an
|
||||||
* {@link AbstractJavaLinker}. In addition to holding a guarded invocation, it holds semantic information about its
|
* {@link AbstractJavaLinker}. In addition to holding a guarded invocation, it holds semantic information about its
|
||||||
@ -196,8 +195,8 @@ class GuardedInvocationComponent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NONE:
|
default:
|
||||||
throw new AssertionError(); // Not possible
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXACT_CLASS:
|
case EXACT_CLASS:
|
||||||
@ -217,8 +216,8 @@ class GuardedInvocationComponent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NONE:
|
default:
|
||||||
throw new AssertionError(); // Not possible
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IS_ARRAY:
|
case IS_ARRAY:
|
||||||
@ -231,10 +230,12 @@ class GuardedInvocationComponent {
|
|||||||
break;
|
break;
|
||||||
case IS_ARRAY:
|
case IS_ARRAY:
|
||||||
return this;
|
return this;
|
||||||
case NONE:
|
default:
|
||||||
throw new AssertionError(); // Not possible
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
throw new AssertionError("Incompatible composition " + this + " vs " + other);
|
throw new AssertionError("Incompatible composition " + this + " vs " + other);
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,6 @@ import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
|
|||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
import jdk.internal.dynalink.support.TypeUtilities;
|
import jdk.internal.dynalink.support.TypeUtilities;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class that encapsulates the algorithm for choosing the maximally specific methods.
|
* Utility class that encapsulates the algorithm for choosing the maximally specific methods.
|
||||||
*
|
*
|
||||||
@ -141,6 +140,10 @@ class MaximallySpecific {
|
|||||||
}
|
}
|
||||||
case INDETERMINATE: {
|
case INDETERMINATE: {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,6 @@ import jdk.internal.dynalink.beans.ApplicableOverloadedMethods.ApplicabilityTest
|
|||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
import jdk.internal.dynalink.support.TypeUtilities;
|
import jdk.internal.dynalink.support.TypeUtilities;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an overloaded method.
|
* Represents an overloaded method.
|
||||||
*
|
*
|
||||||
@ -204,15 +203,17 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
|||||||
final MethodHandle mh = invokables.iterator().next();
|
final MethodHandle mh = invokables.iterator().next();
|
||||||
return new SimpleDynamicMethod(mh).getInvocation(callSiteType, linkerServices);
|
return new SimpleDynamicMethod(mh).getInvocation(callSiteType, linkerServices);
|
||||||
}
|
}
|
||||||
}
|
default: {
|
||||||
|
// We have more than one candidate. We have no choice but to link to a method that resolves overloads on
|
||||||
// We have more than one candidate. We have no choice but to link to a method that resolves overloads on every
|
// every invocation (alternatively, we could opportunistically link the one method that resolves for the
|
||||||
// invocation (alternatively, we could opportunistically link the one method that resolves for the current
|
// current arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd
|
||||||
// arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd go back all the
|
// go back all the way to candidate selection.
|
||||||
// way to candidate selection.
|
|
||||||
// TODO: cache per call site type
|
// TODO: cache per call site type
|
||||||
return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker();
|
return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(MethodHandle mh) {
|
public boolean contains(MethodHandle mh) {
|
||||||
@ -248,6 +249,8 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
|||||||
final boolean varArgs = m.isVarargsCollector();
|
final boolean varArgs = m.isVarargsCollector();
|
||||||
final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0);
|
final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0);
|
||||||
final int callSiteArgLen = callSiteType.parameterCount();
|
final int callSiteArgLen = callSiteType.parameterCount();
|
||||||
|
|
||||||
|
// Arity checks
|
||||||
if(varArgs) {
|
if(varArgs) {
|
||||||
if(callSiteArgLen < fixedArgLen) {
|
if(callSiteArgLen < fixedArgLen) {
|
||||||
return false;
|
return false;
|
||||||
@ -255,33 +258,37 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
|||||||
} else if(callSiteArgLen != fixedArgLen) {
|
} else if(callSiteArgLen != fixedArgLen) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Starting from 1, as receiver type doesn't participate
|
|
||||||
|
// Fixed arguments type checks, starting from 1, as receiver type doesn't participate
|
||||||
for(int i = 1; i < fixedArgLen; ++i) {
|
for(int i = 1; i < fixedArgLen; ++i) {
|
||||||
if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), methodType.parameterType(i))) {
|
if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), methodType.parameterType(i))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(varArgs) {
|
if(!varArgs) {
|
||||||
|
// Not vararg; both arity and types matched.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
final Class<?> varArgArrayType = methodType.parameterType(fixedArgLen);
|
final Class<?> varArgArrayType = methodType.parameterType(fixedArgLen);
|
||||||
final Class<?> varArgType = varArgArrayType.getComponentType();
|
final Class<?> varArgType = varArgArrayType.getComponentType();
|
||||||
|
|
||||||
if(fixedArgLen == callSiteArgLen - 1) {
|
if(fixedArgLen == callSiteArgLen - 1) {
|
||||||
|
// Exactly one vararg; check both array type matching and array component type matching.
|
||||||
final Class<?> callSiteArgType = callSiteType.parameterType(fixedArgLen);
|
final Class<?> callSiteArgType = callSiteType.parameterType(fixedArgLen);
|
||||||
// Exactly one vararg; check both exact matching and component
|
|
||||||
// matching.
|
|
||||||
return isApplicableDynamically(linkerServices, callSiteArgType, varArgArrayType)
|
return isApplicableDynamically(linkerServices, callSiteArgType, varArgArrayType)
|
||||||
|| isApplicableDynamically(linkerServices, callSiteArgType, varArgType);
|
|| isApplicableDynamically(linkerServices, callSiteArgType, varArgType);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
// Either zero, or more than one vararg; check if all actual vararg types match the vararg array component type.
|
||||||
for(int i = fixedArgLen; i < callSiteArgLen; ++i) {
|
for(int i = fixedArgLen; i < callSiteArgLen; ++i) {
|
||||||
if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), varArgType)) {
|
if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), varArgType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isApplicableDynamically(LinkerServices linkerServices, Class<?> callSiteType,
|
private static boolean isApplicableDynamically(LinkerServices linkerServices, Class<?> callSiteType,
|
||||||
Class<?> methodType) {
|
Class<?> methodType) {
|
||||||
@ -298,7 +305,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
|||||||
*
|
*
|
||||||
* @param method the method to add.
|
* @param method the method to add.
|
||||||
*/
|
*/
|
||||||
public void addMethod(SimpleDynamicMethod method) {
|
void addMethod(SimpleDynamicMethod method) {
|
||||||
addMethod(method.getTarget());
|
addMethod(method.getTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
import jdk.internal.dynalink.support.Lookup;
|
import jdk.internal.dynalink.support.Lookup;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a subset of overloaded methods for a certain method name on a certain class. It can be either a fixarg or
|
* Represents a subset of overloaded methods for a certain method name on a certain class. It can be either a fixarg or
|
||||||
* a vararg subset depending on the subclass. The method is for a fixed number of arguments though (as it is generated
|
* a vararg subset depending on the subclass. The method is for a fixed number of arguments though (as it is generated
|
||||||
|
@ -90,7 +90,6 @@ import java.lang.reflect.Array;
|
|||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
import jdk.internal.dynalink.support.Guards;
|
import jdk.internal.dynalink.support.Guards;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A dynamic method bound to exactly one, non-overloaded Java method. Handles varargs.
|
* A dynamic method bound to exactly one, non-overloaded Java method. Handles varargs.
|
||||||
*
|
*
|
||||||
@ -164,14 +163,13 @@ class SimpleDynamicMethod extends DynamicMethod {
|
|||||||
// Less actual arguments than number of fixed declared arguments; can't invoke.
|
// Less actual arguments than number of fixed declared arguments; can't invoke.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Method handle of the same number of arguments as the call site type
|
// Method handle has the same number of fixed arguments as the call site type
|
||||||
if(argsLen == fixParamsLen) {
|
if(argsLen == fixParamsLen) {
|
||||||
// Method handle that matches the number of actual arguments as the number of fixed arguments
|
// Method handle that matches the number of actual arguments as the number of fixed arguments
|
||||||
final MethodHandle matchedMethod;
|
final MethodHandle matchedMethod;
|
||||||
if(varArgs) {
|
if(varArgs) {
|
||||||
// If vararg, add a zero-length array of the expected type as the last argument to signify no variable
|
// If vararg, add a zero-length array of the expected type as the last argument to signify no variable
|
||||||
// arguments.
|
// arguments.
|
||||||
// TODO: check whether collectArguments() would handle this too.
|
|
||||||
matchedMethod = MethodHandles.insertArguments(fixTarget, fixParamsLen, Array.newInstance(
|
matchedMethod = MethodHandles.insertArguments(fixTarget, fixParamsLen, Array.newInstance(
|
||||||
methodType.parameterType(fixParamsLen).getComponentType(), 0));
|
methodType.parameterType(fixParamsLen).getComponentType(), 0));
|
||||||
} else {
|
} else {
|
||||||
@ -195,23 +193,23 @@ class SimpleDynamicMethod extends DynamicMethod {
|
|||||||
// Call site signature guarantees we'll always be passed a single compatible array; just link directly
|
// Call site signature guarantees we'll always be passed a single compatible array; just link directly
|
||||||
// to the method.
|
// to the method.
|
||||||
return createConvertingInvocation(fixTarget, linkerServices, callSiteType);
|
return createConvertingInvocation(fixTarget, linkerServices, callSiteType);
|
||||||
} else if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) {
|
}
|
||||||
|
if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) {
|
||||||
// Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive);
|
// Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive);
|
||||||
// link immediately to a vararg-packing method handle.
|
// link immediately to a vararg-packing method handle.
|
||||||
return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
|
return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
|
||||||
} else {
|
}
|
||||||
// Call site signature makes no guarantees that the single argument in the vararg position will be
|
// Call site signature makes no guarantees that the single argument in the vararg position will be
|
||||||
// compatible across all invocations. Need to insert an appropriate guard and fall back to generic
|
// compatible across all invocations. Need to insert an appropriate guard and fall back to generic vararg
|
||||||
// vararg method when it is not.
|
// method when it is not.
|
||||||
return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType),
|
return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType),
|
||||||
createConvertingInvocation(fixTarget, linkerServices, callSiteType),
|
createConvertingInvocation(fixTarget, linkerServices, callSiteType),
|
||||||
createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType));
|
createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Remaining case: more than one vararg.
|
// Remaining case: more than one vararg.
|
||||||
return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
|
return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(MethodHandle mh) {
|
public boolean contains(MethodHandle mh) {
|
||||||
|
@ -99,7 +99,6 @@ import jdk.internal.dynalink.linker.LinkerServices;
|
|||||||
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||||
import jdk.internal.dynalink.support.Lookup;
|
import jdk.internal.dynalink.support.Lookup;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a linker for the {@link StaticClass} objects.
|
* Provides a linker for the {@link StaticClass} objects.
|
||||||
* @author Attila Szegedi
|
* @author Attila Szegedi
|
||||||
|
@ -92,7 +92,6 @@ import java.util.List;
|
|||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
import jdk.internal.dynalink.support.Guards;
|
import jdk.internal.dynalink.support.Guards;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a conditionally valid method handle. It is an immutable triple of an invocation method handle, a guard
|
* Represents a conditionally valid method handle. It is an immutable triple of an invocation method handle, a guard
|
||||||
* method handle that defines the applicability of the invocation handle, and a switch point that can be used for
|
* method handle that defines the applicability of the invocation handle, and a switch point that can be used for
|
||||||
|
@ -89,7 +89,6 @@ import java.lang.invoke.MethodType;
|
|||||||
import jdk.internal.dynalink.DynamicLinker;
|
import jdk.internal.dynalink.DynamicLinker;
|
||||||
import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
|
import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for services provided to {@link GuardingDynamicLinker} instances by the {@link DynamicLinker} that owns
|
* Interface for services provided to {@link GuardingDynamicLinker} instances by the {@link DynamicLinker} that owns
|
||||||
* them. You can think of it as the interface of the {@link DynamicLinker} that faces the {@link GuardingDynamicLinker}
|
* them. You can think of it as the interface of the {@link DynamicLinker} that faces the {@link GuardingDynamicLinker}
|
||||||
|
@ -88,7 +88,6 @@ import java.lang.invoke.MethodHandles.Lookup;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for call site descriptor implementations. Provides reconstruction of the name from the tokens, as well
|
* A base class for call site descriptor implementations. Provides reconstruction of the name from the tokens, as well
|
||||||
* as a generally useful {@code equals} and {@code hashCode} methods.
|
* as a generally useful {@code equals} and {@code hashCode} methods.
|
||||||
|
@ -88,7 +88,6 @@ import java.lang.invoke.MutableCallSite;
|
|||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
import jdk.internal.dynalink.RelinkableCallSite;
|
import jdk.internal.dynalink.RelinkableCallSite;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic implementation of the {@link RelinkableCallSite} as a {@link MutableCallSite} subclass.
|
* A basic implementation of the {@link RelinkableCallSite} as a {@link MutableCallSite} subclass.
|
||||||
*
|
*
|
||||||
|
@ -89,7 +89,6 @@ import java.util.ServiceLoader;
|
|||||||
import jdk.internal.dynalink.DynamicLinkerFactory;
|
import jdk.internal.dynalink.DynamicLinkerFactory;
|
||||||
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
|
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides methods for automatic discovery of all guarding dynamic linkers listed in the
|
* Provides methods for automatic discovery of all guarding dynamic linkers listed in the
|
||||||
* <tt>/META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker</tt> resources of all JAR files for a
|
* <tt>/META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker</tt> resources of all JAR files for a
|
||||||
|
@ -94,7 +94,6 @@ import java.util.StringTokenizer;
|
|||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usable as a default factory for call site descriptor implementations. It is weakly canonicalizing, meaning it will
|
* Usable as a default factory for call site descriptor implementations. It is weakly canonicalizing, meaning it will
|
||||||
* return the same immutable call site descriptor for identical inputs, i.e. repeated requests for a descriptor
|
* return the same immutable call site descriptor for identical inputs, i.e. repeated requests for a descriptor
|
||||||
@ -129,9 +128,8 @@ public class CallSiteDescriptorFactory {
|
|||||||
final String[] tokenizedName = tokenizeName(name);
|
final String[] tokenizedName = tokenizeName(name);
|
||||||
if(isPublicLookup(lookup)) {
|
if(isPublicLookup(lookup)) {
|
||||||
return getCanonicalPublicDescriptor(createPublicCallSiteDescriptor(tokenizedName, methodType));
|
return getCanonicalPublicDescriptor(createPublicCallSiteDescriptor(tokenizedName, methodType));
|
||||||
} else {
|
|
||||||
return new LookupCallSiteDescriptor(tokenizedName, methodType, lookup);
|
|
||||||
}
|
}
|
||||||
|
return new LookupCallSiteDescriptor(tokenizedName, methodType, lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CallSiteDescriptor getCanonicalPublicDescriptor(final CallSiteDescriptor desc) {
|
static CallSiteDescriptor getCanonicalPublicDescriptor(final CallSiteDescriptor desc) {
|
||||||
|
@ -91,7 +91,6 @@ import jdk.internal.dynalink.linker.GuardingDynamicLinker;
|
|||||||
import jdk.internal.dynalink.linker.LinkRequest;
|
import jdk.internal.dynalink.linker.LinkRequest;
|
||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link GuardingDynamicLinker} that delegates sequentially to a list of other guarding dynamic linkers. The first
|
* A {@link GuardingDynamicLinker} that delegates sequentially to a list of other guarding dynamic linkers. The first
|
||||||
* value returned from a component linker other than null is returned. If no component linker returns an invocation,
|
* value returned from a component linker other than null is returned. If no component linker returns an invocation,
|
||||||
|
@ -93,7 +93,6 @@ import jdk.internal.dynalink.linker.LinkRequest;
|
|||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A composite type-based guarding dynamic linker. When a receiver of a not yet seen class is encountered, all linkers
|
* A composite type-based guarding dynamic linker. When a receiver of a not yet seen class is encountered, all linkers
|
||||||
* are queried sequentially on their {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers
|
* are queried sequentially on their {@link TypeBasedGuardingDynamicLinker#canLinkType(Class)} method. The linkers
|
||||||
|
@ -87,7 +87,6 @@ import java.lang.invoke.MethodHandles.Lookup;
|
|||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default, fairly light implementation of a call site descriptor used for describing non-standard operations. It does
|
* A default, fairly light implementation of a call site descriptor used for describing non-standard operations. It does
|
||||||
* not store {@link Lookup} objects but always returns the public lookup from its {@link #getLookup()} method. If you
|
* not store {@link Lookup} objects but always returns the public lookup from its {@link #getLookup()} method. If you
|
||||||
|
@ -90,7 +90,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods for creating typical guards. TODO: introduce reasonable caching of created guards.
|
* Utility methods for creating typical guards. TODO: introduce reasonable caching of created guards.
|
||||||
*
|
*
|
||||||
|
@ -91,7 +91,6 @@ import jdk.internal.dynalink.linker.GuardingDynamicLinker;
|
|||||||
import jdk.internal.dynalink.linker.LinkRequest;
|
import jdk.internal.dynalink.linker.LinkRequest;
|
||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the {@link LinkerServices} interface.
|
* Default implementation of the {@link LinkerServices} interface.
|
||||||
*
|
*
|
||||||
|
@ -231,9 +231,8 @@ public class Lookup {
|
|||||||
m.setAccessible(true);
|
m.setAccessible(true);
|
||||||
}
|
}
|
||||||
return unreflect(m);
|
return unreflect(m);
|
||||||
} else {
|
|
||||||
return lookup.findSpecial(declaringClass, name, type, declaringClass);
|
|
||||||
}
|
}
|
||||||
|
return lookup.findSpecial(declaringClass, name, type, declaringClass);
|
||||||
} catch(IllegalAccessException e) {
|
} catch(IllegalAccessException e) {
|
||||||
final IllegalAccessError ee = new IllegalAccessError("Failed to access special method " + methodDescription(
|
final IllegalAccessError ee = new IllegalAccessError("Failed to access special method " + methodDescription(
|
||||||
declaringClass, name, type));
|
declaringClass, name, type));
|
||||||
|
@ -87,7 +87,6 @@ import java.lang.invoke.MethodHandles.Lookup;
|
|||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A call site descriptor that stores a specific {@link Lookup}. It does not, however, store static bootstrap arguments.
|
* A call site descriptor that stores a specific {@link Lookup}. It does not, however, store static bootstrap arguments.
|
||||||
* @author Attila Szegedi
|
* @author Attila Szegedi
|
||||||
|
@ -86,7 +86,6 @@ package jdk.internal.dynalink.support;
|
|||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
|
|
||||||
|
|
||||||
class NamedDynCallSiteDescriptor extends UnnamedDynCallSiteDescriptor {
|
class NamedDynCallSiteDescriptor extends UnnamedDynCallSiteDescriptor {
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
@ -95,7 +95,6 @@ import jdk.internal.dynalink.linker.GuardedInvocation;
|
|||||||
import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
|
import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
|
||||||
import jdk.internal.dynalink.linker.LinkerServices;
|
import jdk.internal.dynalink.linker.LinkerServices;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory for type converters. This class is the main implementation behind the
|
* A factory for type converters. This class is the main implementation behind the
|
||||||
* {@link LinkerServices#asType(MethodHandle, MethodType)}. It manages the known {@link GuardingTypeConverterFactory}
|
* {@link LinkerServices#asType(MethodHandle, MethodType)}. It manages the known {@link GuardingTypeConverterFactory}
|
||||||
|
@ -86,7 +86,6 @@ package jdk.internal.dynalink.support;
|
|||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
|
|
||||||
|
|
||||||
class UnnamedDynCallSiteDescriptor extends AbstractCallSiteDescriptor {
|
class UnnamedDynCallSiteDescriptor extends AbstractCallSiteDescriptor {
|
||||||
private final MethodType methodType;
|
private final MethodType methodType;
|
||||||
private final String op;
|
private final String op;
|
||||||
|
@ -7,6 +7,7 @@ import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.FINALIZED;
|
|||||||
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.INITIALIZED;
|
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.INITIALIZED;
|
||||||
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOWERED;
|
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOWERED;
|
||||||
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT;
|
import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -15,9 +16,9 @@ import jdk.nashorn.internal.codegen.types.Type;
|
|||||||
import jdk.nashorn.internal.ir.FunctionNode;
|
import jdk.nashorn.internal.ir.FunctionNode;
|
||||||
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
|
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
|
||||||
import jdk.nashorn.internal.ir.Node;
|
import jdk.nashorn.internal.ir.Node;
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
|
||||||
import jdk.nashorn.internal.ir.debug.ASTWriter;
|
import jdk.nashorn.internal.ir.debug.ASTWriter;
|
||||||
import jdk.nashorn.internal.ir.debug.PrintVisitor;
|
import jdk.nashorn.internal.ir.debug.PrintVisitor;
|
||||||
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Context;
|
import jdk.nashorn.internal.runtime.Context;
|
||||||
import jdk.nashorn.internal.runtime.ECMAErrors;
|
import jdk.nashorn.internal.runtime.ECMAErrors;
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
package jdk.nashorn.internal.codegen;
|
package jdk.nashorn.internal.codegen;
|
||||||
|
|
||||||
|
import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
|
||||||
|
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -34,8 +36,6 @@ import jdk.nashorn.internal.ir.Node;
|
|||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
|
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
|
||||||
|
|
||||||
import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that generates function signatures for dynamic calls
|
* Class that generates function signatures for dynamic calls
|
||||||
*/
|
*/
|
||||||
|
@ -36,7 +36,6 @@ import java.util.EnumSet;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import jdk.nashorn.internal.codegen.CompileUnit;
|
import jdk.nashorn.internal.codegen.CompileUnit;
|
||||||
import jdk.nashorn.internal.codegen.Compiler;
|
import jdk.nashorn.internal.codegen.Compiler;
|
||||||
import jdk.nashorn.internal.codegen.Frame;
|
import jdk.nashorn.internal.codegen.Frame;
|
||||||
|
@ -28,7 +28,6 @@ package jdk.nashorn.internal.objects;
|
|||||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
|
|
||||||
import jdk.nashorn.internal.runtime.GlobalFunctions;
|
import jdk.nashorn.internal.runtime.GlobalFunctions;
|
||||||
import jdk.nashorn.internal.runtime.Property;
|
import jdk.nashorn.internal.runtime.Property;
|
||||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package jdk.nashorn.internal.objects;
|
package jdk.nashorn.internal.objects;
|
||||||
|
|
||||||
|
import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
|
|
||||||
|
|
||||||
import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
|
|
||||||
|
|
||||||
import jdk.nashorn.internal.codegen.Compiler;
|
import jdk.nashorn.internal.codegen.Compiler;
|
||||||
import jdk.nashorn.internal.codegen.FunctionSignature;
|
import jdk.nashorn.internal.codegen.FunctionSignature;
|
||||||
import jdk.nashorn.internal.codegen.types.Type;
|
import jdk.nashorn.internal.codegen.types.Type;
|
||||||
|
@ -59,7 +59,6 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import jdk.nashorn.internal.codegen.CompilerConstants;
|
import jdk.nashorn.internal.codegen.CompilerConstants;
|
||||||
import jdk.nashorn.internal.codegen.Namespace;
|
import jdk.nashorn.internal.codegen.Namespace;
|
||||||
import jdk.nashorn.internal.ir.AccessNode;
|
import jdk.nashorn.internal.ir.AccessNode;
|
||||||
@ -101,8 +100,8 @@ import jdk.nashorn.internal.runtime.Context;
|
|||||||
import jdk.nashorn.internal.runtime.ErrorManager;
|
import jdk.nashorn.internal.runtime.ErrorManager;
|
||||||
import jdk.nashorn.internal.runtime.JSErrorType;
|
import jdk.nashorn.internal.runtime.JSErrorType;
|
||||||
import jdk.nashorn.internal.runtime.ParserException;
|
import jdk.nashorn.internal.runtime.ParserException;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
|
||||||
import jdk.nashorn.internal.runtime.ScriptingFunctions;
|
import jdk.nashorn.internal.runtime.ScriptingFunctions;
|
||||||
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the IR.
|
* Builds the IR.
|
||||||
|
@ -45,7 +45,6 @@ import java.security.CodeSource;
|
|||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||||
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
|
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
|
||||||
import jdk.nashorn.internal.codegen.ClassEmitter;
|
import jdk.nashorn.internal.codegen.ClassEmitter;
|
||||||
|
@ -31,6 +31,7 @@ import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
|
|||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
|
import jdk.internal.dynalink.beans.BeansLinker;
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
|
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
|
||||||
import jdk.internal.dynalink.linker.LinkRequest;
|
import jdk.internal.dynalink.linker.LinkRequest;
|
||||||
@ -78,14 +79,14 @@ class NashornBottomLinker implements GuardingDynamicLinker {
|
|||||||
final String operator = desc.getFirstOperator();
|
final String operator = desc.getFirstOperator();
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case "new":
|
case "new":
|
||||||
if(isJavaDynamicMethod(self)) {
|
if(BeansLinker.isDynamicMethod(self)) {
|
||||||
typeError("method.not.constructor", ScriptRuntime.safeToString(self));
|
typeError("method.not.constructor", ScriptRuntime.safeToString(self));
|
||||||
} else {
|
} else {
|
||||||
typeError("not.a.function", ScriptRuntime.safeToString(self));
|
typeError("not.a.function", ScriptRuntime.safeToString(self));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "call":
|
case "call":
|
||||||
if(isJavaDynamicMethod(self)) {
|
if(BeansLinker.isDynamicMethod(self)) {
|
||||||
typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
|
typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
|
||||||
} else {
|
} else {
|
||||||
typeError("not.a.function", ScriptRuntime.safeToString(self));
|
typeError("not.a.function", ScriptRuntime.safeToString(self));
|
||||||
@ -113,16 +114,6 @@ class NashornBottomLinker implements GuardingDynamicLinker {
|
|||||||
throw new AssertionError("unknown call type " + desc);
|
throw new AssertionError("unknown call type " + desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the object is a Dynalink dynamic method. Unfortunately, the dynamic method classes are package
|
|
||||||
* private in Dynalink, so this is the closest we can get to determining it.
|
|
||||||
* @param obj the object we want to test for being a dynamic method
|
|
||||||
* @return true if it is a dynamic method, false otherwise.
|
|
||||||
*/
|
|
||||||
private static boolean isJavaDynamicMethod(Object obj) {
|
|
||||||
return obj.getClass().getName().endsWith("DynamicMethod");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GuardedInvocation getInvocation(final MethodHandle handle, final Object self, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
|
private static GuardedInvocation getInvocation(final MethodHandle handle, final Object self, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
|
||||||
return Bootstrap.asType(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc);
|
return Bootstrap.asType(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc);
|
||||||
}
|
}
|
||||||
|
52
nashorn/test/script/basic/javamethodcallerrors.js
Normal file
52
nashorn/test/script/basic/javamethodcallerrors.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect TypeError on wrong Java method invocations.
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Exit = java.lang.System.exit;
|
||||||
|
|
||||||
|
// Try to invoke it as constructor
|
||||||
|
try {
|
||||||
|
new Exit();
|
||||||
|
fail("Should have thrown TypeError");
|
||||||
|
} catch (e) {
|
||||||
|
if (! (e instanceof TypeError)) {
|
||||||
|
fail("TypeError expected, got " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to invoke with wrong number of args
|
||||||
|
|
||||||
|
try {
|
||||||
|
Exit(33, 44);
|
||||||
|
fail("Should have thrown TypeError");
|
||||||
|
} catch (e) {
|
||||||
|
if (! (e instanceof TypeError)) {
|
||||||
|
fail("TypeError expected, got " + e);
|
||||||
|
}
|
||||||
|
}
|
89
nashorn/test/script/basic/jsobject.js
Normal file
89
nashorn/test/script/basic/jsobject.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSObject tests
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var m = new javax.script.ScriptEngineManager();
|
||||||
|
var e = m.getEngineByName("nashorn");
|
||||||
|
|
||||||
|
e.eval("obj = { foo:'hello', 0: 'world', func: function(x) { return x.toUpperCase() } } ");
|
||||||
|
var obj = e.get("obj");
|
||||||
|
|
||||||
|
|
||||||
|
// try various getters
|
||||||
|
if (obj.foo != 'hello') {
|
||||||
|
fail("obj.foo does have expected value");
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPropGetter(obj, prop, expected) {
|
||||||
|
if (obj[prop] != expected) {
|
||||||
|
fail(prop + " does not have value: " + expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkPropGetter(obj, "foo", "hello");
|
||||||
|
checkPropGetter(obj, 0, "world");
|
||||||
|
checkPropGetter(obj, "0", "world");
|
||||||
|
|
||||||
|
// try various setters
|
||||||
|
|
||||||
|
obj.foo = "HELLO";
|
||||||
|
if (obj.foo != "HELLO") {
|
||||||
|
fail("obj.foo set does not work as expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPropSetter(obj, prop, newValue) {
|
||||||
|
obj[prop] = newValue;
|
||||||
|
checkPropGetter(obj, prop, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkPropSetter(obj, "foo", "NASHORN");
|
||||||
|
checkPropSetter(obj, 0, "ECMASCRIPT");
|
||||||
|
checkPropSetter(obj, "0", "CHANGED");
|
||||||
|
|
||||||
|
function callFunc(input, expected) {
|
||||||
|
if (obj.func(input) != expected) {
|
||||||
|
fail("obj.func(..) does not work as expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callFunc("nashorn", "NASHORN");
|
||||||
|
callFunc("javascript", "JAVASCRIPT");
|
||||||
|
callFunc("hello", "HELLO");
|
||||||
|
|
||||||
|
var Func = obj.func;
|
||||||
|
|
||||||
|
function callWithoutObject(input, expected) {
|
||||||
|
if (Func(input) != expected) {
|
||||||
|
fail("obj.func(..) does not work as expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callWithoutObject("nashorn", "NASHORN");
|
||||||
|
callWithoutObject("javascript", "JAVASCRIPT");
|
||||||
|
callWithoutObject("hello", "HELLO");
|
Loading…
x
Reference in New Issue
Block a user