Use ForInSimpleProgressionLoopGenerator for most of the loop intrinsics
This commit is contained in:
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.range
|
|||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInArrayIndicesRangeLoopGenerator
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||||
|
|
||||||
private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
||||||
|
|
||||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||||
@@ -42,6 +43,5 @@ class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): P
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInArrayIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
|
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.range
|
|||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInCharSequenceIndicesRangeLoopGenerator
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -42,5 +42,5 @@ class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescript
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInCharSequenceIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
|
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||||
}
|
}
|
||||||
+2
-2
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.range
|
|||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInCollectionIndicesRangeLoopGenerator
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -42,5 +42,5 @@ class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInCollectionIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
|
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||||
}
|
}
|
||||||
+2
-2
@@ -19,7 +19,7 @@ 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.generateCallReceiver
|
||||||
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInDownToProgressionLoopGenerator
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -33,5 +33,5 @@ class DownToProgressionRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInDownToProgressionLoopGenerator(codegen, forExpression, rangeCall)
|
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(codegen, forExpression, getBoundedValue(codegen))
|
||||||
}
|
}
|
||||||
+22
-6
@@ -17,24 +17,30 @@
|
|||||||
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.range.forLoop.ForInRangeLiteralLoopGenerator
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInUntilConstantRangeLoopGenerator
|
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
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.constants.*
|
import org.jetbrains.kotlin.resolve.constants.ByteValue
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.IntValue
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.ShortValue
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class PrimitiveNumberRangeLiteralRangeValue(
|
class PrimitiveNumberRangeLiteralRangeValue(
|
||||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
rangeCall: ResolvedCall<out CallableDescriptor>
|
||||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||||
|
|
||||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||||
SimpleBoundedValue(codegen, rangeCall)
|
SimpleBoundedValue(codegen, rangeCall)
|
||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||||
getConstRangeForInRangeLiteralGenerator(codegen, forExpression) ?:
|
getConstRangeForInRangeLiteralGenerator(codegen, forExpression) ?:
|
||||||
ForInRangeLiteralLoopGenerator(codegen, forExpression, rangeCall)
|
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||||
|
|
||||||
private fun getConstRangeForInRangeLiteralGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator? {
|
private fun getConstRangeForInRangeLiteralGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator? {
|
||||||
val rhsExpression = rangeCall.valueArgumentsByIndex?.run { get(0).arguments[0].getArgumentExpression() } ?: return null
|
val rhsExpression = rangeCall.valueArgumentsByIndex?.run { get(0).arguments[0].getArgumentExpression() } ?: return null
|
||||||
@@ -45,8 +51,18 @@ class PrimitiveNumberRangeLiteralRangeValue(
|
|||||||
is IntValue -> constValue.value + 1
|
is IntValue -> constValue.value + 1
|
||||||
else -> return null
|
else -> return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch out for integer overflow
|
// Watch out for integer overflow
|
||||||
if (untilValue == Int.MIN_VALUE) return null
|
return if (untilValue == Int.MIN_VALUE)
|
||||||
return ForInUntilConstantRangeLoopGenerator(codegen, forExpression, rangeCall, untilValue)
|
null
|
||||||
|
else
|
||||||
|
ForInSimpleProgressionLoopGenerator(
|
||||||
|
codegen, forExpression,
|
||||||
|
startValue = codegen.generateCallReceiver(rangeCall),
|
||||||
|
isStartInclusive = true,
|
||||||
|
endValue = StackValue.integerConstant(untilValue, asmElementType),
|
||||||
|
isEndInclusive = false,
|
||||||
|
step = 1
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -17,7 +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.range.forLoop.ForInUntilRangeLoopGenerator
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -27,5 +27,5 @@ class PrimitiveNumberUntilRangeValue(rangeCall: ResolvedCall<out CallableDescrip
|
|||||||
SimpleBoundedValue(codegen, rangeCall, isLowInclusive = true, isHighInclusive = false)
|
SimpleBoundedValue(codegen, rangeCall, isLowInclusive = true, isHighInclusive = false)
|
||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInUntilRangeLoopGenerator(codegen, forExpression, rangeCall)
|
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||||
}
|
}
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
|
||||||
|
|
||||||
abstract class AbstractForInExclusiveRangeLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression
|
|
||||||
) : AbstractForInRangeWithGivenBoundsLoopGenerator(codegen, forExpression) {
|
|
||||||
override fun checkEmptyLoop(loopExit: Label) {}
|
|
||||||
|
|
||||||
override fun checkPreCondition(loopExit: Label) {
|
|
||||||
loopParameter().put(asmElementType, v)
|
|
||||||
v.load(endVar, asmElementType)
|
|
||||||
if (asmElementType.sort == Type.LONG) {
|
|
||||||
v.lcmp()
|
|
||||||
v.ifge(loopExit)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.ificmpge(loopExit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun checkPostConditionAndIncrement(loopExit: Label) {
|
|
||||||
incrementLoopVariable()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
|
|
||||||
abstract class AbstractForInRangeLoopGenerator : AbstractForInProgressionOrRangeLoopGenerator {
|
abstract class AbstractForInRangeLoopGenerator : AbstractForInProgressionOrRangeLoopGenerator {
|
||||||
private val step: Int
|
protected val step: Int
|
||||||
|
|
||||||
constructor(codegen: ExpressionCodegen, forExpression: KtForExpression, step: Int) : super(codegen, forExpression) {
|
constructor(codegen: ExpressionCodegen, forExpression: KtForExpression, step: Int) : super(codegen, forExpression) {
|
||||||
assert(step == 1 || step == -1) { "'step' should be either 1 or -1: " + step }
|
assert(step == 1 || step == -1) { "'step' should be either 1 or -1: " + step }
|
||||||
|
|||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
|
|
||||||
abstract class AbstractForInRangeWithGivenBoundsLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
step: Int = 1
|
|
||||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression, step) {
|
|
||||||
protected abstract fun generateFrom(): StackValue
|
|
||||||
protected abstract fun generateTo(): StackValue
|
|
||||||
|
|
||||||
override fun storeRangeStartAndEnd() {
|
|
||||||
loopParameter().store(generateFrom(), v)
|
|
||||||
StackValue.local(endVar, asmElementType).store(generateTo(), v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|
||||||
|
|
||||||
class ForInArrayIndicesRangeLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
loopRangeCall: ResolvedCall<*>
|
|
||||||
) : ForInOptimizedIndicesLoopGenerator(codegen, forExpression, loopRangeCall) {
|
|
||||||
override fun getReceiverSizeAsInt() {
|
|
||||||
v.arraylength()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|
||||||
|
|
||||||
class ForInCharSequenceIndicesRangeLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
loopRangeCall: ResolvedCall<*>
|
|
||||||
) : ForInOptimizedIndicesLoopGenerator(codegen, forExpression, loopRangeCall) {
|
|
||||||
|
|
||||||
override fun getReceiverSizeAsInt() {
|
|
||||||
v.invokeinterface("java/lang/CharSequence", "length", "()I")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|
||||||
|
|
||||||
class ForInCollectionIndicesRangeLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
loopRangeCall: ResolvedCall<*>
|
|
||||||
) : ForInOptimizedIndicesLoopGenerator(codegen, forExpression, loopRangeCall) {
|
|
||||||
override fun getReceiverSizeAsInt() {
|
|
||||||
v.invokeinterface("java/util/Collection", "size", "()I")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
|
|
||||||
class ForInDownToProgressionLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
loopRangeCall: ResolvedCall<*>
|
|
||||||
) : AbstractForInRangeWithGivenBoundsLoopGenerator(codegen, forExpression, -1) {
|
|
||||||
private val from: ReceiverValue = loopRangeCall.extensionReceiver!!
|
|
||||||
private val to: KtExpression = ExpressionCodegen.getSingleArgumentExpression(loopRangeCall)!!
|
|
||||||
|
|
||||||
override fun generateFrom(): StackValue = codegen.generateReceiverValue(from, false)
|
|
||||||
|
|
||||||
override fun generateTo(): StackValue = codegen.gen(to)
|
|
||||||
}
|
|
||||||
-48
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
|
||||||
|
|
||||||
abstract class ForInOptimizedIndicesLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
loopRangeCall: ResolvedCall<*>
|
|
||||||
) : AbstractForInExclusiveRangeLoopGenerator(codegen, forExpression) {
|
|
||||||
protected val receiverValue: ReceiverValue = loopRangeCall.extensionReceiver!!
|
|
||||||
protected val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(loopRangeCall)
|
|
||||||
|
|
||||||
override fun generateFrom(): StackValue =
|
|
||||||
StackValue.constant(0, asmElementType)
|
|
||||||
|
|
||||||
override fun generateTo(): StackValue =
|
|
||||||
StackValue.operation(Type.INT_TYPE) { v ->
|
|
||||||
codegen.generateReceiverValue(receiverValue, false).put(codegen.asmType(expectedReceiverType), v)
|
|
||||||
getReceiverSizeAsInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `(receiver -> size:I)`
|
|
||||||
*/
|
|
||||||
protected abstract fun getReceiverSizeAsInt()
|
|
||||||
}
|
|
||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
|
|
||||||
class ForInRangeLiteralLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
loopRangeCall: ResolvedCall<*>
|
|
||||||
) : AbstractForInRangeWithGivenBoundsLoopGenerator(codegen, forExpression) {
|
|
||||||
private val from: ReceiverValue = loopRangeCall.dispatchReceiver!!
|
|
||||||
private val to: KtExpression = ExpressionCodegen.getSingleArgumentExpression(loopRangeCall)!!
|
|
||||||
|
|
||||||
override fun generateFrom(): StackValue = codegen.generateReceiverValue(from, false)
|
|
||||||
|
|
||||||
override fun generateTo(): StackValue = codegen.gen(to)
|
|
||||||
|
|
||||||
override fun storeRangeStartAndEnd() {
|
|
||||||
loopParameter().store(generateFrom(), v)
|
|
||||||
StackValue.local(endVar, asmElementType).store(generateTo(), v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+98
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.psi.KtForExpression
|
||||||
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
|
class ForInSimpleProgressionLoopGenerator(
|
||||||
|
codegen: ExpressionCodegen,
|
||||||
|
forExpression: KtForExpression,
|
||||||
|
private val startValue: StackValue,
|
||||||
|
private val isStartInclusive: Boolean,
|
||||||
|
private val endValue: StackValue,
|
||||||
|
private val isEndInclusive: Boolean,
|
||||||
|
step: Int
|
||||||
|
) : AbstractForInRangeLoopGenerator(codegen, forExpression, step) {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
codegen: ExpressionCodegen,
|
||||||
|
forExpression: KtForExpression,
|
||||||
|
boundedValue: SimpleBoundedValue,
|
||||||
|
step: Int
|
||||||
|
) : this(
|
||||||
|
codegen, forExpression,
|
||||||
|
startValue = if (step == 1) boundedValue.lowBound else boundedValue.highBound,
|
||||||
|
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,
|
||||||
|
step = step
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromBoundedValueWithStep1(codegen: ExpressionCodegen, forExpression: KtForExpression, boundedValue: SimpleBoundedValue) =
|
||||||
|
ForInSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, 1)
|
||||||
|
|
||||||
|
fun fromBoundedValueWithStepMinus1(codegen: ExpressionCodegen, forExpression: KtForExpression, boundedValue: SimpleBoundedValue) =
|
||||||
|
ForInSimpleProgressionLoopGenerator(codegen, forExpression, boundedValue, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun storeRangeStartAndEnd() {
|
||||||
|
loopParameter().store(startValue, v)
|
||||||
|
// Skip 1st element if start is not inclusive.
|
||||||
|
if (!isStartInclusive) incrementLoopVariable()
|
||||||
|
|
||||||
|
StackValue.local(endVar, asmElementType).store(endValue, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun checkEmptyLoop(loopExit: Label) {
|
||||||
|
// No check required if end is non-inclusive: loop is generated with pre-condition.
|
||||||
|
if (isEndInclusive) {
|
||||||
|
super.checkEmptyLoop(loopExit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun checkPreCondition(loopExit: Label) {
|
||||||
|
// Generate pre-condition loop if end is not inclusive.
|
||||||
|
if (!isEndInclusive) {
|
||||||
|
loopParameter().put(asmElementType, v)
|
||||||
|
v.load(endVar, asmElementType)
|
||||||
|
if (asmElementType.sort == Type.LONG) {
|
||||||
|
v.lcmp()
|
||||||
|
v.ifge(loopExit)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v.ificmpge(loopExit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun checkPostConditionAndIncrement(loopExit: Label) {
|
||||||
|
// Generate post-condition loop if end is inclusive.
|
||||||
|
// Otherwise, just increment the loop variable.
|
||||||
|
if (isEndInclusive) {
|
||||||
|
super.checkPostConditionAndIncrement(loopExit)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
incrementLoopVariable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
|
|
||||||
class ForInUntilConstantRangeLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
loopRangeCall: ResolvedCall<*>,
|
|
||||||
private val untilValue: Int
|
|
||||||
) : AbstractForInExclusiveRangeLoopGenerator(codegen, forExpression) {
|
|
||||||
private val from: ReceiverValue = loopRangeCall.dispatchReceiver!!
|
|
||||||
|
|
||||||
override fun generateFrom(): StackValue =
|
|
||||||
codegen.generateReceiverValue(from, false)
|
|
||||||
|
|
||||||
override fun generateTo(): StackValue =
|
|
||||||
StackValue.integerConstant(untilValue, asmElementType)
|
|
||||||
}
|
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
|
|
||||||
class ForInUntilRangeLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
loopRangeCall: ResolvedCall<*>
|
|
||||||
) : AbstractForInExclusiveRangeLoopGenerator(codegen, forExpression) {
|
|
||||||
private val from: ReceiverValue = loopRangeCall.extensionReceiver!!
|
|
||||||
private val to: KtExpression = ExpressionCodegen.getSingleArgumentExpression(loopRangeCall)!!
|
|
||||||
|
|
||||||
override fun generateFrom(): StackValue =
|
|
||||||
codegen.generateReceiverValue(from, false)
|
|
||||||
|
|
||||||
override fun generateTo(): StackValue =
|
|
||||||
codegen.gen(to)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user