diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 2b5fdfebfe9..9992483de04 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -4476,12 +4476,16 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum")); * @since 9 */ public static MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) { - MethodHandle returnVar = dropArguments(init == null || init.type().returnType() == void.class ? - zero(void.class) : identity(init.type().returnType()), 0, int.class, int.class); + MethodHandle defaultResultHandle = init == null || init.type().returnType() == void.class ? + zero(void.class) : + identity(init.type().returnType()); + MethodHandle adaptedBody = body == null ? dropArguments(defaultResultHandle, 0, int.class) : body; + MethodHandle returnVar = dropArguments(defaultResultHandle, 0, int.class, int.class); MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)}; - MethodHandle[] loopLimit = {end, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar}; + MethodHandle[] loopLimit = {end, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), + returnVar}; MethodHandle[] bodyClause = {init, - filterArgument(dropArguments(body, 1, int.class), 0, + filterArgument(dropArguments(adaptedBody, 1, int.class), 0, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter))}; return loop(indexVar, loopLimit, bodyClause); } diff --git a/jdk/test/java/lang/invoke/LoopCombinatorTest.java b/jdk/test/java/lang/invoke/LoopCombinatorTest.java index 67edb08a8cd..5637a9958a0 100644 --- a/jdk/test/java/lang/invoke/LoopCombinatorTest.java +++ b/jdk/test/java/lang/invoke/LoopCombinatorTest.java @@ -30,6 +30,7 @@ * @bug 8150957 * @bug 8152667 * @bug 8153637 + * @bug 8154751 * @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest */ @@ -347,6 +348,23 @@ public class LoopCombinatorTest { assertEquals(10, loop.invoke()); } + @Test + public static void testCountedLoopEmpty() throws Throwable { + // for (int i = 0; i < 5; ++i) { /* empty */ } + MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null); + assertEquals(methodType(void.class), loop.type()); + loop.invoke(); + } + + @Test + public static void testCountedRangeLoopEmpty() throws Throwable { + // for (int i = -5; i < 5; ++i) { /* empty */ } + MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, -5), + MethodHandles.constant(int.class, 5), null, null); + assertEquals(methodType(void.class), loop.type()); + loop.invoke(); + } + @Test public static void testIterateSum() throws Throwable { // Integer[] a = new Integer[]{1,2,3,4,5,6}; int sum = 0; for (int e : a) { sum += e; } return sum; => 21