test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java
changeset 49576 535498e7602f
parent 48826 c4d9d1b08e2e
equal deleted inserted replaced
49575:3a2172d8613a 49576:535498e7602f
     1 /*
     1 /*
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 
    23 
    24 /*
    24 /*
    25  * @test
    25  * @test
    26  * @bug 8186046
    26  * @bug 8186046 8199875
    27  * @summary Test basic invocation of bootstrap methods
    27  * @summary Test basic invocation of bootstrap methods
    28  * @library /lib/testlibrary/bytecode /java/lang/invoke/common
    28  * @library /lib/testlibrary/bytecode /java/lang/invoke/common
    29  * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper
    29  * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper
    30  * @run testng CondyBSMInvocation
    30  * @run testng CondyBSMInvocation
    31  * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMInvocation
    31  * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMInvocation
    38 
    38 
    39 import java.lang.invoke.MethodHandle;
    39 import java.lang.invoke.MethodHandle;
    40 import java.lang.invoke.MethodHandles;
    40 import java.lang.invoke.MethodHandles;
    41 import java.lang.invoke.MethodType;
    41 import java.lang.invoke.MethodType;
    42 import java.lang.invoke.WrongMethodTypeException;
    42 import java.lang.invoke.WrongMethodTypeException;
       
    43 import java.util.Arrays;
    43 import java.util.Collections;
    44 import java.util.Collections;
    44 import java.util.stream.IntStream;
    45 import java.util.stream.IntStream;
       
    46 import java.util.stream.Stream;
    45 
    47 
    46 import static java.lang.invoke.MethodType.methodType;
    48 import static java.lang.invoke.MethodType.methodType;
    47 
    49 
    48 public class CondyBSMInvocation {
    50 public class CondyBSMInvocation {
    49     static final MethodHandles.Lookup L = MethodHandles.lookup();
    51     static final MethodHandles.Lookup L = MethodHandles.lookup();
    61             Assert.fail("NoSuchMethodError expected to be thrown");
    63             Assert.fail("NoSuchMethodError expected to be thrown");
    62         } catch (NoSuchMethodError e) {
    64         } catch (NoSuchMethodError e) {
    63         }
    65         }
    64     }
    66     }
    65 
    67 
    66 
    68     static MethodHandle[] bsms(String bsmName) {
    67     public static Object _bsm() {
    69         return Stream.of(CondyBSMInvocation.class.getDeclaredMethods()).
    68         return "0";
    70                 filter(m -> m.getName().equals(bsmName)).
    69     }
    71                 map(m -> {
    70 
    72                     try {
    71     public static Object _bsm(Object a1) {
    73                         return MethodHandles.lookup().unreflect(m);
    72         return "0";
    74                     } catch (IllegalAccessException e) {
    73     }
    75                         throw new RuntimeException();
    74 
    76                     }
    75     // Note: when pull mode is supported for a BSM this test case
    77                 }).toArray(MethodHandle[]::new);
    76     //       will fail and must be removed
    78     }
    77     public static Object _bsm(Object a1, Object a2) {
    79 
    78         return "0";
    80     public static Object shape_bsm() {
    79     }
    81         return "0";
    80 
    82     }
    81     @Test
    83 
    82     public void testWrongArity() throws Throwable {
    84     public static Object shape_bsm(Object a1) {
    83         for (int i = 0; i < 3; i++) {
    85         return "0";
       
    86     }
       
    87 
       
    88     public static Object shape_bsm(Object... args) {
       
    89         return "0";
       
    90     }
       
    91 
       
    92     public static Object shape_bsm(Object a1, Object a2) {
       
    93         return "0";
       
    94     }
       
    95 
       
    96     public static Object shape_bsm(Object a1, Object... args) {
       
    97         return "0";
       
    98     }
       
    99 
       
   100     public static Object shape_bsm(Object a1, Object a2, Object a3) {
       
   101         return "0";
       
   102     }
       
   103 
       
   104     public static Object shape_bsm(MethodHandles.Lookup a1) {
       
   105         return "0";
       
   106     }
       
   107 
       
   108     @Test
       
   109     public void testWrongShape() throws Throwable {
       
   110         for (MethodHandle bsm : bsms("shape_bsm")) {
       
   111             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
       
   112                     L, "name", Object.class,
       
   113                     "shape_bsm", bsm.type(),
       
   114                     S -> {}
       
   115             );
       
   116 
       
   117             try {
       
   118                 Object r = mh.invoke();
       
   119                 Assert.fail("BootstrapMethodError expected to be thrown for " + bsm);
       
   120             } catch (BootstrapMethodError e) {
       
   121             }
       
   122         }
       
   123     }
       
   124 
       
   125 
       
   126     public static Object sig_bsm(MethodHandles.Lookup a1, String[] a2) {
       
   127         return "0";
       
   128     }
       
   129 
       
   130     public static Object sig_bsm(MethodHandles.Lookup a1, String a2, String a3) {
       
   131         return "0";
       
   132     }
       
   133 
       
   134     @Test
       
   135     public void testWrongSignature() throws Throwable {
       
   136         for (MethodHandle bsm : bsms("sig_bsm")) {
       
   137             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
       
   138                     L, "name", Object.class,
       
   139                     "sig_bsm", bsm.type(),
       
   140                     S -> {}
       
   141             );
       
   142 
       
   143             try {
       
   144                 Object r = mh.invoke();
       
   145                 Assert.fail("BootstrapMethodError expected to be thrown for " + bsm);
       
   146             } catch (BootstrapMethodError e) {
       
   147             }
       
   148         }
       
   149     }
       
   150 
       
   151 
       
   152     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type) {
       
   153         return "0";
       
   154     }
       
   155 
       
   156     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   157                              Object a1) {
       
   158         assertAll(a1);
       
   159         return "1";
       
   160     }
       
   161 
       
   162     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   163                              Object a1, Object a2) {
       
   164         assertAll(a1, a2);
       
   165         return "2";
       
   166     }
       
   167 
       
   168     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   169                              Object a1, Object a2, Object a3) {
       
   170         assertAll(a1, a2, a3);
       
   171         return "3";
       
   172     }
       
   173 
       
   174     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   175                              Object a1, Object a2, Object a3, Object a4) {
       
   176         assertAll(a1, a2, a3, a4);
       
   177         return "4";
       
   178     }
       
   179 
       
   180     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   181                              Object a1, Object a2, Object a3, Object a4, Object a5) {
       
   182         assertAll(a1, a2, a3, a4, a5);
       
   183         return "5";
       
   184     }
       
   185 
       
   186     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   187                              Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) {
       
   188         assertAll(a1, a2, a3, a4, a5, a6);
       
   189         return "6";
       
   190     }
       
   191 
       
   192     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   193                              Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) {
       
   194         assertAll(a1, a2, a3, a4, a5, a6, a7);
       
   195         return "7";
       
   196     }
       
   197 
       
   198     public static Object bsm(MethodHandles.Lookup l, Object... args) {
       
   199         Object[] staticArgs = Arrays.copyOfRange(args, 2, args.length);
       
   200         assertAll(staticArgs);
       
   201         return Integer.toString(staticArgs.length);
       
   202     }
       
   203 
       
   204     static void assertAll(Object... as) {
       
   205         for (int i = 0; i < as.length; i++) {
       
   206             Assert.assertEquals(as[i], i);
       
   207         }
       
   208     }
       
   209 
       
   210     @Test
       
   211     public void testArity() throws Throwable {
       
   212         for (int i = 0; i < 8; i++) {
    84             final int n = i;
   213             final int n = i;
    85             MethodType mt = methodType(Object.class)
   214             MethodType mt = methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class)
    86                     .appendParameterTypes(Collections.nCopies(n, Object.class));
   215                     .appendParameterTypes(Collections.nCopies(n, Object.class));
    87             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
   216             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
    88                     L, "name", Object.class,
   217                     L, "name", Object.class,
    89                     "_bsm", mt,
   218                     "bsm", mt,
    90                     S -> IntStream.range(0, n).forEach(S::add)
   219                     S -> IntStream.range(0, n).forEach(S::add)
       
   220                     );
       
   221 
       
   222             Object r = mh.invoke();
       
   223             Assert.assertEquals(r, Integer.toString(n));
       
   224         }
       
   225 
       
   226         {
       
   227             MethodType mt = methodType(Object.class, MethodHandles.Lookup.class, Object[].class);
       
   228             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
       
   229                     L, "name", Object.class,
       
   230                     "bsm", mt,
       
   231                     S -> IntStream.range(0, 9).forEach(S::add)
       
   232             );
       
   233 
       
   234             Object r = mh.invoke();
       
   235             Assert.assertEquals(r, Integer.toString(9));
       
   236 
       
   237         }
       
   238     }
       
   239 
       
   240     @Test
       
   241     public void testWrongNumberOfStaticArguments() throws Throwable {
       
   242         for (int i = 1; i < 8; i++) {
       
   243             final int n = i;
       
   244             MethodType mt = methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class)
       
   245                     .appendParameterTypes(Collections.nCopies(n, Object.class));
       
   246             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
       
   247                     L, "name", Object.class,
       
   248                     "bsm", mt,
       
   249                     S -> IntStream.range(0, n - 1).forEach(S::add)
    91             );
   250             );
    92 
   251 
    93             try {
   252             try {
    94                 Object r = mh.invoke();
   253                 Object r = mh.invoke();
    95                 Assert.fail("BootstrapMethodError expected to be thrown for arrity " + n);
   254                 Assert.fail("BootstrapMethodError expected to be thrown for arrity " + n);
    97                 Throwable t = e.getCause();
   256                 Throwable t = e.getCause();
    98                 Assert.assertTrue(WrongMethodTypeException.class.isAssignableFrom(t.getClass()));
   257                 Assert.assertTrue(WrongMethodTypeException.class.isAssignableFrom(t.getClass()));
    99             }
   258             }
   100         }
   259         }
   101     }
   260     }
   102 
       
   103 
       
   104     public static Object _bsm(String[] ss) {
       
   105         return "0";
       
   106     }
       
   107 
       
   108     public static Object _bsm(String a1, String a2, String a3) {
       
   109         return "0";
       
   110     }
       
   111 
       
   112     @Test
       
   113     public void testWrongSignature() throws Throwable {
       
   114         {
       
   115             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
       
   116                     L, "name", Object.class,
       
   117                     "_bsm", methodType(Object.class, String[].class),
       
   118                     S -> {}
       
   119             );
       
   120 
       
   121             try {
       
   122                 Object r = mh.invoke();
       
   123                 Assert.fail("BootstrapMethodError expected to be thrown");
       
   124             }
       
   125             catch (BootstrapMethodError e) {
       
   126                 Throwable t = e.getCause();
       
   127                 Assert.assertTrue(WrongMethodTypeException.class.isAssignableFrom(t.getClass()));
       
   128             }
       
   129         }
       
   130 
       
   131         {
       
   132             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
       
   133                     L, "name", Object.class,
       
   134                     "_bsm", methodType(Object.class, String.class, String.class, String.class),
       
   135                     S -> {}
       
   136             );
       
   137 
       
   138             try {
       
   139                 Object r = mh.invoke();
       
   140                 Assert.fail("BootstrapMethodError expected to be thrown");
       
   141             }
       
   142             catch (BootstrapMethodError e) {
       
   143                 Throwable t = e.getCause();
       
   144                 Assert.assertTrue(ClassCastException.class.isAssignableFrom(t.getClass()));
       
   145             }
       
   146         }
       
   147     }
       
   148 
       
   149 
       
   150     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type) {
       
   151         return "0";
       
   152     }
       
   153 
       
   154     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   155                              Object a1) {
       
   156         assertAll(a1);
       
   157         return "1";
       
   158     }
       
   159 
       
   160     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   161                              Object a1, Object a2) {
       
   162         assertAll(a1, a2);
       
   163         return "2";
       
   164     }
       
   165 
       
   166     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   167                              Object a1, Object a2, Object a3) {
       
   168         assertAll(a1, a2, a3);
       
   169         return "3";
       
   170     }
       
   171 
       
   172     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   173                              Object a1, Object a2, Object a3, Object a4) {
       
   174         assertAll(a1, a2, a3, a4);
       
   175         return "4";
       
   176     }
       
   177 
       
   178     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   179                              Object a1, Object a2, Object a3, Object a4, Object a5) {
       
   180         assertAll(a1, a2, a3, a4, a5);
       
   181         return "5";
       
   182     }
       
   183 
       
   184     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   185                              Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) {
       
   186         assertAll(a1, a2, a3, a4, a5, a6);
       
   187         return "6";
       
   188     }
       
   189 
       
   190     public static Object bsm(MethodHandles.Lookup l, String name, Class<?> type,
       
   191                              Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) {
       
   192         assertAll(a1, a2, a3, a4, a5, a6, a7);
       
   193         return "7";
       
   194     }
       
   195 
       
   196     static void assertAll(Object... as) {
       
   197         for (int i = 0; i < as.length; i++) {
       
   198             Assert.assertEquals(as[i], i);
       
   199         }
       
   200     }
       
   201 
       
   202     @Test
       
   203     public void testArity() throws Throwable {
       
   204         for (int i = 0; i < 8; i++) {
       
   205             final int n = i;
       
   206             MethodType mt = methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class)
       
   207                     .appendParameterTypes(Collections.nCopies(n, Object.class));
       
   208             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
       
   209                     L, "name", Object.class,
       
   210                     "bsm", mt,
       
   211                     S -> IntStream.range(0, n).forEach(S::add)
       
   212                     );
       
   213 
       
   214             Object r = mh.invoke();
       
   215             Assert.assertEquals(r, Integer.toString(n));
       
   216         }
       
   217     }
       
   218 
       
   219     @Test
       
   220     public void testWrongNumberOfStaticArguments() throws Throwable {
       
   221         for (int i = 1; i < 8; i++) {
       
   222             final int n = i;
       
   223             MethodType mt = methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class)
       
   224                     .appendParameterTypes(Collections.nCopies(n, Object.class));
       
   225             MethodHandle mh = InstructionHelper.ldcDynamicConstant(
       
   226                     L, "name", Object.class,
       
   227                     "bsm", mt,
       
   228                     S -> IntStream.range(0, n - 1).forEach(S::add)
       
   229             );
       
   230 
       
   231             try {
       
   232                 Object r = mh.invoke();
       
   233                 Assert.fail("BootstrapMethodError expected to be thrown for arrity " + n);
       
   234             } catch (BootstrapMethodError e) {
       
   235                 Throwable t = e.getCause();
       
   236                 Assert.assertTrue(WrongMethodTypeException.class.isAssignableFrom(t.getClass()));
       
   237             }
       
   238         }
       
   239     }
       
   240 }
   261 }