Fix missing "outer this" field in cached super inner classes

#KT-39153 Fixed
This commit is contained in:
SvyatoslavScherbina
2020-06-05 14:43:43 +03:00
committed by GitHub
parent da5ac1ff70
commit 40602d47ec
4 changed files with 32 additions and 9 deletions
@@ -254,7 +254,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
val layoutBuilders = mutableMapOf<IrClass, ClassLayoutBuilder>()
fun getLayoutBuilder(irClass: IrClass) = layoutBuilders.getOrPut(irClass) {
ClassLayoutBuilder(irClass, this)
ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass))
}
lateinit var globalHierarchyAnalysisResult: GlobalHierarchyAnalysisResult
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.symbols.IrSymbol
@@ -256,7 +257,10 @@ internal val psiToIrPhase = konanUnitPhase(
linker.modules.values.forEach{ fakeOverrideChecker.check(it) }
irModule = module
// Note: coupled with [shouldLower] below.
irModules = linker.modules.filterValues { llvmModuleSpecification.containsModule(it) }
ir.symbols = symbols
functionIrClassFactory.module =
@@ -268,6 +272,11 @@ internal val psiToIrPhase = konanUnitPhase(
prerequisite = setOf(createSymbolTablePhase)
)
// Coupled with [psiToIrPhase] logic above.
internal fun shouldLower(context: Context, declaration: IrDeclaration): Boolean {
return context.llvmModuleSpecification.containsDeclaration(declaration)
}
internal val destroySymbolTablePhase = konanUnitPhase(
op = {
this.symbolTable = null // TODO: invalidate symbolTable itself.
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.backend.konan.llvm.functionName
import org.jetbrains.kotlin.backend.konan.llvm.llvmType
import org.jetbrains.kotlin.backend.konan.llvm.localHash
import org.jetbrains.kotlin.backend.konan.lower.InnerClassLowering
import org.jetbrains.kotlin.backend.konan.lower.bridgeTarget
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrElement
@@ -260,7 +261,7 @@ internal class GlobalHierarchyAnalysis(val context: Context, val irModule: IrMod
}
}
internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context) {
internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context, val isLowered: Boolean) {
private val DEBUG = 0
private inline fun DEBUG_OUTPUT(severity: Int, block: () -> Unit) {
@@ -432,7 +433,15 @@ internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context) {
* Fields declared in the class.
*/
private fun getDeclaredFields(): List<IrField> {
val fields = irClass.declarations.mapNotNull {
val declarations: List<IrDeclaration> = if (irClass.isInner && !isLowered) {
// Note: copying to avoid mutation of the original class.
irClass.declarations.toMutableList()
.also { InnerClassLowering.addOuterThisField(it, irClass, context) }
} else {
irClass.declarations
}
val fields = declarations.mapNotNull {
when (it) {
is IrField -> it.takeIf { it.isReal }
is IrProperty -> it.takeIf { it.isReal }?.backingField
@@ -9,9 +9,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.lower.callsSuper
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
@@ -20,7 +18,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.parentAsClass
@@ -32,6 +29,14 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
InnerClassTransformer(irClass).lowerInnerClass()
}
companion object {
fun addOuterThisField(declarations: MutableList<IrDeclaration>, irClass: IrClass, context: Context): IrField {
val outerThisField = context.specialDeclarationsFactory.getOuterThisField(irClass)
declarations += outerThisField
return outerThisField
}
}
private inner class InnerClassTransformer(val irClass: IrClass) {
lateinit var outerThisFieldSymbol: IrFieldSymbol
@@ -44,8 +49,8 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
}
private fun createOuterThisField() {
irClass.declarations += context.specialDeclarationsFactory.getOuterThisField(irClass)
outerThisFieldSymbol = context.specialDeclarationsFactory.getOuterThisField(irClass).symbol
val outerThisField = addOuterThisField(irClass.declarations, irClass, context)
outerThisFieldSymbol = outerThisField.symbol
}
private fun lowerConstructors() {