Fix KT-43530

This commit is contained in:
Sergey Bogolepov
2020-11-23 21:00:22 +07:00
committed by Stanislav Erokhin
parent 5fc17ce5fa
commit 30345c3708
2 changed files with 31 additions and 5 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.*
@@ -110,6 +111,24 @@ internal class KonanSymbols(
}
}.toMap()
private val binaryOperatorCache = mutableMapOf<Triple<Name, KotlinType, KotlinType>, IrSimpleFunctionSymbol>()
/**
* A less restrictive version of [getBinaryOperator] that should be used when symbols might not be bound yet.
* Note that it is a hack that will be removed in a foreseeable future. Consider using [getBinaryOperator] instead.
*
* TODO: Remove with [org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumByValueFunctionGenerator].
*/
fun getBinaryOperatorMaybeUnbound(name: Name, lhsType: KotlinType, rhsType: KotlinType): IrSimpleFunctionSymbol {
val key = Triple(name, lhsType, rhsType)
return binaryOperatorCache.getOrPut(key) {
symbolTable.referenceSimpleFunction(
lhsType.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND)
.first { it.valueParameters.size == 1 && it.valueParameters[0].type == rhsType }
)
}
}
val arrayList = symbolTable.referenceClass(getArrayListClassDescriptor(context))
val symbolName = topLevelClass(RuntimeNames.symbolNameAnnotation)
@@ -56,22 +56,29 @@ internal class CEnumByValueFunctionGenerator(
val values = irTemporary(irCall(valuesIrFunctionSymbol), isMutable = true)
val inductionVariable = irTemporary(irInt(0), isMutable = true)
val arrayClass = values.type.classOrNull!!
val valuesSize = irCall(symbols.arraySize.getValue(arrayClass), irBuiltIns.intType).also { irCall ->
val valuesSize = IrCallImpl.fromSymbolDescriptor(
startOffset, endOffset, irBuiltIns.intType, symbols.arraySize.getValue(arrayClass)
).also { irCall ->
irCall.dispatchReceiver = irGet(values)
}
val getElementFn = symbols.arrayGet.getValue(arrayClass)
val plusFun = symbols.getBinaryOperator(OperatorNameConventions.PLUS, irBuiltIns.intType, irBuiltIns.intType)
val plusFun = symbols.getBinaryOperatorMaybeUnbound(OperatorNameConventions.PLUS, irBuiltIns.int, irBuiltIns.int)
val lessFunctionSymbol = irBuiltIns.lessFunByOperandType.getValue(irBuiltIns.intClass)
+irWhile().also { loop ->
loop.condition = irCall(lessFunctionSymbol, irBuiltIns.booleanType).also { irCall ->
loop.condition = IrCallImpl.fromSymbolDescriptor(
startOffset, endOffset, irBuiltIns.booleanType, lessFunctionSymbol
).also { irCall ->
irCall.putValueArgument(0, irGet(inductionVariable))
irCall.putValueArgument(1, valuesSize)
}
loop.body = irBlock {
val entry = irTemporary(irCall(getElementFn, byValueIrFunction.returnType).also { irCall ->
val temporaryValue = IrCallImpl.fromSymbolDescriptor(
startOffset, endOffset,byValueIrFunction.returnType, getElementFn
).also { irCall ->
irCall.dispatchReceiver = irGet(values)
irCall.putValueArgument(0, irGet(inductionVariable))
}, isMutable = true)
}
val entry = irTemporary(temporaryValue, isMutable = true)
val valueGetter = entry.type.getClass()!!.getPropertyGetter("value")!!
val entryValue = irGet(irValueParameter.type, irGet(entry), valueGetter)
+irIfThenElse(