Use ComparisonGenerator for range element type in counter loops
This commit is contained in:
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.codegen.range
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.IntComparisonGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInDefinitelySafeSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
@@ -36,7 +38,7 @@ class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>) :
|
||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||
SimpleBoundedValue(
|
||||
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
|
||||
StackValue.constant(0, asmElementType),
|
||||
StackValue.constant(0, elementType),
|
||||
true,
|
||||
StackValue.operation(Type.INT_TYPE) { v ->
|
||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||
@@ -46,10 +48,12 @@ class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>) :
|
||||
)
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(
|
||||
codegen, forExpression, getBoundedValue(codegen), IntComparisonGenerator
|
||||
)
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
ForInDefinitelySafeSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(
|
||||
codegen, forExpression, getBoundedValue(codegen)
|
||||
codegen, forExpression, getBoundedValue(codegen), IntComparisonGenerator
|
||||
)
|
||||
}
|
||||
+7
-3
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.codegen.range
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.IntComparisonGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInDefinitelySafeSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
@@ -35,7 +37,7 @@ class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescript
|
||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||
SimpleBoundedValue(
|
||||
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
|
||||
StackValue.constant(0, asmElementType),
|
||||
StackValue.constant(0, elementType),
|
||||
true,
|
||||
StackValue.operation(Type.INT_TYPE) { v ->
|
||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||
@@ -45,10 +47,12 @@ class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescript
|
||||
)
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(
|
||||
codegen, forExpression, getBoundedValue(codegen), IntComparisonGenerator
|
||||
)
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
ForInDefinitelySafeSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(
|
||||
codegen, forExpression, getBoundedValue(codegen)
|
||||
codegen, forExpression, getBoundedValue(codegen), IntComparisonGenerator
|
||||
)
|
||||
}
|
||||
+7
-3
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.codegen.range
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.IntComparisonGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInDefinitelySafeSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
@@ -35,7 +37,7 @@ class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
|
||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||
SimpleBoundedValue(
|
||||
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
|
||||
StackValue.constant(0, asmElementType),
|
||||
StackValue.constant(0, elementType),
|
||||
true,
|
||||
StackValue.operation(Type.INT_TYPE) { v ->
|
||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||
@@ -45,10 +47,12 @@ class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
|
||||
)
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(
|
||||
codegen, forExpression, getBoundedValue(codegen), IntComparisonGenerator
|
||||
)
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
ForInDefinitelySafeSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(
|
||||
codegen, forExpression, getBoundedValue(codegen)
|
||||
codegen, forExpression, getBoundedValue(codegen), IntComparisonGenerator
|
||||
)
|
||||
}
|
||||
+6
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.range
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
@@ -39,12 +40,16 @@ class DownToProgressionRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
createConstBoundedForInDownToGenerator(codegen, forExpression)
|
||||
?: ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(codegen, forExpression, getBoundedValue(codegen))
|
||||
?: ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(
|
||||
codegen, forExpression, getBoundedValue(codegen),
|
||||
getComparisonGeneratorForKotlinType(elementKotlinType)
|
||||
)
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
createConstBoundedForInReversedDownToGenerator(codegen, forExpression)
|
||||
?: ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(
|
||||
codegen, forExpression, getBoundedValue(codegen),
|
||||
getComparisonGeneratorForKotlinType(elementKotlinType),
|
||||
inverseBoundsEvaluationOrder = true
|
||||
)
|
||||
|
||||
|
||||
+13
-4
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.range
|
||||
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForRangeContainsCall
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInDefinitelySafeSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
@@ -36,7 +38,12 @@ import org.jetbrains.org.objectweb.asm.Type
|
||||
abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
||||
) : CallIntrinsicRangeValue(rangeCall) {
|
||||
protected val asmElementType = getAsmRangeElementTypeForPrimitiveRangeOrProgression(rangeCall.resultingDescriptor)
|
||||
|
||||
protected val elementKotlinType =
|
||||
rangeCall.resultingDescriptor.returnType?.let { getRangeOrProgressionElementType(it) }
|
||||
?: throw AssertionError("Unexpected range ")
|
||||
|
||||
protected val elementType = getAsmRangeElementTypeForPrimitiveRangeOrProgression(rangeCall.resultingDescriptor)
|
||||
|
||||
override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>) =
|
||||
resolvedCallForIn.resultingDescriptor.let {
|
||||
@@ -138,8 +145,9 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||
codegen, forExpression,
|
||||
startValue = startValue,
|
||||
isStartInclusive = isStartInclusive,
|
||||
endValue = StackValue.integerConstant(endIntValue, asmElementType),
|
||||
endValue = StackValue.integerConstant(endIntValue, elementType),
|
||||
isEndInclusive = true,
|
||||
comparisonGenerator = getComparisonGeneratorForKotlinType(elementKotlinType),
|
||||
step = step
|
||||
)
|
||||
|
||||
@@ -155,8 +163,9 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||
codegen, forExpression,
|
||||
startValue = startValue,
|
||||
isStartInclusive = isStartInclusive,
|
||||
endValue = StackValue.constant(endLongValue, asmElementType),
|
||||
endValue = StackValue.constant(endLongValue, elementType),
|
||||
isEndInclusive = true,
|
||||
comparisonGenerator = getComparisonGeneratorForKotlinType(elementKotlinType),
|
||||
step = step
|
||||
)
|
||||
|
||||
|
||||
+6
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.range
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
@@ -51,12 +52,16 @@ class PrimitiveNumberRangeLiteralRangeValue(
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
createConstBoundedForInRangeLiteralGenerator(codegen, forExpression)
|
||||
?: ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||
?: ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(
|
||||
codegen, forExpression, getBoundedValue(codegen),
|
||||
getComparisonGeneratorForKotlinType(elementKotlinType)
|
||||
)
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
createConstBoundedRangeForInReversedRangeLiteralGenerator(codegen, forExpression)
|
||||
?: ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(
|
||||
codegen, forExpression, getBoundedValue(codegen),
|
||||
getComparisonGeneratorForKotlinType(elementKotlinType),
|
||||
inverseBoundsEvaluationOrder = true
|
||||
)
|
||||
|
||||
|
||||
+6
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.range
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
@@ -39,12 +40,16 @@ class PrimitiveNumberUntilRangeValue(rangeCall: ResolvedCall<out CallableDescrip
|
||||
)
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(
|
||||
codegen, forExpression, getBoundedValue(codegen),
|
||||
getComparisonGeneratorForKotlinType(elementKotlinType)
|
||||
)
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
createConstBoundedForInReversedUntilGenerator(codegen, forExpression)
|
||||
?: ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(
|
||||
codegen, forExpression, getBoundedValue(codegen),
|
||||
getComparisonGeneratorForKotlinType(elementKotlinType),
|
||||
inverseBoundsEvaluationOrder = true
|
||||
)
|
||||
|
||||
|
||||
+21
-2
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.range
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForKotlinType
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInRangeInstanceLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.inExpression.CallBasedInExpressionGenerator
|
||||
@@ -24,15 +25,33 @@ import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class PrimitiveRangeRangeValue(private val rangeExpression: KtExpression) : ReversableRangeValue {
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
ForInRangeInstanceLoopGenerator(codegen, forExpression, rangeExpression, reversed = false)
|
||||
ForInRangeInstanceLoopGenerator(
|
||||
codegen, forExpression, rangeExpression,
|
||||
getComparisonGeneratorForKotlinType(getRangeElementType(codegen, forExpression)),
|
||||
reversed = false
|
||||
)
|
||||
|
||||
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
|
||||
CallBasedInExpressionGenerator(codegen, operatorReference)
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
ForInRangeInstanceLoopGenerator(codegen, forExpression, rangeExpression, reversed = true)
|
||||
ForInRangeInstanceLoopGenerator(
|
||||
codegen, forExpression, rangeExpression,
|
||||
getComparisonGeneratorForKotlinType(getRangeElementType(codegen, forExpression)),
|
||||
reversed = true
|
||||
)
|
||||
|
||||
private fun getRangeElementType(codegen: ExpressionCodegen, forExpression: KtForExpression): KotlinType {
|
||||
val ktLoopRange = forExpression.loopRange
|
||||
?: throw AssertionError("No loop range expression: ${forExpression.text}")
|
||||
val rangeType = codegen.bindingContext.getType(ktLoopRange)
|
||||
?: throw AssertionError("No type for loop range expression: ${ktLoopRange.text}")
|
||||
return getRangeOrProgressionElementType(rangeType)
|
||||
?: throw AssertionError("Unexpected range type: $rangeType")
|
||||
}
|
||||
}
|
||||
+16
-8
@@ -16,10 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.range.comparison
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.range.getRangeOrProgressionElementType
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -33,14 +35,20 @@ interface ComparisonGenerator {
|
||||
fun jumpIfLess(v: InstructionAdapter, label: Label)
|
||||
}
|
||||
|
||||
fun getComparisonGeneratorForPrimitiveType(type: Type): ComparisonGenerator =
|
||||
fun getComparisonGeneratorForKotlinType(kotlinType: KotlinType): ComparisonGenerator =
|
||||
when {
|
||||
type == Type.CHAR_TYPE -> CharComparisonGenerator
|
||||
type.isPrimitiveIntOrCoercible() -> IntComparisonGenerator
|
||||
type == Type.LONG_TYPE -> LongComparisonGenerator
|
||||
type == Type.FLOAT_TYPE -> FloatComparisonGenerator
|
||||
type == Type.DOUBLE_TYPE -> DoubleComparisonGenerator
|
||||
else -> throw UnsupportedOperationException("Unexpected primitive type: " + type)
|
||||
KotlinBuiltIns.isChar(kotlinType) ->
|
||||
CharComparisonGenerator
|
||||
KotlinBuiltIns.isByte(kotlinType) || KotlinBuiltIns.isShort(kotlinType) || KotlinBuiltIns.isInt(kotlinType) ->
|
||||
IntComparisonGenerator
|
||||
KotlinBuiltIns.isLong(kotlinType) ->
|
||||
LongComparisonGenerator
|
||||
KotlinBuiltIns.isFloat(kotlinType) ->
|
||||
FloatComparisonGenerator
|
||||
KotlinBuiltIns.isDouble(kotlinType) ->
|
||||
DoubleComparisonGenerator
|
||||
else ->
|
||||
throw UnsupportedOperationException("Unexpected element type: $kotlinType")
|
||||
}
|
||||
|
||||
fun getComparisonGeneratorForRangeContainsCall(
|
||||
@@ -60,7 +68,7 @@ fun getComparisonGeneratorForRangeContainsCall(
|
||||
|
||||
return when {
|
||||
asmElementType == asmValueParameterType ->
|
||||
getComparisonGeneratorForPrimitiveType(asmElementType)
|
||||
getComparisonGeneratorForKotlinType(elementType)
|
||||
|
||||
asmElementType.isPrimitiveIntOrCoercible() && asmValueParameterType.isPrimitiveIntOrCoercible() ->
|
||||
IntComparisonGenerator
|
||||
|
||||
+3
-4
@@ -20,7 +20,7 @@ import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
sealed class FloatingPointComparisonGenerator(override val comparedType: Type) : ComparisonGenerator {
|
||||
class FloatingPointComparisonGenerator(override val comparedType: Type) : ComparisonGenerator {
|
||||
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
|
||||
v.cmpg(comparedType)
|
||||
v.ifge(label)
|
||||
@@ -42,6 +42,5 @@ sealed class FloatingPointComparisonGenerator(override val comparedType: Type) :
|
||||
}
|
||||
}
|
||||
|
||||
object FloatComparisonGenerator : FloatingPointComparisonGenerator(Type.FLOAT_TYPE)
|
||||
|
||||
object DoubleComparisonGenerator : FloatingPointComparisonGenerator(Type.DOUBLE_TYPE)
|
||||
val FloatComparisonGenerator = FloatingPointComparisonGenerator(Type.FLOAT_TYPE)
|
||||
val DoubleComparisonGenerator = FloatingPointComparisonGenerator(Type.DOUBLE_TYPE)
|
||||
+3
-4
@@ -20,7 +20,7 @@ import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
abstract class IntegerComparisonGenerator(override val comparedType: Type) : ComparisonGenerator {
|
||||
class IntegerComparisonGenerator(override val comparedType: Type) : ComparisonGenerator {
|
||||
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
|
||||
v.ificmpge(label)
|
||||
}
|
||||
@@ -38,6 +38,5 @@ abstract class IntegerComparisonGenerator(override val comparedType: Type) : Com
|
||||
}
|
||||
}
|
||||
|
||||
object IntComparisonGenerator : IntegerComparisonGenerator(Type.INT_TYPE)
|
||||
|
||||
object CharComparisonGenerator : IntegerComparisonGenerator(Type.CHAR_TYPE)
|
||||
val IntComparisonGenerator = IntegerComparisonGenerator(Type.INT_TYPE)
|
||||
val CharComparisonGenerator = IntegerComparisonGenerator(Type.CHAR_TYPE)
|
||||
+7
-13
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.range.forLoop
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genIncrement
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.ComparisonGenerator
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -26,7 +27,8 @@ import org.jetbrains.org.objectweb.asm.Type
|
||||
abstract class AbstractForInRangeLoopGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
protected val step: Int
|
||||
protected val step: Int,
|
||||
protected val comparisonGenerator: ComparisonGenerator
|
||||
) : AbstractForInProgressionOrRangeLoopGenerator(codegen, forExpression) {
|
||||
|
||||
override fun beforeLoop() {
|
||||
@@ -40,19 +42,11 @@ abstract class AbstractForInRangeLoopGenerator(
|
||||
override fun checkEmptyLoop(loopExit: Label) {
|
||||
loopParameter().put(asmElementType, elementType, v)
|
||||
v.load(endVar, asmElementType)
|
||||
if (asmElementType.sort == Type.LONG) {
|
||||
v.lcmp()
|
||||
if (step > 0) {
|
||||
v.ifgt(loopExit)
|
||||
} else {
|
||||
v.iflt(loopExit)
|
||||
}
|
||||
|
||||
if (step > 0) {
|
||||
comparisonGenerator.jumpIfGreater(v, loopExit)
|
||||
} else {
|
||||
if (step > 0) {
|
||||
v.ificmpgt(loopExit)
|
||||
} else {
|
||||
v.ificmplt(loopExit)
|
||||
}
|
||||
comparisonGenerator.jumpIfLess(v, loopExit)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+29
-34
@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.codegen.range.forLoop
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.range.SimpleBoundedValue
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.ComparisonGenerator
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
/**
|
||||
* Generates "naive" for loop:
|
||||
@@ -45,13 +45,15 @@ class ForInDefinitelySafeSimpleProgressionLoopGenerator(
|
||||
private val isStartInclusive: Boolean,
|
||||
private val endValue: StackValue,
|
||||
private val isEndInclusive: Boolean,
|
||||
comparisonGenerator: ComparisonGenerator,
|
||||
step: Int
|
||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression, step) {
|
||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression, step, comparisonGenerator) {
|
||||
|
||||
constructor(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
boundedValue: SimpleBoundedValue,
|
||||
comparisonGenerator: ComparisonGenerator,
|
||||
step: Int
|
||||
) : this(
|
||||
codegen, forExpression,
|
||||
@@ -59,15 +61,26 @@ class ForInDefinitelySafeSimpleProgressionLoopGenerator(
|
||||
isStartInclusive = if (step == 1) boundedValue.isLowInclusive else boundedValue.isHighInclusive,
|
||||
endValue = if (step == 1) boundedValue.highBound else boundedValue.lowBound,
|
||||
isEndInclusive = if (step == 1) boundedValue.isHighInclusive else boundedValue.isLowInclusive,
|
||||
comparisonGenerator = comparisonGenerator,
|
||||
step = step
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun fromBoundedValueWithStep1(codegen: ExpressionCodegen, forExpression: KtForExpression, boundedValue: SimpleBoundedValue) =
|
||||
ForInDefinitelySafeSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, 1)
|
||||
fun fromBoundedValueWithStep1(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
boundedValue: SimpleBoundedValue,
|
||||
comparisonGenerator: ComparisonGenerator
|
||||
) =
|
||||
ForInDefinitelySafeSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, comparisonGenerator, 1)
|
||||
|
||||
fun fromBoundedValueWithStepMinus1(codegen: ExpressionCodegen, forExpression: KtForExpression, boundedValue: SimpleBoundedValue) =
|
||||
ForInDefinitelySafeSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, -1)
|
||||
fun fromBoundedValueWithStepMinus1(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
boundedValue: SimpleBoundedValue,
|
||||
comparisonGenerator: ComparisonGenerator
|
||||
) =
|
||||
ForInDefinitelySafeSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, comparisonGenerator, -1)
|
||||
}
|
||||
|
||||
override fun storeRangeStartAndEnd() {
|
||||
@@ -84,35 +97,17 @@ class ForInDefinitelySafeSimpleProgressionLoopGenerator(
|
||||
override fun checkPreCondition(loopExit: Label) {
|
||||
loopParameter().put(asmElementType, elementType, v)
|
||||
v.load(endVar, asmElementType)
|
||||
if (asmElementType.sort == Type.LONG) {
|
||||
v.lcmp()
|
||||
if (step > 0) {
|
||||
if (isEndInclusive) {
|
||||
v.ifgt(loopExit)
|
||||
} else {
|
||||
v.ifge(loopExit)
|
||||
}
|
||||
} else {
|
||||
if (isEndInclusive) {
|
||||
v.iflt(loopExit)
|
||||
} else {
|
||||
v.ifle(loopExit)
|
||||
}
|
||||
}
|
||||
|
||||
if (step > 0) {
|
||||
if (isEndInclusive)
|
||||
comparisonGenerator.jumpIfGreater(v, loopExit)
|
||||
else
|
||||
comparisonGenerator.jumpIfGreaterOrEqual(v, loopExit)
|
||||
} else {
|
||||
if (step > 0) {
|
||||
if (isEndInclusive) {
|
||||
v.ificmpgt(loopExit)
|
||||
} else {
|
||||
v.ificmpge(loopExit)
|
||||
}
|
||||
} else {
|
||||
if (isEndInclusive) {
|
||||
v.ificmplt(loopExit)
|
||||
} else {
|
||||
v.ificmple(loopExit)
|
||||
}
|
||||
}
|
||||
if (isEndInclusive)
|
||||
comparisonGenerator.jumpIfLess(v, loopExit)
|
||||
else
|
||||
comparisonGenerator.jumpIfLessOrEqual(v, loopExit)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.ComparisonGenerator
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
|
||||
@@ -24,8 +25,9 @@ class ForInRangeInstanceLoopGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
private val rangeExpression: KtExpression,
|
||||
comparisonGenerator: ComparisonGenerator,
|
||||
private val reversed: Boolean
|
||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression, if (reversed) -1 else 1) {
|
||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression, if (reversed) -1 else 1, comparisonGenerator) {
|
||||
|
||||
override fun storeRangeStartAndEnd() {
|
||||
val loopRangeType = codegen.bindingContext.getType(rangeExpression)!!
|
||||
|
||||
+13
-18
@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.codegen.range.forLoop
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.range.SimpleBoundedValue
|
||||
import org.jetbrains.kotlin.codegen.range.comparison.ComparisonGenerator
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class ForInSimpleProgressionLoopGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
@@ -31,14 +31,16 @@ class ForInSimpleProgressionLoopGenerator(
|
||||
private val endValue: StackValue,
|
||||
private val isEndInclusive: Boolean,
|
||||
private val inverseBoundsEvaluationOrder: Boolean,
|
||||
comparisonGenerator: ComparisonGenerator,
|
||||
step: Int
|
||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression, step) {
|
||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression, step, comparisonGenerator) {
|
||||
|
||||
constructor(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
boundedValue: SimpleBoundedValue,
|
||||
inverseBoundsEvaluationOrder: Boolean,
|
||||
comparisonGenerator: ComparisonGenerator,
|
||||
step: Int
|
||||
) : this(
|
||||
codegen, forExpression,
|
||||
@@ -47,6 +49,7 @@ class ForInSimpleProgressionLoopGenerator(
|
||||
endValue = if (step == 1) boundedValue.highBound else boundedValue.lowBound,
|
||||
isEndInclusive = if (step == 1) boundedValue.isHighInclusive else boundedValue.isLowInclusive,
|
||||
inverseBoundsEvaluationOrder = inverseBoundsEvaluationOrder,
|
||||
comparisonGenerator = comparisonGenerator,
|
||||
step = step
|
||||
)
|
||||
|
||||
@@ -55,17 +58,19 @@ class ForInSimpleProgressionLoopGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
boundedValue: SimpleBoundedValue,
|
||||
comparisonGenerator: ComparisonGenerator,
|
||||
inverseBoundsEvaluationOrder: Boolean = false
|
||||
) =
|
||||
ForInSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, inverseBoundsEvaluationOrder, 1)
|
||||
ForInSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, inverseBoundsEvaluationOrder, comparisonGenerator, 1)
|
||||
|
||||
fun fromBoundedValueWithStepMinus1(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
boundedValue: SimpleBoundedValue,
|
||||
comparisonGenerator: ComparisonGenerator,
|
||||
inverseBoundsEvaluationOrder: Boolean = false
|
||||
) =
|
||||
ForInSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, inverseBoundsEvaluationOrder, -1)
|
||||
ForInSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, inverseBoundsEvaluationOrder, comparisonGenerator, -1)
|
||||
}
|
||||
|
||||
override fun storeRangeStartAndEnd() {
|
||||
@@ -93,20 +98,10 @@ class ForInSimpleProgressionLoopGenerator(
|
||||
if (!isEndInclusive) {
|
||||
loopParameter().put(asmElementType, elementType, v)
|
||||
v.load(endVar, asmElementType)
|
||||
if (asmElementType.sort == Type.LONG) {
|
||||
v.lcmp()
|
||||
if (step > 0) {
|
||||
v.ifge(loopExit)
|
||||
} else {
|
||||
v.ifle(loopExit)
|
||||
}
|
||||
} else {
|
||||
if (step > 0) {
|
||||
v.ificmpge(loopExit)
|
||||
} else {
|
||||
v.ificmple(loopExit)
|
||||
}
|
||||
}
|
||||
if (step > 0)
|
||||
comparisonGenerator.jumpIfGreaterOrEqual(v, loopExit)
|
||||
else
|
||||
comparisonGenerator.jumpIfLessOrEqual(v, loopExit)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user