jdk-24/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java
Adam Sotona 2b00ac0d02 8308753: Class-File API transition to Preview
Reviewed-by: ihse, mchung, vromero
2023-12-04 07:07:57 +00:00

262 lines
8.6 KiB
Java

/*
* 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8186046 8199875
* @summary Test basic invocation of bootstrap methods
* @library /java/lang/invoke/common
* @build test.java.lang.invoke.lib.InstructionHelper
* @enablePreview
* @run testng CondyBSMInvocation
* @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMInvocation
*/
import org.testng.Assert;
import org.testng.annotations.Test;
import test.java.lang.invoke.lib.InstructionHelper;
import java.lang.constant.ConstantDesc;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.WrongMethodTypeException;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.lang.invoke.MethodType.methodType;
public class CondyBSMInvocation {
static final MethodHandles.Lookup L = MethodHandles.lookup();
@Test
public void testNonexistent() throws Throwable {
MethodHandle mh = InstructionHelper.ldcDynamicConstant(
L, "name", Object.class,
"bsm", methodType(Object.class)
);
try {
mh.invoke();
Assert.fail("NoSuchMethodError expected to be thrown");
} catch (NoSuchMethodError e) {
}
}
static MethodHandle[] bsms(String bsmName) {
return Stream.of(CondyBSMInvocation.class.getDeclaredMethods()).
filter(m -> m.getName().equals(bsmName)).
map(m -> {
try {
return MethodHandles.lookup().unreflect(m);
} catch (IllegalAccessException e) {
throw new RuntimeException();
}
}).toArray(MethodHandle[]::new);
}
public static Object shape_bsm() {
return "0";
}
public static Object shape_bsm(Object a1) {
return "0";
}
public static Object shape_bsm(Object... args) {
return "0";
}
public static Object shape_bsm(Object a1, Object a2) {
return "0";
}
public static Object shape_bsm(Object a1, Object... args) {
return "0";
}
public static Object shape_bsm(Object a1, Object a2, Object a3) {
return "0";
}
public static Object shape_bsm(MethodHandles.Lookup a1) {
return "0";
}
@Test
public void testWrongShape() throws Throwable {
for (MethodHandle bsm : bsms("shape_bsm")) {
MethodHandle mh = InstructionHelper.ldcDynamicConstant(
L, "name", Object.class,
"shape_bsm", bsm.type()
);
try {
Object r = mh.invoke();
Assert.fail("BootstrapMethodError expected to be thrown for " + bsm);
} catch (BootstrapMethodError e) {
}
}
}
public static Object sig_bsm(MethodHandles.Lookup a1, String[] a2) {
return "0";
}
public static Object sig_bsm(MethodHandles.Lookup a1, String a2, String a3) {
return "0";
}
@Test
public void testWrongSignature() throws Throwable {
for (MethodHandle bsm : bsms("sig_bsm")) {
MethodHandle mh = InstructionHelper.ldcDynamicConstant(
L, "name", Object.class,
"sig_bsm", bsm.type()
);
try {
Object r = mh.invoke();
Assert.fail("BootstrapMethodError expected to be thrown for " + bsm);
} catch (BootstrapMethodError e) {
}
}
}
public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type) {
return "0";
}
public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
Object a1) {
assertAll(a1);
return "1";
}
public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
Object a1, Object a2) {
assertAll(a1, a2);
return "2";
}
public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
Object a1, Object a2, Object a3) {
assertAll(a1, a2, a3);
return "3";
}
public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
Object a1, Object a2, Object a3, Object a4) {
assertAll(a1, a2, a3, a4);
return "4";
}
public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
Object a1, Object a2, Object a3, Object a4, Object a5) {
assertAll(a1, a2, a3, a4, a5);
return "5";
}
public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) {
assertAll(a1, a2, a3, a4, a5, a6);
return "6";
}
public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) {
assertAll(a1, a2, a3, a4, a5, a6, a7);
return "7";
}
public static Object bsm(MethodHandles.Lookup l, Object... args) {
Object[] staticArgs = Arrays.copyOfRange(args, 2, args.length);
assertAll(staticArgs);
return Integer.toString(staticArgs.length);
}
static void assertAll(Object... as) {
for (int i = 0; i < as.length; i++) {
Assert.assertEquals(as[i], i);
}
}
@Test
public void testArity() throws Throwable {
for (int i = 0; i < 8; i++) {
final int n = i;
MethodType mt = methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class)
.appendParameterTypes(Collections.nCopies(n, Object.class));
MethodHandle mh = InstructionHelper.ldcDynamicConstant(
L, "name", Object.class,
"bsm", mt,
IntStream.range(0, n).boxed().toArray(ConstantDesc[]::new)
);
Object r = mh.invoke();
Assert.assertEquals(r, Integer.toString(n));
}
{
MethodType mt = methodType(Object.class, MethodHandles.Lookup.class, Object[].class);
MethodHandle mh = InstructionHelper.ldcDynamicConstant(
L, "name", Object.class,
"bsm", mt,
IntStream.range(0, 9).boxed().toArray(ConstantDesc[]::new)
);
Object r = mh.invoke();
Assert.assertEquals(r, Integer.toString(9));
}
}
@Test
public void testWrongNumberOfStaticArguments() throws Throwable {
for (int i = 1; i < 8; i++) {
final int n = i;
MethodType mt = methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class)
.appendParameterTypes(Collections.nCopies(n, Object.class));
MethodHandle mh = InstructionHelper.ldcDynamicConstant(
L, "name", Object.class,
"bsm", mt,
IntStream.range(0, n - 1).boxed().toArray(ConstantDesc[]::new)
);
try {
Object r = mh.invoke();
Assert.fail("BootstrapMethodError expected to be thrown for arrity " + n);
} catch (BootstrapMethodError e) {
Throwable t = e.getCause();
Assert.assertTrue(WrongMethodTypeException.class.isAssignableFrom(t.getClass()));
}
}
}
}