Remove unnecessary dependencies from AbstractBoundedValue

- Bounded value is a low-level abstraction for bounded ranges that is
used to generate specialized contains checks and for loop. It only
needs to contains StackValue that will be used to generate code.
- SimpleBoundedValue already have a constructor supporting StackValue
but having only one constructor avoid to pass extra argument that
will be used to only compute another information.
This commit is contained in:
Mikaël Peltier
2018-02-01 11:48:00 +01:00
committed by Dmitry Petrov
parent ed80252ba8
commit 5c04264218
10 changed files with 47 additions and 68 deletions
@@ -24,14 +24,8 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
abstract class AbstractBoundedValue( abstract class AbstractBoundedValue(
protected val codegen: ExpressionCodegen, override val instanceType: Type,
protected val rangeCall: ResolvedCall<out CallableDescriptor>,
override val isLowInclusive: Boolean = true, override val isLowInclusive: Boolean = true,
override val isHighInclusive: Boolean = true override val isHighInclusive: Boolean = true
) : BoundedValue { ) : BoundedValue {
override val instanceType: Type = codegen.asmType(rangeCall.resultingDescriptor.returnType!!)
override fun putInstance(v: InstructionAdapter, type: Type) {
codegen.invokeFunction(rangeCall.call, rangeCall, StackValue.none()).put(type, v)
}
} }
@@ -35,14 +35,14 @@ class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>) :
override fun getBoundedValue(codegen: ExpressionCodegen) = override fun getBoundedValue(codegen: ExpressionCodegen) =
SimpleBoundedValue( SimpleBoundedValue(
codegen, rangeCall, codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
lowBound = StackValue.constant(0, asmElementType), StackValue.constant(0, asmElementType),
isLowInclusive = true, true,
highBound = StackValue.operation(Type.INT_TYPE) { v -> StackValue.operation(Type.INT_TYPE) { v ->
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v) codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
v.arraylength() v.arraylength()
}, },
isHighInclusive = false false
) )
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
@@ -34,14 +34,14 @@ class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescript
override fun getBoundedValue(codegen: ExpressionCodegen) = override fun getBoundedValue(codegen: ExpressionCodegen) =
SimpleBoundedValue( SimpleBoundedValue(
codegen, rangeCall, codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
lowBound = StackValue.constant(0, asmElementType), StackValue.constant(0, asmElementType),
isLowInclusive = true, true,
highBound = StackValue.operation(Type.INT_TYPE) { v -> StackValue.operation(Type.INT_TYPE) { v ->
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v) codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
v.invokeinterface("java/lang/CharSequence", "length", "()I") v.invokeinterface("java/lang/CharSequence", "length", "()I")
}, },
isHighInclusive = false false
) )
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
@@ -34,14 +34,14 @@ class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
override fun getBoundedValue(codegen: ExpressionCodegen) = override fun getBoundedValue(codegen: ExpressionCodegen) =
SimpleBoundedValue( SimpleBoundedValue(
codegen, rangeCall, codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
lowBound = StackValue.constant(0, asmElementType), StackValue.constant(0, asmElementType),
isLowInclusive = true, true,
highBound = StackValue.operation(Type.INT_TYPE) { v -> StackValue.operation(Type.INT_TYPE) { v ->
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v) codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
v.invokeinterface("java/util/Collection", "size", "()I") v.invokeinterface("java/util/Collection", "size", "()I")
}, },
isHighInclusive = false false
) )
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
@@ -17,6 +17,8 @@
package org.jetbrains.kotlin.codegen.range package org.jetbrains.kotlin.codegen.range
import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.generateCallReceiver
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
import org.jetbrains.kotlin.codegen.isClosedRangeContains import org.jetbrains.kotlin.codegen.isClosedRangeContains
import org.jetbrains.kotlin.codegen.range.forLoop.IteratorForLoopGenerator import org.jetbrains.kotlin.codegen.range.forLoop.IteratorForLoopGenerator
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeOfComparableExpressionGenerator import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeOfComparableExpressionGenerator
@@ -29,7 +31,11 @@ class ComparableRangeLiteralRangeValue(
codegen: ExpressionCodegen, codegen: ExpressionCodegen,
rangeCall: ResolvedCall<out CallableDescriptor> rangeCall: ResolvedCall<out CallableDescriptor>
) : CallIntrinsicRangeValue(rangeCall) { ) : CallIntrinsicRangeValue(rangeCall) {
private val boundedValue = SimpleBoundedValue(codegen, rangeCall) private val boundedValue = SimpleBoundedValue(
instanceType = codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
lowBound = codegen.generateCallReceiver(rangeCall),
highBound = codegen.generateCallSingleArgument(rangeCall)
)
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
IteratorForLoopGenerator(codegen, forExpression) IteratorForLoopGenerator(codegen, forExpression)
@@ -32,7 +32,7 @@ class DownToProgressionRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
override fun getBoundedValue(codegen: ExpressionCodegen) = override fun getBoundedValue(codegen: ExpressionCodegen) =
SimpleBoundedValue( SimpleBoundedValue(
codegen, rangeCall, instanceType = codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
lowBound = codegen.generateCallSingleArgument(rangeCall), lowBound = codegen.generateCallSingleArgument(rangeCall),
highBound = codegen.generateCallReceiver(rangeCall) highBound = codegen.generateCallReceiver(rangeCall)
) )
@@ -36,18 +36,17 @@ class PrimitiveNumberRangeLiteralRangeValue(
ReversableRangeValue { ReversableRangeValue {
override fun getBoundedValue(codegen: ExpressionCodegen): SimpleBoundedValue { override fun getBoundedValue(codegen: ExpressionCodegen): SimpleBoundedValue {
val instanceType = codegen.asmType(rangeCall.resultingDescriptor.returnType!!)
val lowBound = codegen.generateCallReceiver(rangeCall)
if (codegen.canBeSpecializedByExcludingHighBound(rangeCall)) { if (codegen.canBeSpecializedByExcludingHighBound(rangeCall)) {
val highBound = (rangeCall.getFirstArgumentExpression() as KtBinaryExpression).left val highBound = (rangeCall.getFirstArgumentExpression() as KtBinaryExpression).left
return SimpleBoundedValue( return SimpleBoundedValue(instanceType, lowBound, true, codegen.gen(highBound), false)
codegen,
rangeCall,
codegen.generateCallReceiver(rangeCall),
true,
codegen.gen(highBound),
false
)
} }
return SimpleBoundedValue(codegen, rangeCall) return SimpleBoundedValue(
instanceType = instanceType,
lowBound = lowBound,
highBound = codegen.generateCallSingleArgument(rangeCall)
)
} }
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator = override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen.range package org.jetbrains.kotlin.codegen.range
import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.generateCallReceiver
import org.jetbrains.kotlin.codegen.generateCallSingleArgument import org.jetbrains.kotlin.codegen.generateCallSingleArgument
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
@@ -29,7 +30,13 @@ class PrimitiveNumberUntilRangeValue(rangeCall: ResolvedCall<out CallableDescrip
PrimitiveNumberRangeIntrinsicRangeValue(rangeCall), ReversableRangeValue { PrimitiveNumberRangeIntrinsicRangeValue(rangeCall), ReversableRangeValue {
override fun getBoundedValue(codegen: ExpressionCodegen) = override fun getBoundedValue(codegen: ExpressionCodegen) =
SimpleBoundedValue(codegen, rangeCall, isLowInclusive = true, isHighInclusive = false) SimpleBoundedValue(
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
codegen.generateCallReceiver(rangeCall),
true,
codegen.generateCallSingleArgument(rangeCall),
false
)
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen)) ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
@@ -30,8 +30,6 @@ interface ReversableRangeValue : RangeValue {
interface BoundedValue { interface BoundedValue {
val instanceType: Type val instanceType: Type
fun putInstance(v: InstructionAdapter, type: Type)
// It is necessary to maintain the proper evaluation order as of Kotlin 1.0 and 1.1 // It is necessary to maintain the proper evaluation order as of Kotlin 1.0 and 1.1
// to evaluate range bounds left to right and put them on stack as 'high; low'. // to evaluate range bounds left to right and put them on stack as 'high; low'.
fun putHighLow(v: InstructionAdapter, type: Type) fun putHighLow(v: InstructionAdapter, type: Type)
@@ -39,10 +37,3 @@ interface BoundedValue {
val isLowInclusive: Boolean val isLowInclusive: Boolean
val isHighInclusive: Boolean val isHighInclusive: Boolean
} }
fun BoundedValue.asStackValue(): StackValue =
object : StackValue(instanceType) {
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
putInstance(v, type)
}
}
@@ -22,34 +22,16 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
/**
* Low level abstraction for bounded range that is used to generate contains checks and for loops.
*/
class SimpleBoundedValue( class SimpleBoundedValue(
codegen: ExpressionCodegen, instanceType: Type,
rangeCall: ResolvedCall<out CallableDescriptor>,
val lowBound: StackValue, val lowBound: StackValue,
isLowInclusive: Boolean, isLowInclusive: Boolean = true,
val highBound: StackValue, val highBound: StackValue,
isHighInclusive: Boolean isHighInclusive: Boolean = true
) : AbstractBoundedValue(codegen, rangeCall, isLowInclusive, isHighInclusive) { ) : AbstractBoundedValue(instanceType, isLowInclusive, isHighInclusive) {
constructor(
codegen: ExpressionCodegen,
rangeCall: ResolvedCall<out CallableDescriptor>,
isLowInclusive: Boolean = true,
isHighInclusive: Boolean = true
) : this(
codegen,
rangeCall,
codegen.generateCallReceiver(rangeCall),
isLowInclusive,
codegen.generateCallSingleArgument(rangeCall),
isHighInclusive
)
constructor(
codegen: ExpressionCodegen,
rangeCall: ResolvedCall<out CallableDescriptor>,
lowBound: StackValue,
highBound: StackValue
) : this(codegen, rangeCall, lowBound, true, highBound, true)
override fun putHighLow(v: InstructionAdapter, type: Type) { override fun putHighLow(v: InstructionAdapter, type: Type) {
if (!lowBound.canHaveSideEffects() || !highBound.canHaveSideEffects()) { if (!lowBound.canHaveSideEffects() || !highBound.canHaveSideEffects()) {