[K/N] Store ordinal value in lowered enum

This commit is contained in:
Pavel Kunyavskiy
2021-05-19 12:14:00 +03:00
committed by Space
parent 8a418161f6
commit 1dd6dcdeef
3 changed files with 19 additions and 14 deletions
@@ -39,6 +39,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM") internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM")
internal data class LoweredEnumEntryDescription(val ordinal: Int, val getterId: Int)
/** /**
* Common interface for both [InternalLoweredEnum] and [ExternalLoweredEnum] * Common interface for both [InternalLoweredEnum] and [ExternalLoweredEnum]
* that allows to work with lowered enum regardless of its location. * that allows to work with lowered enum regardless of its location.
@@ -46,7 +48,7 @@ internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM")
internal interface LoweredEnumAccess { internal interface LoweredEnumAccess {
val valuesGetter: IrSimpleFunction val valuesGetter: IrSimpleFunction
val itemGetterSymbol: IrSimpleFunctionSymbol val itemGetterSymbol: IrSimpleFunctionSymbol
val entriesMap: Map<Name, Int> val entriesMap: Map<Name, LoweredEnumEntryDescription>
fun getValuesField(startOffset: Int, endOffset: Int): IrExpression fun getValuesField(startOffset: Int, endOffset: Int): IrExpression
} }
@@ -59,7 +61,7 @@ internal data class InternalLoweredEnum(
val valuesGetterWrapper: IrSimpleFunction, val valuesGetterWrapper: IrSimpleFunction,
override val valuesGetter: IrSimpleFunction, override val valuesGetter: IrSimpleFunction,
override val itemGetterSymbol: IrSimpleFunctionSymbol, override val itemGetterSymbol: IrSimpleFunctionSymbol,
override val entriesMap: Map<Name, Int> override val entriesMap: Map<Name, LoweredEnumEntryDescription>
) : LoweredEnumAccess { ) : LoweredEnumAccess {
private fun internalObjectGetter(startOffset: Int, endOffset: Int) = private fun internalObjectGetter(startOffset: Int, endOffset: Int) =
IrGetObjectValueImpl(startOffset, endOffset, IrGetObjectValueImpl(startOffset, endOffset,
@@ -82,7 +84,7 @@ internal data class InternalLoweredEnum(
internal data class ExternalLoweredEnum( internal data class ExternalLoweredEnum(
override val valuesGetter: IrSimpleFunction, override val valuesGetter: IrSimpleFunction,
override val itemGetterSymbol: IrSimpleFunctionSymbol, override val itemGetterSymbol: IrSimpleFunctionSymbol,
override val entriesMap: Map<Name, Int> override val entriesMap: Map<Name, LoweredEnumEntryDescription>
) : LoweredEnumAccess { ) : LoweredEnumAccess {
override fun getValuesField(startOffset: Int, endOffset: Int): IrExpression = override fun getValuesField(startOffset: Int, endOffset: Int): IrExpression =
IrCallImpl(startOffset, endOffset, valuesGetter.returnType, valuesGetter.symbol, valuesGetter.typeParameters.size, valuesGetter.valueParameters.size) IrCallImpl(startOffset, endOffset, valuesGetter.returnType, valuesGetter.symbol, valuesGetter.typeParameters.size, valuesGetter.valueParameters.size)
@@ -91,13 +93,16 @@ internal data class ExternalLoweredEnum(
internal class EnumSpecialDeclarationsFactory(val context: Context) { internal class EnumSpecialDeclarationsFactory(val context: Context) {
private val symbols = context.ir.symbols private val symbols = context.ir.symbols
private fun enumEntriesMap(enumClass: IrClass): Map<Name, Int> = private fun enumEntriesMap(enumClass: IrClass): Map<Name, LoweredEnumEntryDescription> {
enumClass.declarations data class NameWithOrdinal(val name: Name, val ordinal: Int)
.filterIsInstance<IrEnumEntry>() return enumClass.declarations.asSequence()
.sortedBy { it.name } .filterIsInstance<IrEnumEntry>()
.withIndex() .mapIndexed { index, it -> NameWithOrdinal(it.name, index) }
.associate { it.value.name to it.index } .sortedBy { it.name }
.toMap() .withIndex()
.associate { it.value.name to LoweredEnumEntryDescription(it.value.ordinal, it.index) }
.toMap()
}
private fun findItemGetterSymbol(): IrSimpleFunctionSymbol = private fun findItemGetterSymbol(): IrSimpleFunctionSymbol =
symbols.array.functions.single { it.descriptor.name == Name.identifier("get") } symbols.array.functions.single { it.descriptor.name == Name.identifier("get") }
@@ -1189,7 +1189,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
val enumClass = enumEntry.parentAsClass val enumClass = enumEntry.parentAsClass
val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass)
val ordinal = loweredEnum.entriesMap[enumEntry.name]!! val getterId = loweredEnum.entriesMap[enumEntry.name]!!.getterId
val values = call( val values = call(
loweredEnum.valuesGetter.llvmFunction, loweredEnum.valuesGetter.llvmFunction,
emptyList(), emptyList(),
@@ -1199,7 +1199,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
return call( return call(
loweredEnum.itemGetterSymbol.owner.llvmFunction, loweredEnum.itemGetterSymbol.owner.llvmFunction,
listOf(values, Int32(ordinal).llvm), listOf(values, Int32(getterId).llvm),
Lifetime.GLOBAL, Lifetime.GLOBAL,
exceptionHandler exceptionHandler
) )
@@ -101,10 +101,10 @@ internal class EnumUsageLowering(val context: Context)
private fun IrBuilderWithScope.loadEnumEntry(enumClass: IrClass, name: Name): IrExpression { private fun IrBuilderWithScope.loadEnumEntry(enumClass: IrClass, name: Name): IrExpression {
val loweredEnum = this@EnumUsageLowering.context.specialDeclarationsFactory.getLoweredEnum(enumClass) val loweredEnum = this@EnumUsageLowering.context.specialDeclarationsFactory.getLoweredEnum(enumClass)
val ordinal = loweredEnum.entriesMap.getValue(name) val getterId = loweredEnum.entriesMap.getValue(name).getterId
return irCall(loweredEnum.itemGetterSymbol, enumClass.defaultType).apply { return irCall(loweredEnum.itemGetterSymbol, enumClass.defaultType).apply {
dispatchReceiver = irCall(loweredEnum.valuesGetter) dispatchReceiver = irCall(loweredEnum.valuesGetter)
putValueArgument(0, irInt(ordinal)) putValueArgument(0, irInt(getterId))
} }
} }
} }