8195694: ConstantBootstraps.invoke does not preserve variable arity

Reviewed-by: jrose
This commit is contained in:
Paul Sandoz 2018-02-01 14:19:04 -08:00
parent 5dc2184391
commit 00b3f917ac
2 changed files with 24 additions and 4 deletions

View File

@ -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 @@ public final class ConstantBootstraps {
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);

View File

@ -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.MethodType;
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 @@ public class ConstantBootstrapsTest {
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,