Skip to content
This repository has been archived by the owner on Aug 10, 2021. It is now read-only.

Commit

Permalink
Fix KT-43530
Browse files Browse the repository at this point in the history
  • Loading branch information
sbogolepov committed Nov 27, 2020
1 parent 48f27c1 commit 9c1fc56
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down

0 comments on commit 9c1fc56

Please sign in to comment.