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
abstract class AbstractBoundedValue(
protected val codegen: ExpressionCodegen,
protected val rangeCall: ResolvedCall<out CallableDescriptor>,
override val instanceType: Type,
override val isLowInclusive: Boolean = true,
override val isHighInclusive: Boolean = true
) : 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) =
SimpleBoundedValue(
codegen, rangeCall,
lowBound = StackValue.constant(0, asmElementType),
isLowInclusive = true,
highBound = StackValue.operation(Type.INT_TYPE) { v ->
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
StackValue.constant(0, asmElementType),
true,
StackValue.operation(Type.INT_TYPE) { v ->
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
v.arraylength()
},
isHighInclusive = false
false
)
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
@@ -34,14 +34,14 @@ class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescript
override fun getBoundedValue(codegen: ExpressionCodegen) =
SimpleBoundedValue(
codegen, rangeCall,
lowBound = StackValue.constant(0, asmElementType),
isLowInclusive = true,
highBound = StackValue.operation(Type.INT_TYPE) { v ->
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
StackValue.constant(0, asmElementType),
true,
StackValue.operation(Type.INT_TYPE) { v ->
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
v.invokeinterface("java/lang/CharSequence", "length", "()I")
},
isHighInclusive = false
false
)
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
@@ -34,14 +34,14 @@ class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
override fun getBoundedValue(codegen: ExpressionCodegen) =
SimpleBoundedValue(
codegen, rangeCall,
lowBound = StackValue.constant(0, asmElementType),
isLowInclusive = true,
highBound = StackValue.operation(Type.INT_TYPE) { v ->
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
StackValue.constant(0, asmElementType),
true,
StackValue.operation(Type.INT_TYPE) { v ->
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), v)
v.invokeinterface("java/util/Collection", "size", "()I")
},
isHighInclusive = false
false
)
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
@@ -17,6 +17,8 @@
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.isClosedRangeContains
import org.jetbrains.kotlin.codegen.range.forLoop.IteratorForLoopGenerator
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeOfComparableExpressionGenerator
@@ -29,7 +31,11 @@ class ComparableRangeLiteralRangeValue(
codegen: ExpressionCodegen,
rangeCall: ResolvedCall<out CallableDescriptor>
) : 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) =
IteratorForLoopGenerator(codegen, forExpression)
@@ -32,7 +32,7 @@ class DownToProgressionRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
override fun getBoundedValue(codegen: ExpressionCodegen) =
SimpleBoundedValue(
codegen, rangeCall,
instanceType = codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
lowBound = codegen.generateCallSingleArgument(rangeCall),
highBound = codegen.generateCallReceiver(rangeCall)
)
@@ -36,18 +36,17 @@ class PrimitiveNumberRangeLiteralRangeValue(
ReversableRangeValue {
override fun getBoundedValue(codegen: ExpressionCodegen): SimpleBoundedValue {
val instanceType = codegen.asmType(rangeCall.resultingDescriptor.returnType!!)
val lowBound = codegen.generateCallReceiver(rangeCall)
if (codegen.canBeSpecializedByExcludingHighBound(rangeCall)) {
val highBound = (rangeCall.getFirstArgumentExpression() as KtBinaryExpression).left
return SimpleBoundedValue(
codegen,
rangeCall,
codegen.generateCallReceiver(rangeCall),
true,
codegen.gen(highBound),
false
)
return SimpleBoundedValue(instanceType, lowBound, 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 =
@@ -17,6 +17,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.forLoop.ForInSimpleProgressionLoopGenerator
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
@@ -29,7 +30,13 @@ class PrimitiveNumberUntilRangeValue(rangeCall: ResolvedCall<out CallableDescrip
PrimitiveNumberRangeIntrinsicRangeValue(rangeCall), ReversableRangeValue {
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) =
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
@@ -30,8 +30,6 @@ interface ReversableRangeValue : RangeValue {
interface BoundedValue {
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
// to evaluate range bounds left to right and put them on stack as 'high; low'.
fun putHighLow(v: InstructionAdapter, type: Type)
@@ -39,10 +37,3 @@ interface BoundedValue {
val isLowInclusive: 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.commons.InstructionAdapter
/**
* Low level abstraction for bounded range that is used to generate contains checks and for loops.
*/
class SimpleBoundedValue(
codegen: ExpressionCodegen,
rangeCall: ResolvedCall<out CallableDescriptor>,
instanceType: Type,
val lowBound: StackValue,
isLowInclusive: Boolean,
isLowInclusive: Boolean = true,
val highBound: StackValue,
isHighInclusive: Boolean
) : AbstractBoundedValue(codegen, rangeCall, 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)
isHighInclusive: Boolean = true
) : AbstractBoundedValue(instanceType, isLowInclusive, isHighInclusive) {
override fun putHighLow(v: InstructionAdapter, type: Type) {
if (!lowBound.canHaveSideEffects() || !highBound.canHaveSideEffects()) {