[K/N][IR] Refactored outer this field creation
This commit is contained in:
+32
-72
@@ -6,56 +6,56 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.common.DefaultDelegateFactory
|
||||
import org.jetbrains.kotlin.backend.common.DefaultMapping
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanIr
|
||||
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
|
||||
import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD
|
||||
import org.jetbrains.kotlin.backend.konan.lower.InnerClassesSupport
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.DevirtualizationAnalysis
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.ExternalModulesDFG
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.ModuleDFG
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
import java.lang.System.out
|
||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
import kotlin.reflect.KProperty
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.SerializedClassFields
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.SerializedInlineFunctionReference
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
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.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
||||
import org.jetbrains.kotlin.konan.target.Architecture
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.library.SerializedIrModule
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
||||
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import java.lang.System.out
|
||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
internal class NativeMapping : DefaultMapping() {
|
||||
val outerThisFields = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrClass, IrField>()
|
||||
}
|
||||
|
||||
internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile: IrFile, val startOffset: Int, val endOffset: Int)
|
||||
|
||||
@@ -65,7 +65,6 @@ internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile:
|
||||
|
||||
internal class SpecialDeclarationsFactory(val context: Context) {
|
||||
private val enumSpecialDeclarationsFactory by lazy { EnumSpecialDeclarationsFactory(context) }
|
||||
private val outerThisFields = mutableMapOf<IrClass, IrField>()
|
||||
private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
|
||||
private val externalLoweredEnums = mutableMapOf<IrClass, ExternalLoweredEnum>()
|
||||
|
||||
@@ -81,46 +80,6 @@ internal class SpecialDeclarationsFactory(val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
object DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS :
|
||||
IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
|
||||
|
||||
fun getOuterThisField(innerClass: IrClass): IrField {
|
||||
assert(innerClass.isInner) { "Class is not inner: ${innerClass.render()}" }
|
||||
return outerThisFields.getOrPut(innerClass) {
|
||||
val outerClass = innerClass.parent as? IrClass
|
||||
?: throw AssertionError("No containing class for inner class ${innerClass.descriptor}")
|
||||
|
||||
val receiver = ReceiverParameterDescriptorImpl(
|
||||
innerClass.descriptor,
|
||||
ImplicitClassReceiver(innerClass.descriptor, null),
|
||||
Annotations.EMPTY
|
||||
)
|
||||
val descriptor = PropertyDescriptorImpl.create(
|
||||
innerClass.descriptor, Annotations.EMPTY, Modality.FINAL,
|
||||
DescriptorVisibilities.PRIVATE, false, "this$0".synthesizedName, CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE, false, false, false, false, false, false
|
||||
).apply {
|
||||
this.setType(outerClass.descriptor.defaultType, emptyList(), receiver, null, emptyList())
|
||||
initialize(null, null)
|
||||
}
|
||||
|
||||
IrFieldImpl(
|
||||
startOffset = innerClass.startOffset,
|
||||
endOffset = innerClass.endOffset,
|
||||
origin = DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS,
|
||||
symbol = IrFieldSymbolImpl(descriptor),
|
||||
name = descriptor.name,
|
||||
type = outerClass.defaultType,
|
||||
visibility = descriptor.visibility,
|
||||
isFinal = !descriptor.isVar,
|
||||
isExternal = descriptor.isEffectivelyExternal(),
|
||||
isStatic = descriptor.dispatchReceiverParameter == null
|
||||
).apply {
|
||||
parent = innerClass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getLoweredEnumOrNull(enumClass: IrClass): LoweredEnumAccess? {
|
||||
assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" }
|
||||
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
|
||||
@@ -245,6 +204,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
}
|
||||
|
||||
val specialDeclarationsFactory = SpecialDeclarationsFactory(this)
|
||||
val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) }
|
||||
|
||||
open class LazyMember<T>(val initializer: Context.() -> T) {
|
||||
operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this)
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ internal abstract class KonanBackendContext(val config: KonanConfig) : CommonBac
|
||||
|
||||
override val internalPackageFqn = KonanFqNames.internalPackageName
|
||||
|
||||
override val mapping: Mapping = DefaultMapping()
|
||||
override val mapping: NativeMapping = NativeMapping()
|
||||
|
||||
override val irFactory: IrFactory = IrFactoryImpl
|
||||
}
|
||||
|
||||
+2
-2
@@ -421,7 +421,7 @@ internal val exportInternalAbiPhase = makeKonanModuleOpPhase(
|
||||
function.body = irBlockBody {
|
||||
+irReturn(irGetField(
|
||||
irGet(function.valueParameters[0]),
|
||||
context.specialDeclarationsFactory.getOuterThisField(declaration))
|
||||
context.innerClassesSupport.getOuterThisField(declaration))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -507,7 +507,7 @@ internal val useInternalAbiPhase = makeKonanModuleOpPhase(
|
||||
return when {
|
||||
context.llvmModuleSpecification.containsDeclaration(field) -> expression
|
||||
|
||||
irClass?.isInner == true && context.specialDeclarationsFactory.getOuterThisField(irClass) == field -> {
|
||||
irClass?.isInner == true && context.innerClassesSupport.getOuterThisField(irClass) == field -> {
|
||||
val accessor = outerThisAccessors.getOrPut(irClass) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getInnerClassOuterThisAccessorName(irClass)
|
||||
|
||||
+1
-1
@@ -466,7 +466,7 @@ internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context) {
|
||||
*/
|
||||
fun getDeclaredFields(): List<FieldInfo> {
|
||||
val outerThisField = if (irClass.isInner)
|
||||
context.specialDeclarationsFactory.getOuterThisField(irClass)
|
||||
context.innerClassesSupport.getOuterThisField(irClass)
|
||||
else null
|
||||
val packageFragment = irClass.getPackageFragment()
|
||||
if (packageFragment is IrExternalPackageFragment) {
|
||||
|
||||
+32
-2
@@ -7,9 +7,14 @@ package org.jetbrains.kotlin.backend.konan.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.getOrPut
|
||||
import org.jetbrains.kotlin.backend.common.lower.callsSuper
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.NativeMapping
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
@@ -24,6 +29,31 @@ import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
internal class InnerClassesSupport(mapping: NativeMapping, private val irFactory: IrFactory) {
|
||||
private val outerThisFields = mapping.outerThisFields
|
||||
|
||||
fun getOuterThisField(innerClass: IrClass): IrField {
|
||||
require(innerClass.isInner) { "Expected an inner class: ${innerClass.render()}" }
|
||||
return outerThisFields.getOrPut(innerClass) {
|
||||
val outerClass = innerClass.parentClassOrNull ?: error("No containing class for inner class ${innerClass.render()}")
|
||||
|
||||
irFactory.buildField {
|
||||
startOffset = innerClass.startOffset
|
||||
endOffset = innerClass.endOffset
|
||||
origin = IrDeclarationOrigin.FIELD_FOR_OUTER_THIS
|
||||
name = "this$0".synthesizedName // TODO: other backends have "$this" here.
|
||||
type = outerClass.defaultType
|
||||
visibility = DescriptorVisibilities.PROTECTED
|
||||
isFinal = true
|
||||
isExternal = false
|
||||
isStatic = false
|
||||
}.also {
|
||||
it.parent = innerClass
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class OuterThisLowering(val context: Context) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (!irClass.isInner) return
|
||||
@@ -95,7 +125,7 @@ internal class OuterThisLowering(val context: Context) : ClassLoweringPass {
|
||||
return expression
|
||||
}
|
||||
|
||||
val outerThisField = context.specialDeclarationsFactory.getOuterThisField(innerClass)
|
||||
val outerThisField = context.innerClassesSupport.getOuterThisField(innerClass)
|
||||
irThis = IrGetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
outerThisField.symbol, outerThisField.type,
|
||||
@@ -130,7 +160,7 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
|
||||
}
|
||||
|
||||
private fun createOuterThisField() {
|
||||
val outerThisField = context.specialDeclarationsFactory.getOuterThisField(irClass)
|
||||
val outerThisField = context.innerClassesSupport.getOuterThisField(irClass)
|
||||
irClass.declarations += outerThisField
|
||||
outerThisFieldSymbol = outerThisField.symbol
|
||||
}
|
||||
|
||||
+1
-1
@@ -549,7 +549,7 @@ internal class KonanIrLinker(
|
||||
protoFieldsMap[name] = it
|
||||
}
|
||||
|
||||
val outerThisIndex = fields.indexOfFirst { it.irField?.origin == SpecialDeclarationsFactory.DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS }
|
||||
val outerThisIndex = fields.indexOfFirst { it.irField?.origin == IrDeclarationOrigin.FIELD_FOR_OUTER_THIS }
|
||||
val compatibleMode = CompatibilityMode(libraryAbiVersion).oldSignatures
|
||||
return SerializedClassFields(
|
||||
fileDeserializationState.fileIndex,
|
||||
|
||||
Reference in New Issue
Block a user