diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ComparableRangeLiteralRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ComparableRangeLiteralRangeValue.kt index a68a3aa61cd..8fd9252e1b7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ComparableRangeLiteralRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ComparableRangeLiteralRangeValue.kt @@ -18,9 +18,8 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.isClosedRangeContains -import org.jetbrains.kotlin.codegen.range.comparison.ObjectComparisonGenerator import org.jetbrains.kotlin.codegen.range.forLoop.IteratorForLoopGenerator -import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator +import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeOfComparableExpressionGenerator import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.psi.KtForExpression import org.jetbrains.kotlin.psi.KtSimpleNameExpression @@ -38,6 +37,9 @@ class ComparableRangeLiteralRangeValue( override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall) = isClosedRangeContains(resolvedCallForIn.resultingDescriptor) - override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression, resolvedCall: ResolvedCall)= - InContinuousRangeExpressionGenerator(operatorReference, boundedValue, ObjectComparisonGenerator) + override fun createIntrinsicInExpressionGenerator( + codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression, + resolvedCall: ResolvedCall + ) = InContinuousRangeOfComparableExpressionGenerator(operatorReference, boundedValue) } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt index 2cc7dde7988..77b29686b70 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForRangeContainsCall import org.jetbrains.kotlin.codegen.range.inExpression.CallBasedInExpressionGenerator -import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator +import org.jetbrains.kotlin.codegen.range.inExpression.InPrimitiveContinuousRangeExpressionGenerator import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.psi.KtSimpleNameExpression @@ -42,7 +42,7 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(rangeCall: ResolvedCall= low + v.swap() + comparisonGenerator.jumpIfGreaterOrEqual(v, cmpHighLabel) + } + else { + // arg > low + v.swap() + comparisonGenerator.jumpIfGreater(v, cmpHighLabel) + } + + // Low bound is NOT satisfied, clear stack and goto jumpLabel + AsmUtil.pop2(v, operandType) + v.goTo(jumpLabel) + + v.mark(cmpHighLabel) + // On stack: high arg + // if ([high bound is NOT satisfied]) goto jumpLabel + if (boundedValue.isHighInclusive) { + // arg > high + v.swap() + comparisonGenerator.jumpIfGreater(v, jumpLabel) + } + else { + // arg >= high + v.swap() + comparisonGenerator.jumpIfGreaterOrEqual(v, jumpLabel) + } + } + } +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/inExpression/InContinuousRangeExpressionGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/inExpression/InPrimitiveContinuousRangeExpressionGenerator.kt similarity index 98% rename from compiler/backend/src/org/jetbrains/kotlin/codegen/range/inExpression/InContinuousRangeExpressionGenerator.kt rename to compiler/backend/src/org/jetbrains/kotlin/codegen/range/inExpression/InPrimitiveContinuousRangeExpressionGenerator.kt index 4a3d710a8c9..72c9718fd8d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/inExpression/InContinuousRangeExpressionGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/inExpression/InPrimitiveContinuousRangeExpressionGenerator.kt @@ -28,7 +28,7 @@ import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -class InContinuousRangeExpressionGenerator( +class InPrimitiveContinuousRangeExpressionGenerator( operatorReference: KtSimpleNameExpression, private val boundedValue: BoundedValue, private val comparisonGenerator: ComparisonGenerator diff --git a/compiler/testData/codegen/box/ranges/contains/evaluationOrderForComparableRange.kt b/compiler/testData/codegen/box/ranges/contains/evaluationOrderForComparableRange.kt index 34a0cd0da24..6201cf0b728 100644 --- a/compiler/testData/codegen/box/ranges/contains/evaluationOrderForComparableRange.kt +++ b/compiler/testData/codegen/box/ranges/contains/evaluationOrderForComparableRange.kt @@ -22,14 +22,26 @@ fun z(i: Int): Z { return Z(i) } -fun box(): String { - expectOrder("z0 in z1 .. z3", "z:1 z:3 z:0 c:1,0 ") { z(0) in z(1) .. z(3) } - expectOrder("z2 in z1 .. z3", "z:1 z:3 z:2 c:1,2 c:3,2 ") { z(2) in z(1) .. z(3) } - expectOrder("z4 in z1 .. z3", "z:1 z:4 z:2 c:1,2 c:4,2 ") { z(2) in z(1) .. z(4) } +fun zr(i: Int, j: Int) = z(i) .. z(j) - expectOrder("z0 !in z1 .. z3", "z:1 z:3 z:0 c:1,0 ") { z(0) !in z(1) .. z(3) } - expectOrder("z2 !in z1 .. z3", "z:1 z:3 z:2 c:1,2 c:3,2 ") { z(2) !in z(1) .. z(3) } - expectOrder("z4 !in z1 .. z3", "z:1 z:4 z:2 c:1,2 c:4,2 ") { z(2) !in z(1) .. z(4) } +fun box(): String { + expectOrder("#1", "z:1 z:3 z:0 c:0,1 ") { z(0) in z(1) .. z(3) } + expectOrder("#1a", "z:1 z:3 z:0 c:0,1 ") { z(0) in zr(1, 3) } + + expectOrder("#2", "z:1 z:3 z:2 c:2,1 c:2,3 ") { z(2) in z(1) .. z(3) } + expectOrder("#2a", "z:1 z:3 z:2 c:2,1 c:2,3 ") { z(2) in zr(1, 3) } + + expectOrder("#3", "z:1 z:3 z:4 c:4,1 c:4,3 ") { z(4) in z(1) .. z(3) } + expectOrder("#3a", "z:1 z:3 z:4 c:4,1 c:4,3 ") { z(4) in zr(1, 3) } + + expectOrder("#4", "z:1 z:3 z:0 c:0,1 ") { z(0) !in z(1) .. z(3) } + expectOrder("#4a", "z:1 z:3 z:0 c:0,1 ") { z(0) !in zr(1, 3) } + + expectOrder("#5", "z:1 z:3 z:2 c:2,1 c:2,3 ") { z(2) !in z(1) .. z(3) } + expectOrder("#5a", "z:1 z:3 z:2 c:2,1 c:2,3 ") { z(2) !in zr(1, 3) } + + expectOrder("#6", "z:1 z:3 z:4 c:4,1 c:4,3 ") { z(4) !in z(1) .. z(3) } + expectOrder("#6a", "z:1 z:3 z:4 c:4,1 c:4,3 ") { z(4) !in zr(1, 3) } return "OK" } \ No newline at end of file