Native: fix @ExportObjCClass with the new memory manager
Previous implementation of `@ExportObjCClass` relied on the fact that initialization of top-level fields was eager, i.e. happened during Kotlin runtime initialization, when Kotlin code is accesses for the first time. With the new MM, initialization of top-level fields became lazy, it happens when the particular file is accessed for the first time. This commit fixes `@ExportObjCClass` with the new MM by making the initialization of particular top-level fields eager. ^KT-53373 Fixed
This commit is contained in:
committed by
Space
parent
70da19bd22
commit
ce6c8a51ba
+4
-4
@@ -127,7 +127,7 @@ private class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfor
|
||||
|
||||
lateinit var currentFile: IrFile
|
||||
|
||||
private val topLevelInitializers = mutableListOf<IrExpression>()
|
||||
private val eagerTopLevelInitializers = mutableListOf<IrExpression>()
|
||||
private val newTopLevelDeclarations = mutableListOf<IrDeclaration>()
|
||||
|
||||
override val irFile: IrFile
|
||||
@@ -142,8 +142,8 @@ private class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfor
|
||||
currentFile = irFile
|
||||
irFile.transformChildrenVoid(this)
|
||||
|
||||
topLevelInitializers.forEach { irFile.addTopLevelInitializer(it, context, false) }
|
||||
topLevelInitializers.clear()
|
||||
eagerTopLevelInitializers.forEach { irFile.addTopLevelInitializer(it, context, threadLocal = false, eager = true) }
|
||||
eagerTopLevelInitializers.clear()
|
||||
|
||||
irFile.addChildren(newTopLevelDeclarations)
|
||||
newTopLevelDeclarations.clear()
|
||||
@@ -191,7 +191,7 @@ private class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfor
|
||||
|
||||
if (irClass.annotations.hasAnnotation(interop.exportObjCClass.fqNameSafe)) {
|
||||
val irBuilder = context.createIrBuilder(currentFile.symbol).at(irClass)
|
||||
topLevelInitializers.add(irBuilder.getObjCClass(symbols, irClass.symbol))
|
||||
eagerTopLevelInitializers.add(irBuilder.getObjCClass(symbols, irClass.symbol))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -62,7 +62,7 @@ internal fun irBuilder(
|
||||
|
||||
private var topLevelInitializersCounter = 0
|
||||
|
||||
internal fun IrFile.addTopLevelInitializer(expression: IrExpression, context: KonanBackendContext, threadLocal: Boolean) {
|
||||
internal fun IrFile.addTopLevelInitializer(expression: IrExpression, context: KonanBackendContext, threadLocal: Boolean, eager: Boolean) {
|
||||
val irField = IrFieldImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
@@ -79,6 +79,9 @@ internal fun IrFile.addTopLevelInitializer(expression: IrExpression, context: Ko
|
||||
if (threadLocal)
|
||||
annotations += buildSimpleAnnotation(context.irBuiltIns, startOffset, endOffset, context.ir.symbols.threadLocal.owner)
|
||||
|
||||
if (eager)
|
||||
annotations += buildSimpleAnnotation(context.irBuiltIns, startOffset, endOffset, context.ir.symbols.eagerInitialization.owner)
|
||||
|
||||
initializer = IrExpressionBodyImpl(startOffset, endOffset, expression)
|
||||
}
|
||||
addChild(irField)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
language = Objective-C
|
||||
headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h Foundation/NSStream.h Foundation/NSBundle.h
|
||||
headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h Foundation/NSStream.h Foundation/NSBundle.h \
|
||||
objc/runtime.h
|
||||
headerFilter = **/interop/objc/tests/**.h \
|
||||
Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h Foundation/NSStream.h \
|
||||
objc/objc.h Foundation/NSBundle.h
|
||||
objc/objc.h Foundation/NSBundle.h \
|
||||
objc/runtime.h
|
||||
linkerOpts = -lobjctests
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import objcTests.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
@ExportObjCClass
|
||||
class KT53373 : NSObject()
|
||||
@@ -0,0 +1,10 @@
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import objcTests.*
|
||||
|
||||
@Test
|
||||
fun testKT53373() {
|
||||
val kt53373Class = objc_lookUpClass("KT53373")
|
||||
assertNotNull(kt53373Class)
|
||||
assertEquals("KT53373", class_getName(kt53373Class)?.toKString())
|
||||
}
|
||||
Reference in New Issue
Block a user