[RTTI][Objective-C] Omit RTTI for external Obj-C classes
This commit is contained in:
committed by
Sergey Bogolepov
parent
7b73595aca
commit
d250058943
+17
@@ -15,3 +15,20 @@ internal fun IrClass.isNonGeneratedAnnotation(): Boolean =
|
||||
!this.annotations.hasAnnotation(serialInfoAnnotationFqName)
|
||||
|
||||
private val serialInfoAnnotationFqName = FqName("kotlinx.serialization.SerialInfo")
|
||||
|
||||
/**
|
||||
* We don't need to generate RTTI in some cases, e.g. Objective-C external classes.
|
||||
*/
|
||||
internal fun IrClass.requiresRtti(): Boolean = when {
|
||||
// TODO: Support more cases
|
||||
// Sadly, we still need to emit RTTI for Kotlin inheritors of Obj-C classes.
|
||||
// The reason for it is that we need to know a layout of the object to correctly
|
||||
// deinitialize it.
|
||||
this.isExternalObjCClass() -> false
|
||||
else -> true
|
||||
}
|
||||
|
||||
internal fun IrClass.requiresCodeGeneration(): Boolean =
|
||||
// For now these two sets (classes that require RTTI and classes that require codegen)
|
||||
// are the same, but they might diverge later.
|
||||
requiresRtti()
|
||||
+5
-4
@@ -97,9 +97,9 @@ internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid {
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
super.visitClass(declaration)
|
||||
|
||||
generator.generate(declaration)
|
||||
|
||||
if (declaration.requiresRtti()) {
|
||||
generator.generate(declaration)
|
||||
}
|
||||
if (declaration.isKotlinObjCClass()) {
|
||||
kotlinObjCClassInfoGenerator.generate(declaration)
|
||||
}
|
||||
@@ -772,7 +772,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
context.log{"visitClass : ${ir2string(declaration)}"}
|
||||
if (declaration.isNonGeneratedAnnotation()) {
|
||||
|
||||
if (declaration.isNonGeneratedAnnotation() || !declaration.requiresCodeGeneration()) {
|
||||
// For non-generated annotation classes generate only nested classes.
|
||||
declaration.declarations
|
||||
.filterIsInstance<IrClass>()
|
||||
|
||||
+4
-2
@@ -157,8 +157,9 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
this.classes[declaration] = createClassDeclarations(declaration)
|
||||
|
||||
if (declaration.requiresRtti()) {
|
||||
this.classes[declaration] = createClassDeclarations(declaration)
|
||||
}
|
||||
super.visitClass(declaration)
|
||||
}
|
||||
|
||||
@@ -308,6 +309,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
|
||||
val containingClass = declaration.parent as? IrClass
|
||||
if (containingClass != null) {
|
||||
if (!containingClass.requiresRtti()) return
|
||||
val classDeclarations = this.classes[containingClass] ?:
|
||||
error(containingClass.descriptor.toString())
|
||||
val allFields = context.getLayoutBuilder(containingClass).fields
|
||||
|
||||
+24
-11
@@ -185,6 +185,20 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
return LLVMStoreSizeOfType(llvmTargetData, classType).toInt()
|
||||
}
|
||||
|
||||
private fun getClassId(irClass: IrClass): Int {
|
||||
if (irClass.isKotlinObjCClass()) return 0
|
||||
val hierarchyInfo = if (context.ghaEnabled()) {
|
||||
context.getLayoutBuilder(irClass).hierarchyInfo
|
||||
} else {
|
||||
ClassGlobalHierarchyInfo.DUMMY
|
||||
}
|
||||
return if (irClass.isInterface) {
|
||||
hierarchyInfo.interfaceId
|
||||
} else {
|
||||
hierarchyInfo.classIdLo
|
||||
}
|
||||
}
|
||||
|
||||
fun generate(irClass: IrClass) {
|
||||
|
||||
val className = irClass.fqNameForIrSerialization
|
||||
@@ -195,11 +209,16 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
|
||||
val instanceSize = getInstanceSize(bodyType, className)
|
||||
|
||||
val superTypeOrAny = irClass.getSuperClassNotAny() ?: context.ir.symbols.any.owner
|
||||
val superType = if (irClass.isAny()) NullPointer(runtime.typeInfoType)
|
||||
else superTypeOrAny.typeInfoPtr
|
||||
val superType = when {
|
||||
irClass.isAny() -> NullPointer(runtime.typeInfoType)
|
||||
irClass.isKotlinObjCClass() -> context.ir.symbols.any.owner.typeInfoPtr
|
||||
else -> {
|
||||
val superTypeOrAny = irClass.getSuperClassNotAny() ?: context.ir.symbols.any.owner
|
||||
superTypeOrAny.typeInfoPtr
|
||||
}
|
||||
}
|
||||
|
||||
val implementedInterfaces = irClass.implementedInterfaces
|
||||
val implementedInterfaces = irClass.implementedInterfaces.filter { it.requiresRtti() }
|
||||
|
||||
val interfaces = implementedInterfaces.map { it.typeInfoPtr }
|
||||
val interfacesPtr = staticData.placeGlobalConstArray("kintf:$className",
|
||||
@@ -235,10 +254,6 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
|
||||
val reflectionInfo = getReflectionInfo(irClass)
|
||||
val typeInfoGlobal = llvmDeclarations.typeInfoGlobal
|
||||
val hierarchyInfo =
|
||||
if (context.ghaEnabled())
|
||||
context.getLayoutBuilder(irClass).hierarchyInfo
|
||||
else ClassGlobalHierarchyInfo.DUMMY
|
||||
val typeInfo = TypeInfo(
|
||||
irClass.typeInfoPtr,
|
||||
makeExtendedInfo(irClass),
|
||||
@@ -251,9 +266,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
reflectionInfo.packageName,
|
||||
reflectionInfo.relativeName,
|
||||
flagsFromClass(irClass),
|
||||
if (irClass.isInterface)
|
||||
hierarchyInfo.interfaceId
|
||||
else hierarchyInfo.classIdLo,
|
||||
getClassId(irClass),
|
||||
llvmDeclarations.writableTypeInfoGlobal?.pointer,
|
||||
associatedObjects = genAssociatedObjects(irClass)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user