< prev index next >

test/java/lang/invoke/LoopCombinatorTest.java

Print this page
rev 14276 : 8154754: MethodHandles.countedLoop errors in deriving loop arguments, result type, and local state


  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /* @test
  27  * @bug 8139885
  28  * @bug 8150635
  29  * @bug 8150956
  30  * @bug 8150957
  31  * @bug 8152667
  32  * @bug 8153637
  33  * @bug 8154751

  34  * @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest
  35  */
  36 
  37 package test.java.lang.invoke;
  38 
  39 import java.lang.invoke.MethodHandle;
  40 import java.lang.invoke.MethodHandles;
  41 import java.lang.invoke.MethodHandles.Lookup;
  42 import java.lang.invoke.MethodType;
  43 import java.util.*;
  44 
  45 import static java.lang.invoke.MethodType.methodType;
  46 
  47 import static org.testng.AssertJUnit.*;
  48 
  49 import org.testng.annotations.*;
  50 
  51 /**
  52  * Tests for the loop combinators introduced in JEP 274.
  53  */


 310     @Test
 311     public static void testCountedArrayLoop() throws Throwable {
 312         // int[] a = new int[]{0}; for (int i = 0; i < 13; ++i) { ++a[0]; } => a[0] == 13
 313         MethodHandle fit13 = MethodHandles.dropArguments(MethodHandles.constant(int.class, 13), 0, int[].class);
 314         MethodHandle loop = MethodHandles.countedLoop(fit13, null, Counted.MH_stepUpdateArray);
 315         assertEquals(Counted.MT_arrayCounted, loop.type());
 316         int[] a = new int[]{0};
 317         loop.invoke(a);
 318         assertEquals(13, a[0]);
 319     }
 320 
 321     @Test
 322     public static void testCountedPrintingLoop() throws Throwable {
 323         MethodHandle fit5 = MethodHandles.constant(int.class, 5);
 324         MethodHandle loop = MethodHandles.countedLoop(fit5, null, Counted.MH_printHello);
 325         assertEquals(Counted.MT_countedPrinting, loop.type());
 326         loop.invoke();
 327     }
 328 
 329     @Test




































































 330     public static void testCountedRangeLoop() throws Throwable {
 331         // String s = "Lambdaman!"; for (int i = -5; i < 8; ++i) { s = "na " + s; } return s; => a well known theme
 332         MethodHandle fitm5 = MethodHandles.dropArguments(Counted.MH_m5, 0, String.class);
 333         MethodHandle fit8 = MethodHandles.dropArguments(Counted.MH_8, 0, String.class);
 334         MethodHandle loop = MethodHandles.countedLoop(fitm5, fit8, Counted.MH_start, Counted.MH_step);
 335         assertEquals(Counted.MT_counted, loop.type());
 336         assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
 337     }
 338 
 339     @Test
 340     public static void testCountedLoopCounterInit() throws Throwable {
 341         // int x = 0; for (int i = 0; i < 5; ++i) { x += i; } return x; => 10
 342         // (only if counter's first value in body is 0)
 343         MethodHandle iter = MethodHandles.constant(int.class, 5);
 344         MethodHandle init = MethodHandles.constant(int.class, 0);
 345         MethodHandle body = Counted.MH_addCounter;
 346         MethodHandle loop = MethodHandles.countedLoop(iter, init, body);
 347         assertEquals(Counted.MT_counterInit, loop.type());
 348         assertEquals(10, loop.invoke());
 349     }


 822         static String start(String arg) {
 823             return arg;
 824         }
 825 
 826         static String step(int counter, String v, String arg) {
 827             return "na " + v;
 828         }
 829 
 830         static void stepUpdateArray(int counter, int[] a) {
 831             ++a[0];
 832         }
 833 
 834         static void printHello(int counter) {
 835             System.out.print("hello");
 836         }
 837 
 838         static int addCounter(int counter, int x) {
 839             return x + counter;
 840         }
 841 











 842         static final Class<Counted> COUNTED = Counted.class;
 843 
 844         static final MethodType MT_start = methodType(String.class, String.class);
 845         static final MethodType MT_step = methodType(String.class, int.class, String.class, String.class);
 846         static final MethodType MT_stepUpdateArray = methodType(void.class, int.class, int[].class);
 847         static final MethodType MT_printHello = methodType(void.class, int.class);
 848         static final MethodType MT_addCounter = methodType(int.class, int.class, int.class);


 849 
 850         static final MethodHandle MH_13;
 851         static final MethodHandle MH_m5;
 852         static final MethodHandle MH_8;
 853         static final MethodHandle MH_start;
 854         static final MethodHandle MH_step;
 855         static final MethodHandle MH_stepUpdateArray;
 856         static final MethodHandle MH_printHello;
 857         static final MethodHandle MH_addCounter;


 858 
 859         static final MethodType MT_counted = methodType(String.class, String.class);
 860         static final MethodType MT_arrayCounted = methodType(void.class, int[].class);
 861         static final MethodType MT_countedPrinting = methodType(void.class);
 862         static final MethodType MT_counterInit = methodType(int.class);


 863 
 864         static {
 865             try {
 866                 MH_13 = MethodHandles.constant(int.class, 13);
 867                 MH_m5 = MethodHandles.constant(int.class, -5);
 868                 MH_8 = MethodHandles.constant(int.class, 8);
 869                 MH_start = LOOKUP.findStatic(COUNTED, "start", MT_start);
 870                 MH_step = LOOKUP.findStatic(COUNTED, "step", MT_step);
 871                 MH_stepUpdateArray = LOOKUP.findStatic(COUNTED, "stepUpdateArray", MT_stepUpdateArray);
 872                 MH_printHello = LOOKUP.findStatic(COUNTED, "printHello", MT_printHello);
 873                 MH_addCounter = LOOKUP.findStatic(COUNTED, "addCounter", MT_addCounter);


 874             } catch (Exception e) {
 875                 throw new ExceptionInInitializerError(e);
 876             }
 877         }
 878 
 879     }
 880 
 881     static class Iterate {
 882 
 883         static Iterator<Integer> sumIterator(Integer[] a) {
 884             return Arrays.asList(a).iterator();
 885         }
 886 
 887         static int sumInit(Integer[] a) {
 888             return 0;
 889         }
 890 
 891         static int sumStep(int s, int e, Integer[] a) {
 892             return s + e;
 893         }




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /* @test
  27  * @bug 8139885
  28  * @bug 8150635
  29  * @bug 8150956
  30  * @bug 8150957
  31  * @bug 8152667
  32  * @bug 8153637
  33  * @bug 8154751
  34  * @bug 8154754
  35  * @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest
  36  */
  37 
  38 package test.java.lang.invoke;
  39 
  40 import java.lang.invoke.MethodHandle;
  41 import java.lang.invoke.MethodHandles;
  42 import java.lang.invoke.MethodHandles.Lookup;
  43 import java.lang.invoke.MethodType;
  44 import java.util.*;
  45 
  46 import static java.lang.invoke.MethodType.methodType;
  47 
  48 import static org.testng.AssertJUnit.*;
  49 
  50 import org.testng.annotations.*;
  51 
  52 /**
  53  * Tests for the loop combinators introduced in JEP 274.
  54  */


 311     @Test
 312     public static void testCountedArrayLoop() throws Throwable {
 313         // int[] a = new int[]{0}; for (int i = 0; i < 13; ++i) { ++a[0]; } => a[0] == 13
 314         MethodHandle fit13 = MethodHandles.dropArguments(MethodHandles.constant(int.class, 13), 0, int[].class);
 315         MethodHandle loop = MethodHandles.countedLoop(fit13, null, Counted.MH_stepUpdateArray);
 316         assertEquals(Counted.MT_arrayCounted, loop.type());
 317         int[] a = new int[]{0};
 318         loop.invoke(a);
 319         assertEquals(13, a[0]);
 320     }
 321 
 322     @Test
 323     public static void testCountedPrintingLoop() throws Throwable {
 324         MethodHandle fit5 = MethodHandles.constant(int.class, 5);
 325         MethodHandle loop = MethodHandles.countedLoop(fit5, null, Counted.MH_printHello);
 326         assertEquals(Counted.MT_countedPrinting, loop.type());
 327         loop.invoke();
 328     }
 329 
 330     @Test
 331     public static void testCountedLoopNullBody() throws Throwable {
 332         MethodHandle h5 = MethodHandles.constant(int.class, 5);
 333         MethodHandle h13 = MethodHandles.constant(int.class, 13);
 334         MethodHandle loop = MethodHandles.countedLoop(h5, h13, null);
 335         assertEquals(methodType(int.class), loop.type());
 336         assertEquals(13, loop.invoke());
 337     }
 338 
 339     @Test
 340     public static void testCountedLoopNullIterations() throws Throwable {
 341         MethodHandle loop = MethodHandles.countedLoop(null, null, null);
 342         assertEquals(methodType(void.class), loop.type());
 343         loop.invoke();
 344     }
 345 
 346     @Test
 347     public static void testCountedLoopNullInitAndBody() throws Throwable {
 348         MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null);
 349         assertEquals(methodType(void.class), loop.type());
 350         loop.invoke();
 351     }
 352 
 353     @DataProvider
 354     static Object[][] countedLoopBodyParameters() {
 355         return new Object[][] {
 356                 {methodType(String.class), methodType(String.class, int.class)},
 357                 {methodType(String.class, List.class), methodType(String.class, int.class)},
 358                 {methodType(String.class, List.class), methodType(String.class, int.class, String.class)}
 359         };
 360     }
 361 
 362     @Test(dataProvider = "countedLoopBodyParameters")
 363     public static void testCountedLoopBodyParameters(MethodType initType, MethodType bodyType) throws Throwable {
 364         MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5),
 365                 MethodHandles.empty(initType), MethodHandles.empty(bodyType));
 366         assertEquals(initType, loop.type());
 367     }
 368 
 369     @DataProvider
 370     static Object[][] countedLoopTypes() {
 371         return new Object[][]{{void.class}, {int.class}, {Object.class}, {String.class}, {List.class}};
 372     }
 373 
 374     @Test(dataProvider = "countedLoopTypes")
 375     public static void testCountedLoopBodyParametersNullInit(Class<?> t) throws Throwable {
 376         MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null,
 377                 MethodHandles.empty(methodType(t, int.class)));
 378         assertEquals(methodType(t), loop.type());
 379         loop.invoke();
 380     }
 381 
 382     @Test
 383     public static void testCountedLoopStateDefinedByBody() throws Throwable {
 384         MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, Counted.MH_stateBody);
 385         assertEquals(Counted.MT_bodyDeterminesState, loop.type());
 386         assertEquals("sssssnull01234", loop.invoke());
 387     }
 388 
 389     @Test
 390     public static void testCountedLoopArgsDefinedByIterations() throws Throwable {
 391         MethodHandle loop = MethodHandles.countedLoop(
 392                 MethodHandles.dropArguments(MethodHandles.constant(int.class, 3), 0, String.class),
 393                 null, Counted.MH_append);
 394         assertEquals(Counted.MT_iterationsDefineArgs, loop.type());
 395         assertEquals("hello012", loop.invoke("hello"));
 396     }
 397 
 398     @Test
 399     public static void testCountedRangeLoop() throws Throwable {
 400         // String s = "Lambdaman!"; for (int i = -5; i < 8; ++i) { s = "na " + s; } return s; => a well known theme
 401         MethodHandle fitm5 = MethodHandles.dropArguments(Counted.MH_m5, 0, String.class);
 402         MethodHandle fit8 = MethodHandles.dropArguments(Counted.MH_8, 0, String.class);
 403         MethodHandle loop = MethodHandles.countedLoop(fitm5, fit8, Counted.MH_start, Counted.MH_step);
 404         assertEquals(Counted.MT_counted, loop.type());
 405         assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
 406     }
 407 
 408     @Test
 409     public static void testCountedLoopCounterInit() throws Throwable {
 410         // int x = 0; for (int i = 0; i < 5; ++i) { x += i; } return x; => 10
 411         // (only if counter's first value in body is 0)
 412         MethodHandle iter = MethodHandles.constant(int.class, 5);
 413         MethodHandle init = MethodHandles.constant(int.class, 0);
 414         MethodHandle body = Counted.MH_addCounter;
 415         MethodHandle loop = MethodHandles.countedLoop(iter, init, body);
 416         assertEquals(Counted.MT_counterInit, loop.type());
 417         assertEquals(10, loop.invoke());
 418     }


 891         static String start(String arg) {
 892             return arg;
 893         }
 894 
 895         static String step(int counter, String v, String arg) {
 896             return "na " + v;
 897         }
 898 
 899         static void stepUpdateArray(int counter, int[] a) {
 900             ++a[0];
 901         }
 902 
 903         static void printHello(int counter) {
 904             System.out.print("hello");
 905         }
 906 
 907         static int addCounter(int counter, int x) {
 908             return x + counter;
 909         }
 910 
 911         static String stateBody(int counter, String s) {
 912             return "s" + s + counter;
 913         }
 914 
 915         static String append(int counter, String localState, String loopArg) {
 916             if (null == localState) {
 917                 return loopArg + counter;
 918             }
 919             return localState + counter;
 920         }
 921 
 922         static final Class<Counted> COUNTED = Counted.class;
 923 
 924         static final MethodType MT_start = methodType(String.class, String.class);
 925         static final MethodType MT_step = methodType(String.class, int.class, String.class, String.class);
 926         static final MethodType MT_stepUpdateArray = methodType(void.class, int.class, int[].class);
 927         static final MethodType MT_printHello = methodType(void.class, int.class);
 928         static final MethodType MT_addCounter = methodType(int.class, int.class, int.class);
 929         static final MethodType MT_stateBody = methodType(String.class, int.class, String.class);
 930         static final MethodType MT_append = methodType(String.class, int.class, String.class, String.class);
 931 
 932         static final MethodHandle MH_13;
 933         static final MethodHandle MH_m5;
 934         static final MethodHandle MH_8;
 935         static final MethodHandle MH_start;
 936         static final MethodHandle MH_step;
 937         static final MethodHandle MH_stepUpdateArray;
 938         static final MethodHandle MH_printHello;
 939         static final MethodHandle MH_addCounter;
 940         static final MethodHandle MH_stateBody;
 941         static final MethodHandle MH_append;
 942 
 943         static final MethodType MT_counted = methodType(String.class, String.class);
 944         static final MethodType MT_arrayCounted = methodType(void.class, int[].class);
 945         static final MethodType MT_countedPrinting = methodType(void.class);
 946         static final MethodType MT_counterInit = methodType(int.class);
 947         static final MethodType MT_bodyDeterminesState = methodType(String.class);
 948         static final MethodType MT_iterationsDefineArgs = methodType(String.class, String.class);
 949 
 950         static {
 951             try {
 952                 MH_13 = MethodHandles.constant(int.class, 13);
 953                 MH_m5 = MethodHandles.constant(int.class, -5);
 954                 MH_8 = MethodHandles.constant(int.class, 8);
 955                 MH_start = LOOKUP.findStatic(COUNTED, "start", MT_start);
 956                 MH_step = LOOKUP.findStatic(COUNTED, "step", MT_step);
 957                 MH_stepUpdateArray = LOOKUP.findStatic(COUNTED, "stepUpdateArray", MT_stepUpdateArray);
 958                 MH_printHello = LOOKUP.findStatic(COUNTED, "printHello", MT_printHello);
 959                 MH_addCounter = LOOKUP.findStatic(COUNTED, "addCounter", MT_addCounter);
 960                 MH_stateBody = LOOKUP.findStatic(COUNTED, "stateBody", MT_stateBody);
 961                 MH_append = LOOKUP.findStatic(COUNTED, "append", MT_append);
 962             } catch (Exception e) {
 963                 throw new ExceptionInInitializerError(e);
 964             }
 965         }
 966 
 967     }
 968 
 969     static class Iterate {
 970 
 971         static Iterator<Integer> sumIterator(Integer[] a) {
 972             return Arrays.asList(a).iterator();
 973         }
 974 
 975         static int sumInit(Integer[] a) {
 976             return 0;
 977         }
 978 
 979         static int sumStep(int s, int e, Integer[] a) {
 980             return s + e;
 981         }


< prev index next >