# HG changeset patch # User psandoz # Date 1517523544 28800 # Node ID 19ef3f64bc1086f152c637fde120c3a6ff45ba75 # Parent 614c7e117327e8ed2c64a6040e99b5a5b299e01d 8195694: ConstantBootstraps.invoke does not preserve variable arity Reviewed-by: jrose diff -r 614c7e117327 -r 19ef3f64bc10 src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.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); diff -r 614c7e117327 -r 19ef3f64bc10 test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java --- 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,