8195694: ConstantBootstraps.invoke does not preserve variable arity
Reviewed-by: jrose
--- 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,