8251538: Modernize and lint Dynalink code

Reviewed-by: sundar
This commit is contained in:
Attila Szegedi 2020-08-28 10:23:21 +02:00
parent 9523001f65
commit 4b1b547020
24 changed files with 80 additions and 187 deletions

View File

@ -269,8 +269,7 @@ public class CallSiteDescriptor extends SecureLookupSupplier {
final String mt = methodType.toString(); final String mt = methodType.toString();
final String l = getLookupPrivileged().toString(); final String l = getLookupPrivileged().toString();
final String o = operation.toString(); final String o = operation.toString();
final StringBuilder b = new StringBuilder(o.length() + mt.length() + 1 + l.length()); return o + mt + '@' + l;
return b.append(o).append(mt).append('@').append(l).toString();
} }
private void assertChangeInvariants(final CallSiteDescriptor changed, final String caller) { private void assertChangeInvariants(final CallSiteDescriptor changed, final String caller) {

View File

@ -132,12 +132,9 @@ abstract class ClassMap<T> {
final T newV = computeValue(clazz); final T newV = computeValue(clazz);
assert newV != null; assert newV != null;
final Boolean canReferenceDirectly = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { final Boolean canReferenceDirectly = AccessController.doPrivileged(
@Override (PrivilegedAction<Boolean>) () -> InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader()),
public Boolean run() { GET_CLASS_LOADER_CONTEXT);
return InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader());
}
}, GET_CLASS_LOADER_CONTEXT);
// If allowed to strongly reference, put it in the fast map // If allowed to strongly reference, put it in the fast map
if(canReferenceDirectly) { if(canReferenceDirectly) {

View File

@ -213,8 +213,7 @@ public final class DynamicLinker {
private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) { private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) {
// Make a bound MH of invoke() for this linker and call site // Make a bound MH of invoke() for this linker and call site
final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf( final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, relinkCount);
relinkCount));
// Make a MH that gathers all arguments to the invocation into an Object[] // Make a MH that gathers all arguments to the invocation into an Object[]
final MethodType type = callSite.getDescriptor().getMethodType(); final MethodType type = callSite.getDescriptor().getMethodType();
final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount()); final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount());

View File

