hg: lambda/lambda/jdk: 3 new changesets

Brian Goetz brian.goetz at oracle.com
Sun Apr 22 07:55:09 PDT 2012


I think this will work too.  I think there's an even simpler way, too -- 
make the factory() method part of the same class, and have its signature be

   factory(MethodHandle, Class, Object[]))

and curry the method handle and class on with 2x bindTo or insertArgs. 
Then just wrap a handle to factory in a ConstantCallSite and be done.

On 4/22/2012 9:30 AM, Rémi Forax wrote:
> 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