diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt index a4b38853084..d53a96c14c8 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt @@ -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, 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) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt index ea65b605557..0bfe0b46307 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt @@ -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(