Fix using cached Kotlin subclasses of Objective-C classes (#3990)
This commit is contained in:
committed by
GitHub
parent
5b9beec860
commit
fe3057a40b
+9
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract
|
||||
import org.jetbrains.kotlin.backend.konan.ir.allParameters
|
||||
import org.jetbrains.kotlin.backend.konan.ir.isUnit
|
||||
import org.jetbrains.kotlin.backend.konan.isExternalObjCClass
|
||||
import org.jetbrains.kotlin.backend.konan.isKotlinObjCClass
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.AbstractKonanIrMangler
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.findAnnotation
|
||||
@@ -93,6 +94,14 @@ internal val IrClass.objectInstanceGetterSymbolName: String
|
||||
return "kobjget:$fqNameForIrSerialization"
|
||||
}
|
||||
|
||||
internal val IrClass.kotlinObjCClassInfoSymbolName: String
|
||||
get() {
|
||||
assert (this.isExported())
|
||||
assert (this.isKotlinObjCClass())
|
||||
|
||||
return "kobjcclassinfo:$fqNameForIrSerialization"
|
||||
}
|
||||
|
||||
val IrFunction.functionName get() = with(KonanBinaryInterface) { functionName }
|
||||
|
||||
val IrFunction.symbolName get() = with(KonanBinaryInterface) { symbolName }
|
||||
|
||||
+4
-7
@@ -1005,22 +1005,19 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
error("type-checking against Kotlin classes inheriting Objective-C meta-classes isn't supported yet")
|
||||
}
|
||||
|
||||
val objCDeclarations = context.llvmDeclarations.forClass(irClass).objCDeclarations!!
|
||||
val classPointerGlobal = objCDeclarations.classPointerGlobal.llvmGlobal
|
||||
val classInfo = codegen.kotlinObjCClassInfo(irClass)
|
||||
val classPointerGlobal = load(structGep(classInfo, 12 /* createdClass */))
|
||||
|
||||
val storedClass = this.load(classPointerGlobal)
|
||||
|
||||
val storedClassIsNotNull = this.icmpNe(storedClass, kNullInt8Ptr)
|
||||
|
||||
return this.ifThenElse(storedClassIsNotNull, storedClass) {
|
||||
val newClass = call(
|
||||
call(
|
||||
context.llvm.createKotlinObjCClass,
|
||||
listOf(objCDeclarations.classInfoGlobal.llvmGlobal),
|
||||
listOf(classInfo),
|
||||
exceptionHandler = exceptionHandler
|
||||
)
|
||||
|
||||
this.store(newClass, classPointerGlobal)
|
||||
newClass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-2
@@ -66,12 +66,14 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con
|
||||
irClass.typeInfoPtr,
|
||||
companionObject?.typeInfoPtr ?: NullPointer(runtime.typeInfoType),
|
||||
|
||||
objCLLvmDeclarations.classPointerGlobal.pointer
|
||||
staticData.placeGlobal(
|
||||
"kobjcclassptr:${irClass.fqNameForIrSerialization}#internal",
|
||||
NullPointer(int8Type)
|
||||
).pointer
|
||||
)
|
||||
|
||||
objCLLvmDeclarations.classInfoGlobal.setInitializer(info)
|
||||
|
||||
objCLLvmDeclarations.classPointerGlobal.setInitializer(NullPointer(int8Type))
|
||||
objCLLvmDeclarations.bodyOffsetGlobal.setInitializer(Int32(0))
|
||||
}
|
||||
|
||||
@@ -132,4 +134,17 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con
|
||||
it.llvmFunction
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun CodeGenerator.kotlinObjCClassInfo(irClass: IrClass): LLVMValueRef {
|
||||
require(irClass.isKotlinObjCClass())
|
||||
return if (isExternal(irClass)) {
|
||||
importGlobal(
|
||||
irClass.kotlinObjCClassInfoSymbolName,
|
||||
runtime.kotlinObjCClassInfo,
|
||||
origin = irClass.llvmSymbolOrigin
|
||||
)
|
||||
} else {
|
||||
context.llvmDeclarations.forClass(irClass).objCDeclarations!!.classInfoGlobal.llvmGlobal
|
||||
}
|
||||
}
|
||||
+9
-5
@@ -70,7 +70,6 @@ internal class ClassLlvmDeclarations(
|
||||
internal class SingletonLlvmDeclarations(val instanceStorage: AddressAccess, val instanceShadowStorage: AddressAccess?)
|
||||
|
||||
internal class KotlinObjCClassLlvmDeclarations(
|
||||
val classPointerGlobal: StaticData.Global,
|
||||
val classInfoGlobal: StaticData.Global,
|
||||
val bodyOffsetGlobal: StaticData.Global
|
||||
)
|
||||
@@ -290,18 +289,23 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
private fun createKotlinObjCClassDeclarations(irClass: IrClass): KotlinObjCClassLlvmDeclarations {
|
||||
val internalName = qualifyInternalName(irClass)
|
||||
|
||||
val classPointerGlobal = staticData.createGlobal(int8TypePtr, "kobjcclassptr:$internalName")
|
||||
|
||||
val isExported = irClass.isExported()
|
||||
val classInfoSymbolName = if (isExported) {
|
||||
irClass.kotlinObjCClassInfoSymbolName
|
||||
} else {
|
||||
"kobjcclassinfo:$internalName"
|
||||
}
|
||||
val classInfoGlobal = staticData.createGlobal(
|
||||
context.llvm.runtime.kotlinObjCClassInfo,
|
||||
"kobjcclassinfo:$internalName"
|
||||
classInfoSymbolName,
|
||||
isExported = isExported
|
||||
).apply {
|
||||
setConstant(true)
|
||||
}
|
||||
|
||||
val bodyOffsetGlobal = staticData.createGlobal(int32Type, "kobjcbodyoffs:$internalName")
|
||||
|
||||
return KotlinObjCClassLlvmDeclarations(classPointerGlobal, classInfoGlobal, bodyOffsetGlobal)
|
||||
return KotlinObjCClassLlvmDeclarations(classInfoGlobal, bodyOffsetGlobal)
|
||||
}
|
||||
|
||||
override fun visitField(declaration: IrField) {
|
||||
|
||||
Reference in New Issue
Block a user