backend: fix some bugs and improve RTTI
* fix incorrect assert at RTTIGenerator.kt:109 * add `final override` methods to methods table (aka openMethods) * fix NPE when building vtable with `final override` methods * make vtable generation impl more clear
This commit is contained in:
committed by
SvyatoslavScherbina
parent
db15540a74
commit
f147860fea
+11
-18
@@ -86,29 +86,24 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
|||||||
getVtableEntries(classDesc.getSuperClassOrAny())
|
getVtableEntries(classDesc.getSuperClassOrAny())
|
||||||
}
|
}
|
||||||
|
|
||||||
val inheritedVtableSlots = Array<FunctionDescriptor?>(superVtableEntries.size, { null })
|
val methods = classDesc.getContributedMethods() // TODO: ensure order is well-defined
|
||||||
val methods = getMethodTableEntries(classDesc) // TODO: ensure order is well-defined
|
|
||||||
val entriesForNewVtableSlots = methods.toMutableSet()
|
|
||||||
|
|
||||||
methods.forEach { method ->
|
val inheritedVtableSlots = superVtableEntries.map { superMethod ->
|
||||||
superVtableEntries.forEachIndexed { i, superMethod ->
|
methods.single { OverridingUtil.overrides(it, superMethod) }
|
||||||
if (OverridingUtil.overrides(method, superMethod)) {
|
|
||||||
assert (inheritedVtableSlots[i] == null)
|
|
||||||
inheritedVtableSlots[i] = method
|
|
||||||
|
|
||||||
assert (method in entriesForNewVtableSlots)
|
|
||||||
entriesForNewVtableSlots.remove(method)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return inheritedVtableSlots.map { it!! } + methods.filter { it in entriesForNewVtableSlots }
|
return inheritedVtableSlots + (methods - inheritedVtableSlots).filter { it.isOverridable }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMethodTableEntries(classDesc: ClassDescriptor): List<FunctionDescriptor> {
|
private fun getMethodTableEntries(classDesc: ClassDescriptor): List<FunctionDescriptor> {
|
||||||
assert (classDesc.modality != Modality.ABSTRACT)
|
assert (classDesc.modality != Modality.ABSTRACT)
|
||||||
|
|
||||||
val contributedDescriptors = classDesc.unsubstitutedMemberScope.getContributedDescriptors()
|
return classDesc.getContributedMethods().filter { it.isOverridableOrOverrides }
|
||||||
|
// TODO: probably method table should contain all accessible methods to improve binary compatibility
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ClassDescriptor.getContributedMethods(): List<FunctionDescriptor> {
|
||||||
|
val contributedDescriptors = unsubstitutedMemberScope.getContributedDescriptors()
|
||||||
// (includes declarations from supers)
|
// (includes declarations from supers)
|
||||||
|
|
||||||
val functions = contributedDescriptors.filterIsInstance<FunctionDescriptor>()
|
val functions = contributedDescriptors.filterIsInstance<FunctionDescriptor>()
|
||||||
@@ -118,9 +113,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
|||||||
val setters = properties.mapNotNull { it.setter }
|
val setters = properties.mapNotNull { it.setter }
|
||||||
|
|
||||||
val allMethods = functions + getters + setters
|
val allMethods = functions + getters + setters
|
||||||
|
return allMethods
|
||||||
// TODO: adding or removing 'open' modifier will break the binary compatibility
|
|
||||||
return allMethods.filter { it.modality != Modality.FINAL }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMOpaqueValue?) {
|
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMOpaqueValue?) {
|
||||||
|
|||||||
Reference in New Issue
Block a user