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