@ -471,12 +471,9 @@ public final class DynamicLinkerFactory {
} }
private static ClassLoader getThreadContextClassLoader() { private static ClassLoader getThreadContextClassLoader() {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { return AccessController.doPrivileged(
@Override (PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader(),
public ClassLoader run() { GET_CLASS_LOADER_CONTEXT);
return Thread.currentThread().getContextClassLoader();
}
}, GET_CLASS_LOADER_CONTEXT);
} }
private static void addClasses(final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses, private static void addClasses(final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,

View File

@ -246,7 +246,7 @@ public final class NamespaceOperation implements Operation {
@Override @Override
public int hashCode() { public int hashCode() {
return baseOperation.hashCode() + 31 * Arrays.hashCode(namespaces); return baseOperation.hashCode() + 31 * Arrays.hashCode(namespaces);
}; }
/** /**
* Returns the string representation of this namespace operation. Defined to * Returns the string representation of this namespace operation. Defined to

View File

@ -93,10 +93,10 @@ final class TypeConverterFactory {
private final ConversionComparator[] comparators; private final ConversionComparator[] comparators;
private final MethodTypeConversionStrategy autoConversionStrategy; private final MethodTypeConversionStrategy autoConversionStrategy;
private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<ClassMap<MethodHandle>>() { private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<>() {
@Override @Override
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) { protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
return new ClassMap<MethodHandle>(getClassLoader(sourceType)) { return new ClassMap<>(getClassLoader(sourceType)) {
@Override @Override
protected MethodHandle computeValue(final Class<?> targetType) { protected MethodHandle computeValue(final Class<?> targetType) {
try { try {
@ -111,10 +111,10 @@ final class TypeConverterFactory {
} }
}; };
private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<ClassMap<MethodHandle>>() { private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<>() {
@Override @Override
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) { protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
return new ClassMap<MethodHandle>(getClassLoader(sourceType)) { return new ClassMap<>(getClassLoader(sourceType)) {
@Override @Override
protected MethodHandle computeValue(final Class<?> targetType) { protected MethodHandle computeValue(final Class<?> targetType) {
if(!canAutoConvert(sourceType, targetType)) { if(!canAutoConvert(sourceType, targetType)) {
@ -129,10 +129,10 @@ final class TypeConverterFactory {
} }
}; };
private final ClassValue<ClassMap<Boolean>> canConvert = new ClassValue<ClassMap<Boolean>>() { private final ClassValue<ClassMap<Boolean>> canConvert = new ClassValue<>() {
@Override @Override
protected ClassMap<Boolean> computeValue(final Class<?> sourceType) { protected ClassMap<Boolean> computeValue(final Class<?> sourceType) {
return new ClassMap<Boolean>(getClassLoader(sourceType)) { return new ClassMap<>(getClassLoader(sourceType)) {
@Override @Override
protected Boolean computeValue(final Class<?> targetType) { protected Boolean computeValue(final Class<?> targetType) {
try { try {
@ -148,12 +148,7 @@ final class TypeConverterFactory {
}; };
private static ClassLoader getClassLoader(final Class<?> clazz) { private static ClassLoader getClassLoader(final Class<?> clazz) {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) clazz::getClassLoader, GET_CLASS_LOADER_CONTEXT);
@Override
public ClassLoader run() {
return clazz.getClassLoader();
}
}, GET_CLASS_LOADER_CONTEXT);
} }
/** /**

View File

@ -63,10 +63,9 @@ package jdk.dynalink.beans;
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 java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Arrays; import java.util.Arrays;
@ -172,7 +171,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
return str; return str;
} }
final char c[] = str.toCharArray(); final char[] c = str.toCharArray();
c[0] = Character.toLowerCase(c0); c[0] = Character.toLowerCase(c0);
return new String(c); return new String(c);
} }
@ -232,8 +231,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType); setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType);
} }
private void addMember(final String name, final AccessibleObject ao, final Map<String, DynamicMethod> methodMap) { private void addMember(final String name, final Executable m, final Map<String, DynamicMethod> methodMap) {
addMember(name, createDynamicMethod(ao), methodMap); addMember(name, createDynamicMethod(m), methodMap);
} }
private void addMember(final String name, final SingleDynamicMethod method, final Map<String, DynamicMethod> methodMap) { private void addMember(final String name, final SingleDynamicMethod method, final Map<String, DynamicMethod> methodMap) {
@ -252,9 +251,9 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
* @param name the common name of the reflective members. * @param name the common name of the reflective members.
* @return a dynamic method representing all the specified reflective members. * @return a dynamic method representing all the specified reflective members.
*/ */
static DynamicMethod createDynamicMethod(final Iterable<? extends AccessibleObject> members, final Class<?> clazz, final String name) { static DynamicMethod createDynamicMethod(final Iterable<? extends Executable> members, final Class<?> clazz, final String name) {
DynamicMethod dynMethod = null; DynamicMethod dynMethod = null;
for(final AccessibleObject method: members) { for(final Executable method: members) {
dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name); dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name);
} }
return dynMethod; return dynMethod;
@ -267,7 +266,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
* @param m the reflective member * @param m the reflective member
* @return the single dynamic method representing the reflective member * @return the single dynamic method representing the reflective member
*/ */
private static SingleDynamicMethod createDynamicMethod(final AccessibleObject m) { private static SingleDynamicMethod createDynamicMethod(final Executable m) {
if (m.isAnnotationPresent(CallerSensitive.class)) { if (m.isAnnotationPresent(CallerSensitive.class)) {
// Method has @CallerSensitive annotation // Method has @CallerSensitive annotation
return new CallerSensitiveDynamicMethod(m); return new CallerSensitiveDynamicMethod(m);
@ -282,8 +281,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
return new CallerSensitiveDynamicMethod(m); return new CallerSensitiveDynamicMethod(m);
} }
// Proceed with non-caller sensitive // Proceed with non-caller sensitive
final Member member = (Member)m; return new SimpleDynamicMethod(mh, m.getDeclaringClass(), m.getName(), m instanceof Constructor);
return new SimpleDynamicMethod(mh, member.getDeclaringClass(), member.getName(), m instanceof Constructor);
} }
/** /**
@ -294,7 +292,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
* @param m the method or constructor * @param m the method or constructor
* @return the method handle * @return the method handle
*/ */
private static MethodHandle unreflectSafely(final AccessibleObject m) { private static MethodHandle unreflectSafely(final Executable m) {
if(m instanceof Method) { if(m instanceof Method) {
final Method reflMethod = (Method)m; final Method reflMethod = (Method)m;
final MethodHandle handle = Lookup.PUBLIC.unreflect(reflMethod); final MethodHandle handle = Lookup.PUBLIC.unreflect(reflMethod);
@ -326,8 +324,6 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
@Override @Override
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
throws Exception { throws Exception {
final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor();
final MissingMemberHandlerFactory missingMemberHandlerFactory; final MissingMemberHandlerFactory missingMemberHandlerFactory;
final LinkerServices directLinkerServices; final LinkerServices directLinkerServices;
if (linkerServices instanceof LinkerServicesWithMissingMemberHandlerFactory) { if (linkerServices instanceof LinkerServicesWithMissingMemberHandlerFactory) {
@ -436,14 +432,6 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
return getClassGuardedInvocationComponent(handler, type); return getClassGuardedInvocationComponent(handler, type);
} }
static final <T> List<T> pop(final List<T> l) {
return l.subList(1, l.size());
}
MethodHandle getClassGuard(final CallSiteDescriptor desc) {
return getClassGuard(desc.getMethodType());
}
MethodHandle getClassGuard(final MethodType type) { MethodHandle getClassGuard(final MethodType type) {
return Guards.asType(classGuard, type); return Guards.asType(classGuard, type);
} }
@ -814,7 +802,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
} }
} }
private static MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial( private static final MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
"getPropertyGetterHandle", Object.class, Object.class), 1, Object.class); "getPropertyGetterHandle", Object.class, Object.class), 1, Object.class);
private final MethodHandle getPropertyGetterHandle = GET_PROPERTY_GETTER_HANDLE.bindTo(this); private final MethodHandle getPropertyGetterHandle = GET_PROPERTY_GETTER_HANDLE.bindTo(this);
@ -842,7 +830,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters); return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters);
} }
private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial( private static final MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
"getDynamicMethod", Object.class, Object.class), 1, Object.class); "getDynamicMethod", Object.class, Object.class), 1, Object.class);
private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this); private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this);
@ -873,21 +861,21 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
* @return getter with same name, declared on the most generic superclass/interface of the declaring class * @return getter with same name, declared on the most generic superclass/interface of the declaring class
*/ */
private static Method getMostGenericGetter(final Method getter) { private static Method getMostGenericGetter(final Method getter) {
return getMostGenericGetter(getter.getName(), getter.getReturnType(), getter.getDeclaringClass()); return getMostGenericGetter(getter.getName(), getter.getDeclaringClass());
} }
private static Method getMostGenericGetter(final String name, final Class<?> returnType, final Class<?> declaringClass) { private static Method getMostGenericGetter(final String name, final Class<?> declaringClass) {
if(declaringClass == null) { if(declaringClass == null) {
return null; return null;
} }
// Prefer interfaces // Prefer interfaces
for(final Class<?> itf: declaringClass.getInterfaces()) { for(final Class<?> itf: declaringClass.getInterfaces()) {
final Method itfGetter = getMostGenericGetter(name, returnType, itf); final Method itfGetter = getMostGenericGetter(name, itf);
if(itfGetter != null) { if(itfGetter != null) {
return itfGetter; return itfGetter;
} }
} }
final Method superGetter = getMostGenericGetter(name, returnType, declaringClass.getSuperclass()); final Method superGetter = getMostGenericGetter(name, declaringClass.getSuperclass());
if(superGetter != null) { if(superGetter != null) {
return superGetter; return superGetter;
} }

View File

@ -93,17 +93,6 @@ class AccessibleMembersLookup {
lookupAccessibleMembers(clazz); lookupAccessibleMembers(clazz);
} }
/**
* Returns an accessible method equivalent of a method.
*
* @param m the method whose accessible equivalent is requested.
* @return the accessible equivalent for the method (can be the same as the passed in method), or null if there is
* no accessible method equivalent.
*/
Method getAccessibleMethod(final Method m) {
return m == null ? null : methods.get(new MethodSignature(m));
}
Collection<Method> getMethods() { Collection<Method> getMethods() {
return methods.values(); return methods.values();
} }
@ -230,9 +219,8 @@ class AccessibleMembersLookup {
// If we reach here, the class is either not public, or it is in a restricted package. Alternatively, it is // If we reach here, the class is either not public, or it is in a restricted package. Alternatively, it is
// public, but some of its methods claim that their declaring class is non-public. We'll try superclasses // public, but some of its methods claim that their declaring class is non-public. We'll try superclasses
// and implemented interfaces then looking for public ones. // and implemented interfaces then looking for public ones.
final Class<?>[] interfaces = clazz.getInterfaces(); for (final Class<?> itf: clazz.getInterfaces()) {
for(int i = 0; i < interfaces.length; i++) { lookupAccessibleMembers(itf);
lookupAccessibleMembers(interfaces[i]);
} }
final Class<?> superclass = clazz.getSuperclass(); final Class<?> superclass = clazz.getSuperclass();
if(superclass != null) { if(superclass != null) {

View File

@ -158,7 +158,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
private enum CollectionType { private enum CollectionType {
ARRAY, LIST, MAP ARRAY, LIST, MAP
}; }
private GuardedInvocationComponent getElementGetter(final ComponentLinkRequest req) throws Exception { private GuardedInvocationComponent getElementGetter(final ComponentLinkRequest req) throws Exception {
final CallSiteDescriptor callSiteDescriptor = req.getDescriptor(); final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
@ -241,7 +241,7 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
// Convert the key to a number if we're working with a list or array // Convert the key to a number if we're working with a list or array
if (!isMap && name != null) { if (!isMap && name != null) {
final Integer integer = convertKeyToInteger(name, linkerServices); final Integer integer = convertKeyToInteger(name, linkerServices);
if (integer == null || integer.intValue() < 0) { if (integer == null || integer < 0) {
// key is not a non-negative integer, it can never address an // key is not a non-negative integer, it can never address an
// array or list element // array or list element
return INVALID_NAME; return INVALID_NAME;

View File

@ -133,7 +133,7 @@ import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker;
* method.</p> * method.</p>
*/ */
public class BeansLinker implements GuardingDynamicLinker { public class BeansLinker implements GuardingDynamicLinker {
private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<TypeBasedGuardingDynamicLinker>() { private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<>() {
@Override @Override
protected TypeBasedGuardingDynamicLinker computeValue(final Class<?> clazz) { protected TypeBasedGuardingDynamicLinker computeValue(final Class<?> clazz) {
// If ClassValue.put() were public, we could just pre-populate with these known mappings... // If ClassValue.put() were public, we could just pre-populate with these known mappings...

View File

@ -63,10 +63,8 @@ package jdk.dynalink.beans;
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 java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Executable; import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.security.AccessControlContext; import java.security.AccessControlContext;
@ -76,8 +74,6 @@ import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.SecureLookupSupplier; import jdk.dynalink.SecureLookupSupplier;
import jdk.dynalink.internal.AccessControlContextFactory; import jdk.dynalink.internal.AccessControlContextFactory;
import jdk.dynalink.linker.support.Lookup; import jdk.dynalink.linker.support.Lookup;
import jdk.internal.reflect.CallerSensitive;
/** /**
* A dynamic method bound to exactly one Java method or constructor that is caller sensitive. Since the target method is * A dynamic method bound to exactly one Java method or constructor that is caller sensitive. Since the target method is
@ -90,21 +86,18 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
AccessControlContextFactory.createAccessControlContext( AccessControlContextFactory.createAccessControlContext(
SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME); SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
// Typed as "AccessibleObject" as it can be either a method or a constructor. private final Executable target;
// If we were Java8-only, we could use java.lang.reflect.Executable
private final AccessibleObject target;
private final MethodType type; private final MethodType type;
CallerSensitiveDynamicMethod(final AccessibleObject target) { CallerSensitiveDynamicMethod(final Executable target) {
super(getName(target)); super(getName(target));
this.target = target; this.target = target;
this.type = getMethodType(target); this.type = getMethodType(target);
} }
private static String getName(final AccessibleObject target) { private static String getName(final Executable m) {
final Member m = (Member)target;
final boolean constructor = m instanceof Constructor; final boolean constructor = m instanceof Constructor;
return getMethodNameWithSignature(getMethodType(target), constructor ? m.getName() : return getMethodNameWithSignature(getMethodType(m), constructor ? m.getName() :
getClassAndMethodName(m.getDeclaringClass(), m.getName()), !constructor); getClassAndMethodName(m.getDeclaringClass(), m.getName()), !constructor);
} }
@ -113,12 +106,11 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
return type; return type;
} }
private static MethodType getMethodType(final AccessibleObject ao) { private static MethodType getMethodType(final Executable m) {
final boolean isMethod = ao instanceof Method; final boolean isMethod = m instanceof Method;
final Class<?> rtype = isMethod ? ((Method)ao).getReturnType() : ((Constructor<?>)ao).getDeclaringClass(); final Class<?> rtype = isMethod ? ((Method)m).getReturnType() : ((Constructor<?>)m).getDeclaringClass();
final Class<?>[] ptypes = isMethod ? ((Method)ao).getParameterTypes() : ((Constructor<?>)ao).getParameterTypes(); final Class<?>[] ptypes = m.getParameterTypes();
final MethodType type = MethodType.methodType(rtype, ptypes); final MethodType type = MethodType.methodType(rtype, ptypes);
final Member m = (Member)ao;
return type.insertParameterTypes(0, return type.insertParameterTypes(0,
isMethod ? isMethod ?
Modifier.isStatic(m.getModifiers()) ? Modifier.isStatic(m.getModifiers()) ?
@ -129,18 +121,18 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
@Override @Override
boolean isVarArgs() { boolean isVarArgs() {
return target instanceof Method ? ((Method)target).isVarArgs() : ((Constructor<?>)target).isVarArgs(); return target.isVarArgs();
} }
@Override @Override
MethodHandle getTarget(final CallSiteDescriptor desc) { MethodHandle getTarget(final CallSiteDescriptor desc) {
final MethodHandles.Lookup lookup = AccessController.doPrivileged( final MethodHandles.Lookup lookup = AccessController.doPrivileged(
(PrivilegedAction<MethodHandles.Lookup>)()->desc.getLookup(), (PrivilegedAction<MethodHandles.Lookup>)desc::getLookup,
GET_LOOKUP_CONTEXT); GET_LOOKUP_CONTEXT);
if(target instanceof Method) { if(target instanceof Method) {
final MethodHandle mh = unreflect(lookup, (Method)target); final MethodHandle mh = unreflect(lookup, (Method)target);
if(Modifier.isStatic(((Member)target).getModifiers())) { if(Modifier.isStatic(target.getModifiers())) {
return StaticClassIntrospector.editStaticMethodHandle(mh); return StaticClassIntrospector.editStaticMethodHandle(mh);
} }
return mh; return mh;

View File

@ -102,12 +102,9 @@ class CheckRestrictedPackage {
} }
// Do a package access check from within an access control context with no permissions // Do a package access check from within an access control context with no permissions
try { try {
AccessController.doPrivileged(new PrivilegedAction<Void>() { AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
@Override sm.checkPackageAccess(pkgName);
public Void run() { return null;
sm.checkPackageAccess(pkgName);
return null;
}
}, NO_PERMISSIONS_CONTEXT); }, NO_PERMISSIONS_CONTEXT);
} catch(final SecurityException e) { } catch(final SecurityException e) {
return true; return true;

View File

@ -61,7 +61,6 @@
package jdk.dynalink.beans; package jdk.dynalink.beans;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.security.AccessControlContext; import java.security.AccessControlContext;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
@ -94,10 +93,6 @@ final class ClassString {
this.classes = classes; this.classes = classes;
} }
ClassString(final MethodType type) {
this(type.parameterArray());
}
@Override @Override
public boolean equals(final Object other) { public boolean equals(final Object other) {
if(!(other instanceof ClassString)) { if(!(other instanceof ClassString)) {
@ -119,8 +114,8 @@ final class ClassString {
public int hashCode() { public int hashCode() {
if(hashCode == 0) { if(hashCode == 0) {
int h = 0; int h = 0;
for(int i = 0; i < classes.length; ++i) { for(final Class<?> cls: classes) {
h ^= classes[i].hashCode(); h ^= cls.hashCode();
} }
hashCode = h; hashCode = h;
} }
@ -133,16 +128,13 @@ final class ClassString {
} }
boolean isVisibleFrom(final ClassLoader classLoader) { boolean isVisibleFrom(final ClassLoader classLoader) {
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { return AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
@Override for(final Class<?> clazz: classes) {
public Boolean run() { if(!InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
for(final Class<?> clazz: classes) { return false;
if(!InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
return false;
}
} }
return true;
} }
return true;
}, GET_CLASS_LOADER_CONTEXT); }, GET_CLASS_LOADER_CONTEXT);
} }

View File

@ -65,6 +65,7 @@ import java.lang.invoke.MethodType;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.function.Function;
import jdk.dynalink.linker.ConversionComparator.Comparison; import jdk.dynalink.linker.ConversionComparator.Comparison;
import jdk.dynalink.linker.LinkerServices; import jdk.dynalink.linker.LinkerServices;
import jdk.dynalink.linker.support.TypeUtilities; import jdk.dynalink.linker.support.TypeUtilities;
@ -81,29 +82,9 @@ class MaximallySpecific {
* @return the list of maximally specific methods. * @return the list of maximally specific methods.
*/ */
static List<SingleDynamicMethod> getMaximallySpecificMethods(final List<SingleDynamicMethod> methods, final boolean varArgs) { static List<SingleDynamicMethod> getMaximallySpecificMethods(final List<SingleDynamicMethod> methods, final boolean varArgs) {
return getMaximallySpecificSingleDynamicMethods(methods, varArgs, null, null); return getMaximallySpecificMethods(methods, varArgs, null, null, SingleDynamicMethod::getMethodType);
} }
private abstract static class MethodTypeGetter<T> {
abstract MethodType getMethodType(T t);
}
private static final MethodTypeGetter<MethodHandle> METHOD_HANDLE_TYPE_GETTER =
new MethodTypeGetter<MethodHandle>() {
@Override
MethodType getMethodType(final MethodHandle t) {
return t.type();
}
};
private static final MethodTypeGetter<SingleDynamicMethod> DYNAMIC_METHOD_TYPE_GETTER =
new MethodTypeGetter<SingleDynamicMethod>() {
@Override
MethodType getMethodType(final SingleDynamicMethod t) {
return t.getMethodType();
}
};
/** /**
* Given a list of methods handles, returns a list of maximally specific methods, applying language-runtime * Given a list of methods handles, returns a list of maximally specific methods, applying language-runtime
* specific conversion preferences. * specific conversion preferences.
@ -115,21 +96,7 @@ class MaximallySpecific {
*/ */
static List<MethodHandle> getMaximallySpecificMethodHandles(final List<MethodHandle> methods, final boolean varArgs, static List<MethodHandle> getMaximallySpecificMethodHandles(final List<MethodHandle> methods, final boolean varArgs,
final Class<?>[] argTypes, final LinkerServices ls) { final Class<?>[] argTypes, final LinkerServices ls) {
return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, METHOD_HANDLE_TYPE_GETTER); return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, MethodHandle::type);
}
/**
* Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific
* conversion preferences.
*
* @param methods the list of methods
* @param varArgs whether to assume the methods are varargs
* @param argTypes concrete argument types for the invocation
* @return the list of maximally specific methods.
*/
static List<SingleDynamicMethod> getMaximallySpecificSingleDynamicMethods(final List<SingleDynamicMethod> methods,
final boolean varArgs, final Class<?>[] argTypes, final LinkerServices ls) {
return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, DYNAMIC_METHOD_TYPE_GETTER);
} }
/** /**
@ -142,17 +109,17 @@ class MaximallySpecific {
* @return the list of maximally specific methods. * @return the list of maximally specific methods.
*/ */
private static <T> List<T> getMaximallySpecificMethods(final List<T> methods, final boolean varArgs, private static <T> List<T> getMaximallySpecificMethods(final List<T> methods, final boolean varArgs,
final Class<?>[] argTypes, final LinkerServices ls, final MethodTypeGetter<T> methodTypeGetter) { final Class<?>[] argTypes, final LinkerServices ls, final Function<T, MethodType> methodTypeGetter) {
if(methods.size() < 2) { if(methods.size() < 2) {
return methods; return methods;
} }
final LinkedList<T> maximals = new LinkedList<>(); final LinkedList<T> maximals = new LinkedList<>();
for(final T m: methods) { for(final T m: methods) {
final MethodType methodType = methodTypeGetter.getMethodType(m); final MethodType methodType = methodTypeGetter.apply(m);
boolean lessSpecific = false; boolean lessSpecific = false;
for(final Iterator<T> maximal = maximals.iterator(); maximal.hasNext();) { for(final Iterator<T> maximal = maximals.iterator(); maximal.hasNext();) {
final T max = maximal.next(); final T max = maximal.next();
switch(isMoreSpecific(methodType, methodTypeGetter.getMethodType(max), varArgs, argTypes, ls)) { switch(isMoreSpecific(methodType, methodTypeGetter.apply(max), varArgs, argTypes, ls)) {
case TYPE_1_BETTER: { case TYPE_1_BETTER: {
maximal.remove(); maximal.remove();
break; break;

View File

@ -67,9 +67,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.text.Collator; import java.text.Collator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -158,12 +156,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(subtypingApplicables.getMethods());
invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods());
invokables.removeAll(variableArityApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods());
for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { invokables.removeIf(m -> !isApplicableDynamically(linkerServices, callSiteType, m));
final SingleDynamicMethod m = it.next();
if(!isApplicableDynamically(linkerServices, callSiteType, m)) {
it.remove();
}
}
// If no additional methods can apply at invocation time, and there's more than one maximally specific method // If no additional methods can apply at invocation time, and there's more than one maximally specific method
// based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an
@ -206,12 +199,9 @@ class OverloadedDynamicMethod extends DynamicMethod {
"getClassLoader", SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME); "getClassLoader", SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
private static ClassLoader getCallSiteClassLoader(final CallSiteDescriptor callSiteDescriptor) { private static ClassLoader getCallSiteClassLoader(final CallSiteDescriptor callSiteDescriptor) {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { return AccessController.doPrivileged(
@Override (PrivilegedAction<ClassLoader>) () -> callSiteDescriptor.getLookup().lookupClass().getClassLoader(),
public ClassLoader run() { GET_CALL_SITE_CLASS_LOADER_CONTEXT);
return callSiteDescriptor.getLookup().lookupClass().getClassLoader();
}
}, GET_CALL_SITE_CLASS_LOADER_CONTEXT);
} }
@Override @Override
@ -243,7 +233,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
// Case insensitive sorting, so e.g. "Object" doesn't come before "boolean". // Case insensitive sorting, so e.g. "Object" doesn't come before "boolean".
final Collator collator = Collator.getInstance(); final Collator collator = Collator.getInstance();
collator.setStrength(Collator.SECONDARY); collator.setStrength(Collator.SECONDARY);
Collections.sort(names, collator); names.sort(collator);
final String className = getClass().getName(); final String className = getClass().getName();
// Class name length + length of signatures + 2 chars/per signature for indentation and newline + // Class name length + length of signatures + 2 chars/per signature for indentation and newline +
@ -257,7 +247,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
b.append(']'); b.append(']');
assert b.length() == totalLength; assert b.length() == totalLength;
return b.toString(); return b.toString();
}; }
private static boolean isApplicableDynamically(final LinkerServices linkerServices, final MethodType callSiteType, private static boolean isApplicableDynamically(final LinkerServices linkerServices, final MethodType callSiteType,
final SingleDynamicMethod m) { final SingleDynamicMethod m) {
@ -327,7 +317,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
} }
private boolean constructorFlagConsistent(final SingleDynamicMethod method) { private boolean constructorFlagConsistent(final SingleDynamicMethod method) {
return methods.isEmpty()? true : (methods.getFirst().isConstructor() == method.isConstructor()); return methods.isEmpty() || methods.getFirst().isConstructor() == method.isConstructor();
} }
/** /**

View File

@ -135,7 +135,7 @@ class OverloadedMethod {
MethodHandle.class, Object[].class); MethodHandle.class, Object[].class);
@SuppressWarnings("unused") @SuppressWarnings("unused")
private MethodHandle selectMethod(final Object[] args) throws NoSuchMethodException { private MethodHandle selectMethod(final Object[] args) {
final Class<?>[] argTypes = new Class<?>[args.length]; final Class<?>[] argTypes = new Class<?>[args.length];
for(int i = 0; i < argTypes.length; ++i) { for(int i = 0; i < argTypes.length; ++i) {
final Object arg = args[i]; final Object arg = args[i];

View File

@ -248,7 +248,7 @@ abstract class SingleDynamicMethod extends DynamicMethod {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static boolean canConvertTo(final LinkerServices linkerServices, final Class<?> to, final Object obj) { private static boolean canConvertTo(final LinkerServices linkerServices, final Class<?> to, final Object obj) {
return obj == null ? false : linkerServices.canConvert(obj.getClass(), to); return obj != null && linkerServices.canConvert(obj.getClass(), to);
} }
/** /**

View File

@ -104,7 +104,7 @@ import jdk.dynalink.StandardOperation;
* {@link BeansLinker#getConstructorMethod(Class, String)}. * {@link BeansLinker#getConstructorMethod(Class, String)}.
*/ */
public final class StaticClass implements Serializable { public final class StaticClass implements Serializable {
private static final ClassValue<StaticClass> staticClasses = new ClassValue<StaticClass>() { private static final ClassValue<StaticClass> staticClasses = new ClassValue<>() {
@Override @Override
protected StaticClass computeValue(final Class<?> type) { protected StaticClass computeValue(final Class<?> type) {
return new StaticClass(type); return new StaticClass(type);

View File

@ -81,7 +81,7 @@ import jdk.dynalink.linker.support.Lookup;
* Provides a linker for the {@link StaticClass} objects. * Provides a linker for the {@link StaticClass} objects.
*/ */
class StaticClassLinker implements TypeBasedGuardingDynamicLinker { class StaticClassLinker implements TypeBasedGuardingDynamicLinker {
private static final ClassValue<SingleClassStaticsLinker> linkers = new ClassValue<SingleClassStaticsLinker>() { private static final ClassValue<SingleClassStaticsLinker> linkers = new ClassValue<>() {
@Override @Override
protected SingleClassStaticsLinker computeValue(final Class<?> clazz) { protected SingleClassStaticsLinker computeValue(final Class<?> clazz) {
return new SingleClassStaticsLinker(clazz); return new SingleClassStaticsLinker(clazz);

View File

@ -179,9 +179,8 @@ public class InternalTypeUtilities {
if(sc != null) { if(sc != null) {
collectAssignables(sc, c2, s); collectAssignables(sc, c2, s);
} }
final Class<?>[] itf = c1.getInterfaces(); for(final Class<?> itf: c1.getInterfaces()) {
for(int i = 0; i < itf.length; ++i) { collectAssignables(itf, c2, s);
collectAssignables(itf[i], c2, s);
} }
} }
} }

View File

@ -210,7 +210,7 @@ public final class Guards {
assert test.type().parameterCount() == 1; assert test.type().parameterCount() == 1;
assert test.type().returnType() == Boolean.TYPE; assert test.type().returnType() == Boolean.TYPE;
return MethodHandles.permuteArguments(test.asType(test.type().changeParameterType(0, type.parameterType(pos))), return MethodHandles.permuteArguments(test.asType(test.type().changeParameterType(0, type.parameterType(pos))),
type.changeReturnType(Boolean.TYPE), new int[] { pos }); type.changeReturnType(Boolean.TYPE), pos);
} }
private static final MethodHandle IS_INSTANCE = Lookup.PUBLIC.findVirtual(Class.class, "isInstance", private static final MethodHandle IS_INSTANCE = Lookup.PUBLIC.findVirtual(Class.class, "isInstance",

View File

@ -64,7 +64,6 @@ 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 java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;

View File

@ -72,8 +72,6 @@ import jdk.dynalink.linker.MethodTypeConversionStrategy;
* Various static utility methods for working with Java types. * Various static utility methods for working with Java types.
*/ */
public final class TypeUtilities { public final class TypeUtilities {
static final Class<Object> OBJECT_CLASS = Object.class;
private TypeUtilities() { private TypeUtilities() {
} }

View File

@ -63,7 +63,6 @@ package jdk.dynalink.support;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import jdk.dynalink.CallSiteDescriptor; import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.linker.GuardedInvocation; import jdk.dynalink.linker.GuardedInvocation;
@ -150,12 +149,9 @@ public class ChainedCallSite extends AbstractRelinkableCallSite {
// First, prune the chain of invalidated switchpoints, we always do this // First, prune the chain of invalidated switchpoints, we always do this
// We also remove any catches if the remove catches flag is set // We also remove any catches if the remove catches flag is set
for(final Iterator<GuardedInvocation> it = newInvocations.iterator(); it.hasNext();) { newInvocations.removeIf(inv ->
final GuardedInvocation inv = it.next(); inv.hasBeenInvalidated() || (removeCatches && inv.getException() != null)
if(inv.hasBeenInvalidated() || (removeCatches && inv.getException() != null)) { );
it.remove();
}
}
// prune() is allowed to invoke this method with invocation == null meaning we're just pruning the chain and not // prune() is allowed to invoke this method with invocation == null meaning we're just pruning the chain and not
// adding any new invocations to it. // adding any new invocations to it.