[Wasm] Allow virtual functions signature clash for PL support

This commit is contained in:
Igor Yakovlev
2024-03-06 23:09:57 +01:00
committed by Space Team
parent 8851ccc35d
commit ec1ade1293
2 changed files with 23 additions and 23 deletions
@@ -86,7 +86,8 @@ class VirtualMethodMetadata(
class ClassMetadata(
val klass: IrClass,
val superClass: ClassMetadata?,
irBuiltIns: IrBuiltIns
irBuiltIns: IrBuiltIns,
allowAccidentalOverride: Boolean,
) {
// List of all fields including fields of super classes
// In Wasm order
@@ -102,36 +103,34 @@ class ClassMetadata(
val virtualFunctions = klass.declarations
.asSequence()
.filterVirtualFunctions()
.mapTo(mutableListOf()) { VirtualMethodMetadata(it, it.wasmSignature(irBuiltIns)) }
val virtualFunctionsMetadata = mutableListOf<VirtualMethodMetadata>()
val visitedSignature = mutableSetOf<WasmSignature>()
for (function in virtualFunctions) {
val signature = function.wasmSignature(irBuiltIns)
if (!visitedSignature.add(signature)) {
if (allowAccidentalOverride) {
continue
} else {
val alreadyAdded = virtualFunctionsMetadata.first { it.signature == signature }
error("Class ${klass.fqNameWhenAvailable} has several methods with the same signature $signature\n$alreadyAdded\n$function")
}
}
virtualFunctionsMetadata.add(VirtualMethodMetadata(function, signature))
}
val superClassVirtualMethods = superClass?.virtualMethods
if (superClassVirtualMethods.isNullOrEmpty()) return@run virtualFunctions
if (superClassVirtualMethods.isNullOrEmpty()) return@run virtualFunctionsMetadata
val result = mutableListOf<VirtualMethodMetadata>()
val signatureToVirtualFunction = virtualFunctions.associateBy { it.signature }
val signatureToVirtualFunction = virtualFunctionsMetadata.associateBy { it.signature }
superClassVirtualMethods.mapTo(result) { signatureToVirtualFunction[it.signature] ?: it }
val superSignatures = superClassVirtualMethods.mapTo(mutableSetOf()) { it.signature }
virtualFunctions.filterTo(result) { it.signature !in superSignatures }
virtualFunctionsMetadata.filterTo(result) { it.signature !in superSignatures }
result
}
init {
val signatureToFunctions = mutableMapOf<WasmSignature, MutableList<IrSimpleFunction>>()
for (vm in virtualMethods) {
signatureToFunctions.getOrPut(vm.signature) { mutableListOf() }.add(vm.function)
}
for ((sig, functions) in signatureToFunctions) {
if (functions.size > 1) {
val funcList = functions.joinToString { " ---- ${it.fqNameWhenAvailable} \n" }
// TODO: Check in FE
error("Class ${klass.fqNameWhenAvailable} has ${functions.size} methods with the same signature $sig\n $funcList")
}
}
}
}
class InterfaceMetadata(val iFace: IrClass, irBuiltIns: IrBuiltIns) {
@@ -113,9 +113,10 @@ class WasmModuleCodegenContext(
val superClass = irClass.owner.getSuperClass(backendContext.irBuiltIns)
val superClassMetadata = superClass?.let { getClassMetadata(it.symbol) }
ClassMetadata(
irClass.owner,
superClassMetadata,
backendContext.irBuiltIns
klass = irClass.owner,
superClass = superClassMetadata,
irBuiltIns = backendContext.irBuiltIns,
allowAccidentalOverride = backendContext.partialLinkageSupport.isEnabled
)
}