[Wasm] Move non-recursive function types out of rec group

This fixes linking with other wasm modules with non-rec types
This commit is contained in:
Svyatoslav Kuzmich
2022-12-21 17:16:32 +01:00
committed by teamcity
parent 88f1f74aec
commit d788adcbb5
9 changed files with 83 additions and 29 deletions
@@ -192,21 +192,29 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
}
}
val typeDeclarations = mutableListOf<WasmTypeDeclaration>()
typeDeclarations.addAll(vTableGcTypes.elements)
typeDeclarations.addAll(gcTypes.elements)
typeDeclarations.addAll(classITableGcType.elements.distinct())
typeDeclarations.sortBy(::wasmTypeDeclarationOrderKey)
val recGroupTypes = mutableListOf<WasmTypeDeclaration>()
recGroupTypes.addAll(vTableGcTypes.elements)
recGroupTypes.addAll(this.gcTypes.elements)
recGroupTypes.addAll(classITableGcType.elements.distinct())
recGroupTypes.sortBy(::wasmTypeDeclarationOrderKey)
val globals = mutableListOf<WasmGlobal>()
globals.addAll(globalFields.elements)
globals.addAll(globalVTables.elements)
globals.addAll(globalClassITables.elements.distinct())
val allFunctionTypes = canonicalFunctionTypes.values.toList() + tagFuncType + masterInitFunctionType
// Partition out function types that can't be recursive,
// we don't need to put them into a rec group
// so that they can be matched with function types from other Wasm modules.
val (potentiallyRecursiveFunctionTypes, nonRecursiveFunctionTypes) =
allFunctionTypes.partition { it.referencesTypeDeclarations() }
recGroupTypes.addAll(potentiallyRecursiveFunctionTypes)
val module = WasmModule(
functionTypes = canonicalFunctionTypes.values.toList() + tagFuncType + masterInitFunctionType,
gcTypes = typeDeclarations,
gcTypesInRecursiveGroup = true,
functionTypes = nonRecursiveFunctionTypes,
recGroupTypes = recGroupTypes,
importsInOrder = importedFunctions,
importedFunctions = importedFunctions,
definedFunctions = functions.elements.filterIsInstance<WasmFunction.Defined>() + masterInitFunction,
@@ -0,0 +1,30 @@
// TARGET_BACKEND: WASM
/*
Here we pass export of another Wasm module to our import directly without JS layer.
This enables strict type check without JS conversons.
For instance, recursion groups of function types must fully match.
(module
(func (export "addTwo") (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add))
*/
@JsFun("""
(() => {
let bytes = [0, 97, 115, 109, 1, 0, 0, 0, 1, 7, 1, 96, 2, 127, 127, 1, 127, 3,
2, 1, 0, 7, 10, 1, 6, 97, 100, 100, 84, 119, 111, 0, 0, 10, 9, 1,
7, 0, 32, 0, 32, 1, 106, 11, 0, 10, 4, 110, 97, 109, 101, 2, 3, 1, 0, 0];
let buffer = (new Int8Array(bytes)).buffer;
let module = new WebAssembly.Module(buffer);
let instance = new WebAssembly.Instance(module);
return instance.exports.addTwo;
})()
""")
external fun addTwo(a: Int, b: Int): Int
fun box(): String {
if (addTwo(100, 200) != 300) return "Fail1"
return "OK"
}