Skip to content

Commit

Permalink
Fix missing "outer this" field in cached super inner classes
Browse files Browse the repository at this point in the history
#KT-39153 Fixed
  • Loading branch information
SvyatoslavScherbina authored Jun 5, 2020
1 parent da5ac1f commit 40602d4
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 =
Expand All @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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() {
Expand Down

0 comments on commit 40602d4

Please sign in to comment.