1.1 --- a/src/jdk/internal/dynalink/DynamicLinkerFactory.java Thu Nov 06 17:06:56 2014 +0100 1.2 +++ b/src/jdk/internal/dynalink/DynamicLinkerFactory.java Mon Nov 03 09:49:52 2014 +0100 1.3 @@ -97,6 +97,7 @@ 1.4 import jdk.internal.dynalink.linker.GuardingDynamicLinker; 1.5 import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; 1.6 import jdk.internal.dynalink.linker.LinkRequest; 1.7 +import jdk.internal.dynalink.linker.MethodTypeConversionStrategy; 1.8 import jdk.internal.dynalink.support.AutoDiscovery; 1.9 import jdk.internal.dynalink.support.BottomGuardingDynamicLinker; 1.10 import jdk.internal.dynalink.support.ClassLoaderGetterContextProvider; 1.11 @@ -105,6 +106,7 @@ 1.12 import jdk.internal.dynalink.support.DefaultPrelinkFilter; 1.13 import jdk.internal.dynalink.support.LinkerServicesImpl; 1.14 import jdk.internal.dynalink.support.TypeConverterFactory; 1.15 +import jdk.internal.dynalink.support.TypeUtilities; 1.16 1.17 /** 1.18 * A factory class for creating {@link DynamicLinker}s. The most usual dynamic linker is a linker that is a composition 1.19 @@ -115,7 +117,6 @@ 1.20 * @author Attila Szegedi 1.21 */ 1.22 public class DynamicLinkerFactory { 1.23 - 1.24 /** 1.25 * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink threshold}. 1.26 */ 1.27 @@ -130,6 +131,7 @@ 1.28 private boolean syncOnRelink = false; 1.29 private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD; 1.30 private GuardedInvocationFilter prelinkFilter; 1.31 + private MethodTypeConversionStrategy autoConversionStrategy; 1.32 1.33 /** 1.34 * Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread 1.35 @@ -259,6 +261,29 @@ 1.36 } 1.37 1.38 /** 1.39 + * Sets an object representing the conversion strategy for automatic type conversions. After 1.40 + * {@link TypeConverterFactory#asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)} has 1.41 + * applied all custom conversions to a method handle, it still needs to effect 1.42 + * {@link TypeUtilities#isMethodInvocationConvertible(Class, Class) method invocation conversions} that 1.43 + * can usually be automatically applied as per 1.44 + * {@link java.lang.invoke.MethodHandle#asType(java.lang.invoke.MethodType)}. 1.45 + * However, sometimes language runtimes will want to customize even those conversions for their own call 1.46 + * sites. A typical example is allowing unboxing of null return values, which is by default prohibited by 1.47 + * ordinary {@code MethodHandles.asType}. In this case, a language runtime can install its own custom 1.48 + * automatic conversion strategy, that can deal with null values. Note that when the strategy's 1.49 + * {@link MethodTypeConversionStrategy#asType(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType)} 1.50 + * is invoked, the custom language conversions will already have been applied to the method handle, so by 1.51 + * design the difference between the handle's current method type and the desired final type will always 1.52 + * only be ones that can be subjected to method invocation conversions. The strategy also doesn't need to 1.53 + * invoke a final {@code MethodHandle.asType()} as the converter factory will do that as the final step. 1.54 + * @param autoConversionStrategy the strategy for applying method invocation conversions for the linker 1.55 + * created by this factory. 1.56 + */ 1.57 + public void setAutoConversionStrategy(final MethodTypeConversionStrategy autoConversionStrategy) { 1.58 + this.autoConversionStrategy = autoConversionStrategy; 1.59 + } 1.60 + 1.61 + /** 1.62 * Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers as well as 1.63 * the pre-link filter. 1.64 * 1.65 @@ -324,8 +349,9 @@ 1.66 prelinkFilter = new DefaultPrelinkFilter(); 1.67 } 1.68 1.69 - return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters), composite), 1.70 - prelinkFilter, runtimeContextArgCount, syncOnRelink, unstableRelinkThreshold); 1.71 + return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters, 1.72 + autoConversionStrategy), composite), prelinkFilter, runtimeContextArgCount, syncOnRelink, 1.73 + unstableRelinkThreshold); 1.74 } 1.75 1.76 private static ClassLoader getThreadContextClassLoader() {