8154751: MethodHandles.countedLoop does not accept empty bodies
Reviewed-by: redestad
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Apr 22 13:36:22 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Apr 22 15:05:26 2016 +0200
@@ -4476,12 +4476,16 @@
* @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);
}
--- a/jdk/test/java/lang/invoke/LoopCombinatorTest.java Fri Apr 22 13:36:22 2016 +0200
+++ b/jdk/test/java/lang/invoke/LoopCombinatorTest.java Fri Apr 22 15:05:26 2016 +0200
@@ -30,6 +30,7 @@
* @bug 8150957
* @bug 8152667
* @bug 8153637
+ * @bug 8154751
* @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest
*/
@@ -348,6 +349,23 @@
}
@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
MethodHandle loop = MethodHandles.iteratedLoop(Iterate.MH_sumIterator, Iterate.MH_sumInit, Iterate.MH_sumStep);