[K/N][IR] Refactored enum builder

This commit is contained in:
Igor Chevdar
2022-08-05 14:52:49 +03:00
committed by Space
parent 60ea26750e
commit e6e04e66b9
5 changed files with 48 additions and 52 deletions
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
import org.jetbrains.kotlin.ir.deepCopyWithVariables
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
@@ -61,49 +60,8 @@ internal class NativeMapping : DefaultMapping() {
val bridges = mutableMapOf<BridgeKey, IrSimpleFunction>() val bridges = mutableMapOf<BridgeKey, IrSimpleFunction>()
val notLoweredInlineFunctions = mutableMapOf<IrFunctionSymbol, IrFunction>() val notLoweredInlineFunctions = mutableMapOf<IrFunctionSymbol, IrFunction>()
val loweredInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>() val loweredInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>()
} val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
val externalLoweredEnums = mutableMapOf<IrClass, ExternalLoweredEnum>()
/**
* Offset for synthetic elements created by lowerings and not attributable to other places in the source code.
*/
internal class SpecialDeclarationsFactory(val context: Context) {
private val enumSpecialDeclarationsFactory by lazy { EnumSpecialDeclarationsFactory(context) }
private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
private val externalLoweredEnums = mutableMapOf<IrClass, ExternalLoweredEnum>()
fun getLoweredEnumOrNull(enumClass: IrClass): LoweredEnumAccess? {
assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" }
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
externalLoweredEnums[enumClass]
} else {
internalLoweredEnums[enumClass]
}
}
fun getLoweredEnum(enumClass: IrClass): LoweredEnumAccess {
assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" }
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
externalLoweredEnums.getOrPut(enumClass) {
enumSpecialDeclarationsFactory.createExternalLoweredEnum(enumClass)
}
} else {
internalLoweredEnums.getOrPut(enumClass) {
enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass)
}
}
}
fun getInternalLoweredEnum(enumClass: IrClass): InternalLoweredEnum {
assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" }
assert(context.llvmModuleSpecification.containsDeclaration(enumClass)) { "Expected enum class from current module." }
return internalLoweredEnums.getOrPut(enumClass) {
enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass)
}
}
fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) =
enumEntry.parentAsClass.declarations.filterIsInstance<IrEnumEntry>().indexOf(enumEntry)
} }
internal class Context(config: KonanConfig) : KonanBackendContext(config) { internal class Context(config: KonanConfig) : KonanBackendContext(config) {
@@ -140,10 +98,10 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
builtIns.builtInsModule.getPackage(KonanFqNames.packageName).memberScope.getContributedFunctions("immutableBlobOf").single() builtIns.builtInsModule.getPackage(KonanFqNames.packageName).memberScope.getContributedFunctions("immutableBlobOf").single()
} }
val specialDeclarationsFactory = SpecialDeclarationsFactory(this)
val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) } val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) }
val bridgesSupport by lazy { BridgesSupport(mapping, irBuiltIns, irFactory) } val bridgesSupport by lazy { BridgesSupport(mapping, irBuiltIns, irFactory) }
val inlineFunctionsSupport by lazy { InlineFunctionsSupport(mapping) } val inlineFunctionsSupport by lazy { InlineFunctionsSupport(mapping) }
val enumsSupport by lazy { EnumsSupport(this) }
open class LazyMember<T>(val initializer: Context.() -> T) { open class LazyMember<T>(val initializer: Context.() -> T) {
operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this) operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this)
@@ -31,6 +31,44 @@ import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal class EnumsSupport(private val context: Context) {
private val enumSpecialDeclarationsFactory = EnumSpecialDeclarationsFactory(context)
private val internalLoweredEnums = context.mapping.internalLoweredEnums
private val externalLoweredEnums = context.mapping.externalLoweredEnums
fun getLoweredEnumOrNull(enumClass: IrClass): LoweredEnumAccess? {
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
externalLoweredEnums[enumClass]
} else {
internalLoweredEnums[enumClass]
}
}
fun getLoweredEnum(enumClass: IrClass): LoweredEnumAccess {
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
externalLoweredEnums.getOrPut(enumClass) {
enumSpecialDeclarationsFactory.createExternalLoweredEnum(enumClass)
}
} else {
internalLoweredEnums.getOrPut(enumClass) {
enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass)
}
}
}
fun getInternalLoweredEnum(enumClass: IrClass): InternalLoweredEnum {
require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" }
require(context.llvmModuleSpecification.containsDeclaration(enumClass)) { "Expected enum class from current module." }
return internalLoweredEnums.getOrPut(enumClass) {
enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass)
}
}
fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) =
enumEntry.parentAsClass.declarations.filterIsInstance<IrEnumEntry>().indexOf(enumEntry)
}
internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM") internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM")
@@ -1349,7 +1349,7 @@ internal abstract class FunctionGenerationContext(
*/ */
fun getEnumEntry(enumEntry: IrEnumEntry, exceptionHandler: ExceptionHandler): LLVMValueRef { fun getEnumEntry(enumEntry: IrEnumEntry, exceptionHandler: ExceptionHandler): LLVMValueRef {
val enumClass = enumEntry.parentAsClass val enumClass = enumEntry.parentAsClass
val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) val loweredEnum = context.enumsSupport.getLoweredEnum(enumClass)
val getterId = loweredEnum.entriesMap[enumEntry.name]!!.getterId val getterId = loweredEnum.entriesMap[enumEntry.name]!!.getterId
val values = call( val values = call(
@@ -34,14 +34,14 @@ import org.jetbrains.kotlin.name.Name
private class EnumSyntheticFunctionsBuilder(val context: Context) { private class EnumSyntheticFunctionsBuilder(val context: Context) {
fun IrBuilderWithScope.enumValues(enumClass: IrClass): IrExpression { fun IrBuilderWithScope.enumValues(enumClass: IrClass): IrExpression {
val loweredEnum = this@EnumSyntheticFunctionsBuilder.context.specialDeclarationsFactory.getLoweredEnum(enumClass) val loweredEnum = this@EnumSyntheticFunctionsBuilder.context.enumsSupport.getLoweredEnum(enumClass)
return irCall(genericValuesSymbol, listOf(enumClass.defaultType)).apply { return irCall(genericValuesSymbol, listOf(enumClass.defaultType)).apply {
putValueArgument(0, loweredEnum.getValuesField(startOffset, endOffset)) putValueArgument(0, loweredEnum.getValuesField(startOffset, endOffset))
} }
} }
fun IrBuilderWithScope.enumValueOf(enumClass: IrClass, value: IrExpression): IrExpression { fun IrBuilderWithScope.enumValueOf(enumClass: IrClass, value: IrExpression): IrExpression {
val loweredEnum = this@EnumSyntheticFunctionsBuilder.context.specialDeclarationsFactory.getLoweredEnum(enumClass) val loweredEnum = this@EnumSyntheticFunctionsBuilder.context.enumsSupport.getLoweredEnum(enumClass)
return irCall(genericValueOfSymbol, listOf(enumClass.defaultType)).apply { return irCall(genericValueOfSymbol, listOf(enumClass.defaultType)).apply {
putValueArgument(0, value) putValueArgument(0, value)
putValueArgument(1, loweredEnum.getValuesField(startOffset, endOffset)) putValueArgument(1, loweredEnum.getValuesField(startOffset, endOffset))
@@ -56,7 +56,7 @@ private class EnumSyntheticFunctionsBuilder(val context: Context) {
internal class NativeEnumWhenLowering constructor(context: Context) : EnumWhenLowering(context) { internal class NativeEnumWhenLowering constructor(context: Context) : EnumWhenLowering(context) {
override fun mapConstEnumEntry(entry: IrEnumEntry): Int { override fun mapConstEnumEntry(entry: IrEnumEntry): Int {
val parent = entry.parentAsClass val parent = entry.parentAsClass
val loweredEnum = (context as Context).specialDeclarationsFactory.getLoweredEnumOrNull(parent) val loweredEnum = (context as Context).enumsSupport.getLoweredEnumOrNull(parent)
?: return super.mapConstEnumEntry(entry) ?: return super.mapConstEnumEntry(entry)
return loweredEnum.entriesMap[entry.name]!!.ordinal return loweredEnum.entriesMap[entry.name]!!.ordinal
} }
@@ -109,7 +109,7 @@ 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.enumsSupport.getLoweredEnum(enumClass)
val getterId = loweredEnum.entriesMap.getValue(name).getterId 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)
@@ -132,7 +132,7 @@ internal class EnumClassLowering(val context: Context) : FileLoweringPass {
} }
private inner class EnumClassTransformer(val irClass: IrClass) { private inner class EnumClassTransformer(val irClass: IrClass) {
private val loweredEnum = context.specialDeclarationsFactory.getInternalLoweredEnum(irClass) private val loweredEnum = context.enumsSupport.getInternalLoweredEnum(irClass)
private val enumSyntheticFunctionsBuilder = EnumSyntheticFunctionsBuilder(context) private val enumSyntheticFunctionsBuilder = EnumSyntheticFunctionsBuilder(context)
fun run() { fun run() {
@@ -229,7 +229,7 @@ internal class EnumConstructorsLowering(val context: Context) : ClassLoweringPas
override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression { override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression {
val name = enumEntry.name.asString() val name = enumEntry.name.asString()
val ordinal = context.specialDeclarationsFactory.getEnumEntryOrdinal(enumEntry) val ordinal = context.enumsSupport.getEnumEntryOrdinal(enumEntry)
val startOffset = enumConstructorCall.startOffset val startOffset = enumConstructorCall.startOffset
val endOffset = enumConstructorCall.endOffset val endOffset = enumConstructorCall.endOffset