diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt index 5a12fa3a266..92a9536428a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.llvm.functionName import org.jetbrains.kotlin.backend.konan.llvm.localHash +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.util.simpleFunctions @@ -49,15 +50,19 @@ internal class OverriddenFunctionDescriptor( && descriptor.target.overrides(overriddenDescriptor) && descriptor.bridgeDirectionsTo(overriddenDescriptor).allNotNeeded() - fun getImplementation(context: Context): SimpleFunctionDescriptor { + fun getImplementation(context: Context): SimpleFunctionDescriptor? { val target = descriptor.target - if (!needBridge) return target - val bridgeOwner = if (inheritsBridge) { - target // Bridge is inherited from superclass. - } else { - descriptor + val implementation = if (!needBridge) + target + else { + val bridgeOwner = if (inheritsBridge) { + target // Bridge is inherited from superclass. + } else { + descriptor + } + context.specialDeclarationsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(bridgeOwner, overriddenDescriptor)) } - return context.specialDeclarationsFactory.getBridgeDescriptor(OverriddenFunctionDescriptor(bridgeOwner, overriddenDescriptor)) + return if (implementation.modality == Modality.ABSTRACT) null else implementation } override fun toString(): String { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt index e7ba5d03531..157cdbf1588 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt @@ -200,7 +200,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { // TODO: compile-time resolution limits binary compatibility val vtableEntries = context.getVtableBuilder(classDesc).vtableEntries.map { val implementation = it.implementation - if (implementation.isExternalObjCClassMethod() || implementation.modality == Modality.ABSTRACT) { + if (implementation == null || implementation.isExternalObjCClassMethod()) { NullPointer(int8Type) } else { implementation.entryPointAddress @@ -220,11 +220,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { // TODO: compile-time resolution limits binary compatibility val implementation = it.implementation - val methodEntryPoint = if (implementation.modality == Modality.ABSTRACT) { - null - } else { - implementation.entryPointAddress - } + val methodEntryPoint = implementation?.entryPointAddress MethodTableRecord(nameSignature, methodEntryPoint) }.sortedBy { it.nameSignature.value } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt index f15b78be7a2..174db9d0eaa 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt @@ -1178,9 +1178,11 @@ internal object DFGSerializer { allTypes.forEach { println(it) println(" SUPER TYPES:") - it.superTypes.forEach { - println(" $it") - } + it.superTypes.forEach { println(" $it") } + println(" VTABLE:") + it.vtable.forEach { println(" $it") } + println(" ITABLE:") + it.itable.forEach { t, u -> println(" $t: $u") } } functions.forEach { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt index 86fb5380ab9..f16b7fdabee 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt @@ -483,16 +483,11 @@ internal object DataFlowIR { Type.Public(name.localHash.value, isFinal, isAbstract, module, symbolTableIndex, takeName { name }) else Type.Private(privateTypeIndex++, isFinal, isAbstract, module, symbolTableIndex, takeName { name }) - if (!descriptor.isInterface) { + if (!isAbstract) { val vtableBuilder = context.getVtableBuilder(descriptor) - type.vtable += vtableBuilder.vtableEntries.map { mapFunction(it.getImplementation(context)) } - if (!isAbstract) { - vtableBuilder.methodTableEntries.forEach { - type.itable.put( - it.overriddenDescriptor.functionName.localHash.value, - mapFunction(it.getImplementation(context)) - ) - } + type.vtable += vtableBuilder.vtableEntries.map { mapFunction(it.getImplementation(context)!!) } + vtableBuilder.methodTableEntries.forEach { + type.itable[it.overriddenDescriptor.functionName.localHash.value] = mapFunction(it.getImplementation(context)!!) } } classMap.put(descriptor, type)