hg: lambda/lambda/jdk: 3 new changesets (original) (raw)

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 INSERTARGUMENTS; private static final MethodHandle ASINTERFACEINSTANCE; static { Lookup lookup = MethodHandles.Lookup.IMPLLOOKUP; MethodHandle insertArguments; try { insertArguments = lookup.findStatic(MethodHandles.class, "insertArguments", MethodType.methodType(MethodHandle.class, MethodHandle.class, int.class, Object[].class)); ASINTERFACEINSTANCE = 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 INSERTARGUMENTS = MethodHandles.insertArguments(insertArguments, 1, 0); } static MethodHandle createProxyCreatorMethodHandle(Class<?> samBase, MethodHandle impl, MethodType invokedType) { // curry the SAM class MethodHandle asInterFaceInstance = MethodHandles.insertArguments(ASINTERFACEINSTANCE, 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(INSERTARGUMENTS, 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