[K/N][codegen] Build trampolines for abstract fake overrides

#KT-61924 Fixed
This commit is contained in:
Igor Chevdar
2023-09-13 20:30:53 +03:00
committed by Space Team
parent 1df93e1611
commit 2b8bcfda94
2 changed files with 12 additions and 11 deletions
@@ -202,16 +202,6 @@ private inline fun <T : FunctionGenerationContext> generateFunctionBody(
functionGenerationContext.resetDebugLocation()
}
private fun IrSimpleFunction.findOverriddenMethodOfAny(): IrSimpleFunction? {
if (modality == Modality.ABSTRACT) return null
val resolved = resolveFakeOverride()!!
if ((resolved.parent as IrClass).isAny()) {
return resolved
}
return null
}
internal object VirtualTablesLookup {
private fun FunctionGenerationContext.getInterfaceTableRecord(typeInfo: LLVMValueRef, interfaceId: Int): LLVMValueRef {
val interfaceTableSize = load(structGep(typeInfo, 9 /* interfaceTableSize_ */))
@@ -307,6 +297,9 @@ internal object VirtualTablesLookup {
}
}
internal fun IrSimpleFunction.findOverriddenMethodOfAny() =
resolveFakeOverride(allowAbstract = false).takeIf { it?.parentClassOrNull?.isAny() == true }
/*
* Special trampoline function to call actual virtual implementation. This helps with reducing
* dependence between klibs/files (if vtable/itable of some class has changed, the call sites
@@ -317,8 +310,10 @@ internal fun CodeGenerator.getVirtualFunctionTrampoline(irFunction: IrSimpleFunc
* Resolve owner of the call with special handling of Any methods:
* if toString/eq/hc is invoked on an interface instance, we resolve
* owner as Any and dispatch it via vtable.
* Note: Keep on par with DFG builder.
*/
val anyMethod = irFunction.findOverriddenMethodOfAny()
return getVirtualFunctionTrampolineImpl(anyMethod ?: irFunction)
}
@@ -769,7 +769,13 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
}
else -> {
val callee = value.symbol.owner
/*
* Resolve owner of the call with special handling of Any methods:
* if toString/eq/hc is invoked on an interface instance, we resolve
* owner as Any and dispatch it via vtable.
* Note: Keep on par with the codegen.
*/
val callee = value.symbol.owner.let { it.findOverriddenMethodOfAny() ?: it }
val arguments = value.getArgumentsWithIr()
.map { expressionToEdge(it.second) }