changeset 48754:51f4e03f19d5 condy-folding

Fix the invoke bootstrap to preserve variable arity when an asType transformation is performed.
author psandoz
date Thu, 18 Jan 2018 09:21:31 -0800
parents 99310492a0e6
children 16e5f1091f33
files src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java
diffstat 2 files changed, 24 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java	Thu Jan 18 10:35:38 2018 -0500
+++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java	Thu Jan 18 09:21:31 2018 -0800
@@ -242,6 +242,13 @@
         requireNonNull(handle);
         requireNonNull(args);
 
+        if (type != handle.type().returnType()) {
+            // Adjust the return type of the handle to be invoked while
+            // preserving variable arity if present
+            handle = handle.asType(handle.type().changeReturnType(type)).
+                    withVarargs(handle.isVarargsCollector());
+        }
+
         return handle.invokeWithArguments(args);
     }
 
--- a/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java	Thu Jan 18 10:35:38 2018 -0500
+++ b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java	Thu Jan 18 09:21:31 2018 -0800
@@ -43,6 +43,7 @@
 import java.lang.invoke.VarHandle;
 import java.lang.invoke.WrongMethodTypeException;
 import java.math.BigInteger;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -189,6 +190,22 @@
         assertEquals(handle.invoke(), 42);
     }
 
+    public void testInvokeAsTypeVariableArity() throws Throwable {
+        // The constant type is Collection but the invoke return type is List
+        var handle = InstructionHelper.ldcDynamicConstant(
+                L, "_", Collection.class,
+                ConstantBootstraps.class, "invoke", lookupMT(Object.class, MethodHandle.class, Object[].class),
+                S -> {
+                    S.add("", (P, Z) -> {
+                        return P.putHandle(MethodHandleInfo.REF_invokeStatic, "java/util/List", "of",
+                                           MethodType.methodType(List.class, Object[].class).toMethodDescriptorString(),
+                                           true);
+                    });
+                    S.add(1).add(2).add(3).add(4);
+                });
+        assertEquals(handle.invoke(), List.of(1, 2, 3, 4));
+    }
+
     @Test(expectedExceptions = ClassCastException.class)
     public void testInvokeAsTypeClassCast() throws Throwable {
         ConstantBootstraps.invoke(MethodHandles.lookup(), "_", String.class,