8195694: ConstantBootstraps.invoke does not preserve variable arity
authorpsandoz
Thu, 01 Feb 2018 14:19:04 -0800
changeset 48834 19ef3f64bc10
parent 48833 614c7e117327
child 48835 62004f705d27
child 48856 c866eaca24cb
8195694: ConstantBootstraps.invoke does not preserve variable arity Reviewed-by: jrose
src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java
test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java
--- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java	Thu Feb 01 11:24:39 2018 -0800
+++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java	Thu Feb 01 14:19:04 2018 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -232,7 +232,10 @@
         requireNonNull(args);
 
         if (type != handle.type().returnType()) {
-            handle = handle.asType(handle.type().changeReturnType(type));
+            // 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 Feb 01 11:24:39 2018 -0800
+++ b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java	Thu Feb 01 14:19:04 2018 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8186046
+ * @bug 8186046 8195694
  * @summary Test dynamic constant bootstraps
  * @library /lib/testlibrary/bytecode /java/lang/invoke/common
  * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper
@@ -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,