[Wasm] Allow virtual functions signature clash for PL support
This commit is contained in:
committed by
Space Team
parent
8851ccc35d
commit
ec1ade1293
+19
-20
@@ -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) {
|
||||||
|
|||||||
+4
-3
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user