diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 5a49bdf5475..3e5c4b0d6ed 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -514,7 +514,9 @@ public class ExpressionCodegen extends JetVisitor { } private class ForInRangeLoopGenerator extends ForLoopGenerator { - private int myEndVar; + private int myCountVar; + private int myDeltaVar; + private int myIndexVar; public ForInRangeLoopGenerator(JetForExpression expression, Type loopRangeType) { super(expression, loopRangeType); @@ -522,41 +524,73 @@ public class ExpressionCodegen extends JetVisitor { @Override protected void generatePrologue() { - myEndVar = myFrameMap.enterTemp(); + myIndexVar = lookupLocal(parameterDescriptor); + myCountVar = myFrameMap.enterTemp(); + myDeltaVar = myFrameMap.enterTemp(); if(isIntRangeExpr(expression.getLoopRange())) { JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getLoopRange(); //noinspection ConstantConditions gen(rangeExpression.getLeft(), Type.INT_TYPE); - v.store(lookupLocal(parameterDescriptor), Type.INT_TYPE); + v.store(myIndexVar, Type.INT_TYPE); gen(rangeExpression.getRight(), Type.INT_TYPE); - v.store(myEndVar, Type.INT_TYPE); + v.store(myCountVar, Type.INT_TYPE); + + v.load(myCountVar, Type.INT_TYPE); + v.load(myIndexVar, Type.INT_TYPE); + v.sub(Type.INT_TYPE); + v.iconst(1); + v.add(Type.INT_TYPE); + v.store(myCountVar, Type.INT_TYPE); + + v.load(myCountVar, Type.INT_TYPE); + v.iflt(end); + + v.iconst(1); + v.store(myDeltaVar, Type.INT_TYPE); } else { gen(expression.getLoopRange(), loopRangeType); v.dup(); + v.dup(); - v.invokevirtual("jet/IntRange", "getIteratorStart", "()I"); - v.store(lookupLocal(parameterDescriptor), Type.INT_TYPE); - v.invokevirtual("jet/IntRange", "getEnd", "()I"); - v.store(myEndVar, Type.INT_TYPE); + v.invokevirtual("jet/IntRange", "getStart", "()I"); + v.store(myIndexVar, Type.INT_TYPE); + v.invokevirtual("jet/IntRange", "getSize", "()I"); + v.store(myCountVar, Type.INT_TYPE); + + v.invokevirtual("jet/IntRange", "getIsReversed", "()Z"); + Label down = new Label(); + + v.ifne(down); + v.iconst(1); + Label initEnd = new Label(); + v.goTo(initEnd); + v.mark(down); + v.iconst(-1); + v.mark(initEnd); + v.store(myDeltaVar, Type.INT_TYPE); } } @Override protected void generateCondition(Type asmParamType, Label end) { - v.load(lookupLocal(parameterDescriptor), Type.INT_TYPE); - v.load(myEndVar, Type.INT_TYPE); - v.ificmpgt(end); + v.load(myCountVar, Type.INT_TYPE); + v.ifeq(end); } @Override protected void generateIncrement() { - v.iinc(lookupLocal(parameterDescriptor), 1); // TODO support decreasing order + v.load(myIndexVar, Type.INT_TYPE); + v.load(myDeltaVar, Type.INT_TYPE); + v.add(Type.INT_TYPE); + v.store(myIndexVar, Type.INT_TYPE); + v.iinc(myCountVar, -1); } @Override protected void cleanupTemp() { - myFrameMap.leaveTemp(1); + myFrameMap.leaveTemp(); + myFrameMap.leaveTemp(); } } diff --git a/compiler/testData/codegen/regressions/kt1076.kt b/compiler/testData/codegen/regressions/kt1076.kt new file mode 100644 index 00000000000..9d99b164039 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1076.kt @@ -0,0 +1,11 @@ +fun box() : String { + var cnt = 0 + for (len in 4 downto 1) { + cnt++ + } + + for (n in -(1..5)) + cnt++ + + return if(cnt == 9) "OK" else cnt.toString() +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java index eb8e8b1aa3e..56d56d8cfba 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java @@ -262,4 +262,8 @@ public class ControlStructuresTest extends CodegenTestCase { blackBoxFile("controlStructures/ifInWhile.jet"); // System.out.println(generateToText()); } + + public void testKt1076() throws Exception { + blackBoxFile("regressions/kt1076.kt"); + } } diff --git a/stdlib/ktSrc/Filter.kt b/stdlib/ktSrc/Filter.kt index 45439740e42..bf458ae0fb8 100644 --- a/stdlib/ktSrc/Filter.kt +++ b/stdlib/ktSrc/Filter.kt @@ -11,21 +11,19 @@ inline fun java.util.Iterator.filter(f: (T)-> Boolean) : java.util.Iterat /* Adds filtered elements in to given container */ -/* -inline fun > java.lang.Iterable.filterTo(var container: U, filter: fun(T): Boolean) : U { +inline fun > java.lang.Iterable.filterTo(var container: U, filter: (T)->Boolean) : U { for(element in this) { if(filter(element)) container.add(element) } return container } -*/ /* Create iterator filtering given java.lang.Iterable */ /* -inline fun java.lang.Iterable.filter(f: fun(T): Boolean) : java.util.Iterator = (iterator() as java.util.Iterator).filter(f) +inline fun java.lang.Iterable.filter(f: (T)->Boolean) : java.util.Iterator = (iterator() as java.util.Iterator).filter(f) */ private class FilterIterator(val original: java.util.Iterator, val filter: (T)-> Boolean) : java.util.Iterator {