This commit is contained in:
Jim Laskey 2013-02-19 09:47:02 -04:00
commit b5c0480f54
58 changed files with 361 additions and 259 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 });

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);
} }

View File

@ -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.
* *

View File

@ -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));

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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() {
}
} }

View File

@ -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);
} }

View File

@ -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();
} }
} }
} }

View File

@ -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());
} }

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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.

View File

@ -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.
* *

View File

@ -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

View File

@ -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) {

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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.
* *

View File

@ -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.
* *

View File

@ -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));

View File

@ -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

View File

@ -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;

View File

@ -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}

View File

@ -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;

View File

@ -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;

View File

@ -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
*/ */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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);
} }

View 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);
}
}

View 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");