[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
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
import llvm.*
|
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.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanIr
|
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.*
|
||||||
|
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.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.DevirtualizationAnalysis
|
||||||
import org.jetbrains.kotlin.backend.konan.optimizations.ExternalModulesDFG
|
import org.jetbrains.kotlin.backend.konan.optimizations.ExternalModulesDFG
|
||||||
import org.jetbrains.kotlin.backend.konan.optimizations.ModuleDFG
|
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.KonanIrLinker
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.SerializedClassFields
|
import org.jetbrains.kotlin.backend.konan.serialization.SerializedClassFields
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.SerializedInlineFunctionReference
|
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.declarations.lazy.IrLazyClass
|
||||||
import org.jetbrains.kotlin.ir.deepCopyWithVariables
|
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.symbols.impl.IrFieldSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.name.FqName
|
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.Architecture
|
||||||
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.library.SerializedIrModule
|
import org.jetbrains.kotlin.library.SerializedIrModule
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
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)
|
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) {
|
internal class SpecialDeclarationsFactory(val context: Context) {
|
||||||
private val enumSpecialDeclarationsFactory by lazy { EnumSpecialDeclarationsFactory(context) }
|
private val enumSpecialDeclarationsFactory by lazy { EnumSpecialDeclarationsFactory(context) }
|
||||||
private val outerThisFields = mutableMapOf<IrClass, IrField>()
|
|
||||||
private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
|
private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
|
||||||
private val externalLoweredEnums = mutableMapOf<IrClass, ExternalLoweredEnum>()
|
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? {
|
fun getLoweredEnumOrNull(enumClass: IrClass): LoweredEnumAccess? {
|
||||||
assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" }
|
assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" }
|
||||||
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
|
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
|
||||||
@@ -245,6 +204,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val specialDeclarationsFactory = SpecialDeclarationsFactory(this)
|
val specialDeclarationsFactory = SpecialDeclarationsFactory(this)
|
||||||
|
val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) }
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ internal abstract class KonanBackendContext(val config: KonanConfig) : CommonBac
|
|||||||
|
|
||||||
override val internalPackageFqn = KonanFqNames.internalPackageName
|
override val internalPackageFqn = KonanFqNames.internalPackageName
|
||||||
|
|
||||||
override val mapping: Mapping = DefaultMapping()
|
override val mapping: NativeMapping = NativeMapping()
|
||||||
|
|
||||||
override val irFactory: IrFactory = IrFactoryImpl
|
override val irFactory: IrFactory = IrFactoryImpl
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -421,7 +421,7 @@ internal val exportInternalAbiPhase = makeKonanModuleOpPhase(
|
|||||||
function.body = irBlockBody {
|
function.body = irBlockBody {
|
||||||
+irReturn(irGetField(
|
+irReturn(irGetField(
|
||||||
irGet(function.valueParameters[0]),
|
irGet(function.valueParameters[0]),
|
||||||
context.specialDeclarationsFactory.getOuterThisField(declaration))
|
context.innerClassesSupport.getOuterThisField(declaration))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,7 +507,7 @@ internal val useInternalAbiPhase = makeKonanModuleOpPhase(
|
|||||||
return when {
|
return when {
|
||||||
context.llvmModuleSpecification.containsDeclaration(field) -> expression
|
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) {
|
val accessor = outerThisAccessors.getOrPut(irClass) {
|
||||||
context.irFactory.buildFun {
|
context.irFactory.buildFun {
|
||||||
name = InternalAbi.getInnerClassOuterThisAccessorName(irClass)
|
name = InternalAbi.getInnerClassOuterThisAccessorName(irClass)
|
||||||
|
|||||||
+1
-1
@@ -466,7 +466,7 @@ internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context) {
|
|||||||
*/
|
*/
|
||||||
fun getDeclaredFields(): List<FieldInfo> {
|
fun getDeclaredFields(): List<FieldInfo> {
|
||||||
val outerThisField = if (irClass.isInner)
|
val outerThisField = if (irClass.isInner)
|
||||||
context.specialDeclarationsFactory.getOuterThisField(irClass)
|
context.innerClassesSupport.getOuterThisField(irClass)
|
||||||
else null
|
else null
|
||||||
val packageFragment = irClass.getPackageFragment()
|
val packageFragment = irClass.getPackageFragment()
|
||||||
if (packageFragment is IrExternalPackageFragment) {
|
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.ClassLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
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.common.lower.callsSuper
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
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.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
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.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
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 {
|
internal class OuterThisLowering(val context: Context) : ClassLoweringPass {
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
if (!irClass.isInner) return
|
if (!irClass.isInner) return
|
||||||
@@ -95,7 +125,7 @@ internal class OuterThisLowering(val context: Context) : ClassLoweringPass {
|
|||||||
return expression
|
return expression
|
||||||
}
|
}
|
||||||
|
|
||||||
val outerThisField = context.specialDeclarationsFactory.getOuterThisField(innerClass)
|
val outerThisField = context.innerClassesSupport.getOuterThisField(innerClass)
|
||||||
irThis = IrGetFieldImpl(
|
irThis = IrGetFieldImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
outerThisField.symbol, outerThisField.type,
|
outerThisField.symbol, outerThisField.type,
|
||||||
@@ -130,7 +160,7 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createOuterThisField() {
|
private fun createOuterThisField() {
|
||||||
val outerThisField = context.specialDeclarationsFactory.getOuterThisField(irClass)
|
val outerThisField = context.innerClassesSupport.getOuterThisField(irClass)
|
||||||
irClass.declarations += outerThisField
|
irClass.declarations += outerThisField
|
||||||
outerThisFieldSymbol = outerThisField.symbol
|
outerThisFieldSymbol = outerThisField.symbol
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -549,7 +549,7 @@ internal class KonanIrLinker(
|
|||||||
protoFieldsMap[name] = it
|
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
|
val compatibleMode = CompatibilityMode(libraryAbiVersion).oldSignatures
|
||||||
return SerializedClassFields(
|
return SerializedClassFields(
|
||||||
fileDeserializationState.fileIndex,
|
fileDeserializationState.fileIndex,
|
||||||
|
|||||||
Reference in New Issue
Block a user