hg: lambda/lambda/jdk: 3 new changesets

Rémi Forax forax at univ-mlv.fr
Sun Apr 22 06:30:42 PDT 2012


On 04/22/2012 12:23 PM, Rémi Forax wrote:
> On 04/21/2012 11:58 PM, brian.goetz at oracle.com wrote:
>> Changeset: 59aa44ba1555
>> Author:    briangoetz
>> Date:      2012-04-21 17:56 -0400
>> URL:       http://hg.openjdk.java.net/lambda/lambda/jdk/rev/59aa44ba1555
>>
>> Minor improvements in combo-test framework and lambda tests
>>
>> ! combo-tests/build.xml
>> ! combo-tests/tests/tools/javac/combo/JavacTemplateTestBase.java
>> ! combo-tests/tests/tools/javac/combo/Template.java
>> ! combo-tests/tests/tools/javac/lambda/LambdaConversionTest.java
>>
>> Changeset: b166fa7adaea
>> Author:    briangoetz
>> Date:      2012-04-21 17:56 -0400
>> URL:       http://hg.openjdk.java.net/lambda/lambda/jdk/rev/b166fa7adaea
>>
>> Minor improvements in combo-test framework and lambda tests
>>
>> ! test-ng/build.xml
>> ! test-ng/tests/org/openjdk/tests/java/util/functions/MappersTest.java
>>
>> Changeset: d0e63cae6a1c
>> Author:    briangoetz
>> Date:      2012-04-21 17:57 -0400
>> URL:       http://hg.openjdk.java.net/lambda/lambda/jdk/rev/d0e63cae6a1c
>>
>> Allow metafactory option to be choosable at runtime via lambda.metafactory system property; first cut at second translation strategy (method handle proxies)
>>
>> ! .hgignore
>> ! src/share/classes/java/lang/invoke/InnerClassGenerator.java
>> ! src/share/classes/java/lang/invoke/LambdaMetafactory.java
>> + src/share/classes/java/lang/invoke/MagicLambdaImpl.java
>> ! src/share/classes/java/lang/invoke/MethodHandleProxies.java
>> + src/share/classes/java/lang/invoke/MethodHandleProxyLambdaMetafactory.java
>>
>>
> Hi Brian,
> I think you don't need the MhMetafactoryCallSite because
> the arguments of MethodHandle.asInterfaceInstance are known during the
> bootstrap.
> The idea is that instead of the method factory,() you can bind the
> method bindTo itself.
> I will try to come with a code, it will be more clear :)
>
> Rémi

I propose something like this
(I have not tested it, I will test it tomorrow at my office :)

static CallSite mhProxyMetafactory(MethodHandles.Lookup caller,
                                        MethodType invokedType,
                                        MethodHandleInfo samInfo,
                                        MethodHandleInfo implInfo,
                                        MethodHandle impl) {
         Class<?> samBase = invokedType.returnType();

         // @@@ Special bindTo case for count=1 && isInstance

         if (invokedType.parameterCount() == 0) {
             return new ConstantCallSite(MethodHandles.constant(samBase,
                                                                
MethodHandleProxies.asInterfaceInstance(samBase, impl)));
         }

         return new ConstantCallSite(
             ProxyMetaFactory.createProxyCreatorMethodHandle(samBase, 
impl, invokedType));

         /*
         else {
             try {
                 return new MhMetafactoryCallSite(impl, invokedType, 
samBase);
             }
             catch (Throwable e) {
                 log("Exception constructing Lambda factory callsite", e);
                 throw new LambdaConversionException("Error constructing 
CallSite", e);
             }
         }*/
     }

     static class ProxyMetaFactory {
       private static final MethodHandle INSERT_ARGUMENTS;
       private static final MethodHandle AS_INTERFACE_INSTANCE;

       static {
         Lookup lookup = MethodHandles.Lookup.IMPL_LOOKUP;
         MethodHandle insertArguments;
         try {
           insertArguments = lookup.findStatic(MethodHandles.class, 
"insertArguments",
               MethodType.methodType(MethodHandle.class, 
MethodHandle.class, int.class, Object[].class));
           AS_INTERFACE_INSTANCE = 
lookup.findStatic(MethodHandleProxies.class, "asInterfaceInstance",
               MethodType.methodType(Object.class, Class.class, 
MethodHandle.class));
         } catch (NoSuchMethodException | IllegalAccessException e) {
           throw new AssertionError(e);
         }

         // specialize to always insert at position 0
         INSERT_ARGUMENTS = 
MethodHandles.insertArguments(insertArguments, 1, 0);
       }

       static MethodHandle createProxyCreatorMethodHandle(Class<?> 
samBase, MethodHandle impl, MethodType invokedType) {
         // curry the SAM class
         MethodHandle asInterFaceInstance = 
MethodHandles.insertArguments(AS_INTERFACE_INSTANCE, 0, samBase);
         // the target of fold must have at least the same parameter 
types as the combiner
         asInterFaceInstance = 
MethodHandles.dropArguments(asInterFaceInstance, 1, 
invokedType.parameterList());

         // curry the method handle impl
         MethodHandle insertArgument = 
MethodHandles.insertArguments(INSERT_ARGUMENTS, 0, impl);
         // adapt to the callsite signature
         MethodHandle combiner = 
insertArgument.asCollector(Object[].class, invokedType.parameterCount()).
                                                asType(invokedType);

         return MethodHandles.foldArguments(asInterFaceInstance, combiner);
       }
     }

cheers,
Rémi



More information about the lambda-dev mailing list