[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( class ClassMetadata(
val klass: IrClass, val klass: IrClass,
val superClass: ClassMetadata?, val superClass: ClassMetadata?,
irBuiltIns: IrBuiltIns irBuiltIns: IrBuiltIns,
allowAccidentalOverride: Boolean,
) { ) {
// List of all fields including fields of super classes // List of all fields including fields of super classes
// In Wasm order // In Wasm order
@@ -102,36 +103,34 @@ class ClassMetadata(
val virtualFunctions = klass.declarations val virtualFunctions = klass.declarations
.asSequence() .asSequence()
.filterVirtualFunctions() .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 val superClassVirtualMethods = superClass?.virtualMethods
if (superClassVirtualMethods.isNullOrEmpty()) return@run virtualFunctions if (superClassVirtualMethods.isNullOrEmpty()) return@run virtualFunctionsMetadata
val result = mutableListOf<VirtualMethodMetadata>() val result = mutableListOf<VirtualMethodMetadata>()
val signatureToVirtualFunction = virtualFunctions.associateBy { it.signature } val signatureToVirtualFunction = virtualFunctionsMetadata.associateBy { it.signature }
superClassVirtualMethods.mapTo(result) { signatureToVirtualFunction[it.signature] ?: it } superClassVirtualMethods.mapTo(result) { signatureToVirtualFunction[it.signature] ?: it }
val superSignatures = superClassVirtualMethods.mapTo(mutableSetOf()) { it.signature } val superSignatures = superClassVirtualMethods.mapTo(mutableSetOf()) { it.signature }
virtualFunctions.filterTo(result) { it.signature !in superSignatures } virtualFunctionsMetadata.filterTo(result) { it.signature !in superSignatures }
result 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) { class InterfaceMetadata(val iFace: IrClass, irBuiltIns: IrBuiltIns) {
@@ -113,9 +113,10 @@ class WasmModuleCodegenContext(
val superClass = irClass.owner.getSuperClass(backendContext.irBuiltIns) val superClass = irClass.owner.getSuperClass(backendContext.irBuiltIns)
val superClassMetadata = superClass?.let { getClassMetadata(it.symbol) } val superClassMetadata = superClass?.let { getClassMetadata(it.symbol) }
ClassMetadata( ClassMetadata(
irClass.owner, klass = irClass.owner,
superClassMetadata, superClass = superClassMetadata,
backendContext.irBuiltIns irBuiltIns = backendContext.irBuiltIns,
allowAccidentalOverride = backendContext.partialLinkageSupport.isEnabled
) )
} }