< prev index next >

test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java

Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP

*** 25,36 **** * @test * @bug 8186046 8199875 * @summary Test basic invocation of bootstrap methods * @library /lib/testlibrary/bytecode /java/lang/invoke/common * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper ! * @run testng CondyBSMInvocation ! * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMInvocation */ import org.testng.Assert; import org.testng.annotations.Test; --- 25,35 ---- * @test * @bug 8186046 8199875 * @summary Test basic invocation of bootstrap methods * @library /lib/testlibrary/bytecode /java/lang/invoke/common * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper ! * @run testng/timeout=999999 CondyBSMInvocation */ import org.testng.Assert; import org.testng.annotations.Test;
*** 52,72 **** @Test public void testNonexistent() throws Throwable { MethodHandle mh = InstructionHelper.ldcDynamicConstant( ! L, "name", Object.class, ! "bsm", methodType(Object.class), S -> {}); 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 { --- 51,90 ---- @Test public void testNonexistent() throws Throwable { MethodHandle mh = InstructionHelper.ldcDynamicConstant( ! L, "invoke", Object.class, ! "noSuchMethod", methodType(Object.class), S -> {}); try { mh.invoke(); Assert.fail("NoSuchMethodError expected to be thrown"); } catch (NoSuchMethodError e) { } } + @Test + public void testBadExpr() throws Throwable { + MethodHandle mh = InstructionHelper.ldcDynamicConstant( + L, "noSuchExprMode", Object.class, + "bsm", methodType(Object.class), + S -> {}); + + try { + mh.invoke(); + Assert.fail("BootstrapMethodError expected to be thrown"); + } catch (BootstrapMethodError e) { + Assert.assertEquals(e.getCause().getClass(), IllegalArgumentException.class); + // Example: java.lang.IllegalArgumentException: invalid name + // for expression-mode constant: CondyBSMInvocation.bsm()Object + // /invokeStatic/noSuchExprMode:class java.lang.Object[] + + } + } + static MethodHandle[] bsms(String bsmName) { return Stream.of(CondyBSMInvocation.class.getDeclaredMethods()). filter(m -> m.getName().equals(bsmName)). map(m -> { try {
*** 199,208 **** --- 217,256 ---- Object[] staticArgs = Arrays.copyOfRange(args, 2, args.length); assertAll(staticArgs); return Integer.toString(staticArgs.length); } + // expression mode BSMs + public static Object bsm() { + return bsm((MethodHandles.Lookup)null, null, null); + } + public static Object bsm(Object a1) { + return bsm((MethodHandles.Lookup)null, null, null, a1); + } + public static Object bsm(Object a1, Object a2) { + return bsm((MethodHandles.Lookup)null, null, null, a1, a2); + } + public static Object bsm(Object a1, Object a2, Object a3) { + return bsm((MethodHandles.Lookup)null, null, null, a1, a2, a3); + } + public static Object bsm(Object a1, Object a2, Object a3, Object a4) { + return bsm((MethodHandles.Lookup)null, null, null, a1, a2, a3, a4); + } + public static Object bsm(Object a1, Object a2, Object a3, Object a4, Object a5) { + return bsm((MethodHandles.Lookup)null, null, null, a1, a2, a3, a4, a5); + } + public static Object bsm(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { + return bsm((MethodHandles.Lookup)null, null, null, a1, a2, a3, a4, a5, a6); + } + public static Object bsm(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { + return bsm((MethodHandles.Lookup)null, null, null, a1, a2, a3, a4, a5, a6, a7); + } + public static Object bsm(Object... args) { + assertAll(args); + return Integer.toString(args.length); + } + static void assertAll(Object... as) { for (int i = 0; i < as.length; i++) { Assert.assertEquals(as[i], i); } }
*** 236,246 **** } } @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( --- 284,351 ---- } } @Test ! public void testArityWithoutMetadata() throws Throwable { ! for (int i = 0; i < 8; i++) { ! final int n = i; ! MethodType mt = methodType(Object.class) ! .appendParameterTypes(Collections.nCopies(n, Object.class)); ! MethodHandle mh = InstructionHelper.ldcDynamicConstant( ! L, "invoke", Object.class, ! "bsm", mt, ! S -> IntStream.range(0, n).forEach(S::add) ! ); ! ! Object r = mh.invoke(); ! Assert.assertEquals(r, Integer.toString(n)); ! } ! ! { ! MethodType mt = methodType(Object.class, Object[].class); ! MethodHandle mh = InstructionHelper.ldcDynamicConstant( ! L, "invoke", Object.class, ! "bsm", mt, ! S -> IntStream.range(0, 9).forEach(S::add) ! ); ! ! Object r = mh.invoke(); ! Assert.assertEquals(r, Integer.toString(9)); ! } ! } ! @Test ! public void testArityAsSymbolic() throws Throwable { ! for (int i = 0; i < 8; i++) { ! final int n = i; ! MethodType mt = methodType(Object.class) ! .appendParameterTypes(Collections.nCopies(n, Object.class)); ! MethodHandle mh = InstructionHelper.ldcDynamicConstant( ! L, "symbolic", Object.class, ! "bsm", mt, ! S -> IntStream.range(0, n).forEach(S::add) ! ); ! ! Object r = mh.invoke(); ! Assert.assertEquals(r, Integer.toString(n)); ! } ! ! { ! MethodType mt = methodType(Object.class, Object[].class); ! MethodHandle mh = InstructionHelper.ldcDynamicConstant( ! L, "symbolic", Object.class, ! "bsm", mt, ! S -> IntStream.range(0, 9).forEach(S::add) ! ); ! ! Object r = mh.invoke(); ! Assert.assertEquals(r, Integer.toString(9)); ! } ! } ! ! @Test ! public void testWrongNumberOfStaticArgumentsWithMetaData() 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(
*** 256,261 **** --- 361,389 ---- Throwable t = e.getCause(); Assert.assertTrue(WrongMethodTypeException.class.isAssignableFrom(t.getClass())); } } } + + @Test + public void testWrongNumberOfStaticArgumentsWithoutMetaData() throws Throwable { + for (int i = 1; i < 8; i++) { + final int n = i; + MethodType mt = methodType(Object.class) + .appendParameterTypes(Collections.nCopies(n, Object.class)); + MethodHandle mh = InstructionHelper.ldcDynamicConstant( + L, "invoke", Object.class, + "bsm", mt, + S -> IntStream.range(0, n - 1).forEach(S::add) + ); + + 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())); + } + } + } + }
< prev index next >