backend, runtime: improve support for abstract methods (#62)
backend, runtime: improve support for abstract methods Do not generate vtable and openMethods for abstract classes and interfaces
This commit is contained in:
committed by
GitHub
parent
c5cfa0ac4f
commit
755194486b
+2
-8
@@ -15,20 +15,14 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
var currentFunction:FunctionDescriptor? = null
|
||||
|
||||
fun function(declaration: IrFunction) {
|
||||
if (declaration.descriptor.isExternal) {
|
||||
if (declaration.body == null) {
|
||||
// Abstract and external methods.
|
||||
return
|
||||
}
|
||||
|
||||
if (currentFunction == declaration.descriptor) return
|
||||
val fn = prolog(declaration)
|
||||
|
||||
// TODO: functions without Kotlin body must not have a bitcode body,
|
||||
// which is required to workaround link errors
|
||||
if (declaration.body == null) {
|
||||
trap()
|
||||
return
|
||||
}
|
||||
|
||||
var indexOffset = 0
|
||||
if (declaration.descriptor is ClassConstructorDescriptor || declaration.descriptor.dispatchReceiverParameter != null) {
|
||||
val name = "this"
|
||||
|
||||
+20
-14
@@ -78,9 +78,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
|
||||
// TODO: optimize
|
||||
private fun getVtableEntries(classDesc: ClassDescriptor): List<FunctionDescriptor> {
|
||||
if (classDesc.isInterface) {
|
||||
return emptyList()
|
||||
}
|
||||
assert (!classDesc.isInterface)
|
||||
|
||||
val superVtableEntries = if (KotlinBuiltIns.isSpecialClassWithNoSupertypes(classDesc)) {
|
||||
emptyList()
|
||||
@@ -108,9 +106,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
}
|
||||
|
||||
private fun getMethodTableEntries(classDesc: ClassDescriptor): List<FunctionDescriptor> {
|
||||
if (classDesc.isInterface) {
|
||||
return emptyList()
|
||||
}
|
||||
assert (classDesc.modality != Modality.ABSTRACT)
|
||||
|
||||
val contributedDescriptors = classDesc.unsubstitutedMemberScope.getContributedDescriptors()
|
||||
// (includes declarations from supers)
|
||||
@@ -197,16 +193,26 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
val fieldsPtr = staticData.placeGlobalConstArray("kfields:$className",
|
||||
runtime.fieldTableRecordType, fields)
|
||||
|
||||
// TODO: compile-time resolution limits binary compatibility
|
||||
val vtable = getVtableEntries(classDesc).map { it.implementation.entryPointAddress }
|
||||
val vtablePtr = staticData.placeGlobalConstArray("kvtable:$className", pointerType(int8Type), vtable)
|
||||
val vtable: List<ConstValue>
|
||||
val methods: List<ConstValue>
|
||||
|
||||
val methods = getMethodTableEntries(classDesc).map {
|
||||
val nameSignature = it.functionName.localHash
|
||||
if (classDesc.modality != Modality.ABSTRACT) {
|
||||
// TODO: compile-time resolution limits binary compatibility
|
||||
val methodEntryPoint = it.implementation.entryPointAddress
|
||||
MethodTableRecord(nameSignature, methodEntryPoint)
|
||||
}.sortedBy { it.nameSignature.value }
|
||||
vtable = getVtableEntries(classDesc).map { it.implementation.entryPointAddress }
|
||||
|
||||
methods = getMethodTableEntries(classDesc).map {
|
||||
val nameSignature = it.functionName.localHash
|
||||
// TODO: compile-time resolution limits binary compatibility
|
||||
val methodEntryPoint = it.implementation.entryPointAddress
|
||||
MethodTableRecord(nameSignature, methodEntryPoint)
|
||||
}.sortedBy { it.nameSignature.value }
|
||||
} else {
|
||||
vtable = emptyList()
|
||||
methods = emptyList()
|
||||
}
|
||||
|
||||
|
||||
val vtablePtr = staticData.placeGlobalConstArray("kvtable:$className", pointerType(int8Type), vtable)
|
||||
|
||||
val methodsPtr = staticData.placeGlobalConstArray("kmethods:$className",
|
||||
runtime.methodTableRecordType, methods)
|
||||
|
||||
@@ -32,8 +32,10 @@ struct TypeInfo {
|
||||
int32_t objOffsetsCount_;
|
||||
const TypeInfo* const* implementedInterfaces_;
|
||||
int32_t implementedInterfacesCount_;
|
||||
// Null for abstract classes and interfaces.
|
||||
// TODO: place vtable at the end of TypeInfo to eliminate the indirection.
|
||||
void* const* vtable_;
|
||||
// Null for abstract classes and interfaces.
|
||||
const MethodTableRecord* openMethods_;
|
||||
uint32_t openMethodsCount_;
|
||||
const FieldTableRecord* fields_;
|
||||
|
||||
Reference in New Issue
Block a user