[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:
committed by
teamcity
parent
88f1f74aec
commit
d788adcbb5
+16
-8
@@ -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"
|
||||
}
|
||||
+5
@@ -30,6 +30,11 @@ public class IrCodegenWasmJsInteropWasmTestGenerated extends AbstractIrCodegenWa
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxWasmJsInterop"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.WASM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("callingWasmDirectly.kt")
|
||||
public void testCallingWasmDirectly() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxWasmJsInterop/callingWasmDirectly.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultValues.kt")
|
||||
public void testDefaultValues() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt");
|
||||
|
||||
@@ -10,9 +10,7 @@ import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation
|
||||
|
||||
class WasmModule(
|
||||
val functionTypes: List<WasmFunctionType> = emptyList(),
|
||||
val gcTypes: List<WasmTypeDeclaration> = emptyList(),
|
||||
val gcTypesInRecursiveGroup: Boolean,
|
||||
|
||||
val recGroupTypes: List<WasmTypeDeclaration> = emptyList(),
|
||||
val importsInOrder: List<WasmNamedModuleField> = emptyList(),
|
||||
val importedFunctions: List<WasmFunction.Imported> = emptyList(),
|
||||
val importedMemories: List<WasmMemory> = emptyList(),
|
||||
|
||||
@@ -77,3 +77,15 @@ fun WasmType.getHeapType(): WasmHeapType =
|
||||
is WasmExternRef -> WasmHeapType.Simple.Extern
|
||||
else -> error("Unknown heap type for type $this")
|
||||
}
|
||||
|
||||
fun WasmFunctionType.referencesTypeDeclarations(): Boolean =
|
||||
parameterTypes.any { it.referencesTypeDeclaration() } or resultTypes.any { it.referencesTypeDeclaration() }
|
||||
|
||||
fun WasmType.referencesTypeDeclaration(): Boolean {
|
||||
val heapType = when (this) {
|
||||
is WasmRefNullType -> getHeapType()
|
||||
is WasmRefType -> getHeapType()
|
||||
else -> return false
|
||||
}
|
||||
return heapType is WasmHeapType.Type
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ fun WasmModule.calculateIds() {
|
||||
}
|
||||
|
||||
functionTypes.calculateIds()
|
||||
gcTypes.calculateIds(startIndex = functionTypes.size)
|
||||
recGroupTypes.calculateIds(startIndex = functionTypes.size)
|
||||
importedFunctions.calculateIds()
|
||||
importedMemories.calculateIds()
|
||||
importedTables.calculateIds()
|
||||
|
||||
@@ -329,8 +329,7 @@ class WasmBinaryToIR(val b: MyByteReader) {
|
||||
|
||||
return WasmModule(
|
||||
functionTypes = functionTypes,
|
||||
gcTypes = gcTypes,
|
||||
gcTypesInRecursiveGroup = false,
|
||||
recGroupTypes = gcTypes,
|
||||
importsInOrder = importsInOrder,
|
||||
importedFunctions = importedFunctions,
|
||||
importedMemories = importedMemories,
|
||||
|
||||
@@ -35,17 +35,18 @@ class WasmIrToBinary(
|
||||
with(module) {
|
||||
// type section
|
||||
appendSection(1u) {
|
||||
if (module.gcTypesInRecursiveGroup) {
|
||||
appendVectorSize(1)
|
||||
b.writeByte(0x4f)
|
||||
}
|
||||
appendVectorSize(functionTypes.size + gcTypes.size)
|
||||
val numRecGroups = if (recGroupTypes.isEmpty()) 0 else 1
|
||||
appendVectorSize(functionTypes.size + numRecGroups)
|
||||
functionTypes.forEach { appendFunctionTypeDeclaration(it) }
|
||||
gcTypes.forEach {
|
||||
when (it) {
|
||||
is WasmStructDeclaration -> appendStructTypeDeclaration(it)
|
||||
is WasmArrayDeclaration -> appendArrayTypeDeclaration(it)
|
||||
is WasmFunctionType -> error("Function type in GC types")
|
||||
if (!recGroupTypes.isEmpty()) {
|
||||
b.writeByte(0x4f)
|
||||
appendVectorSize(recGroupTypes.size)
|
||||
recGroupTypes.forEach {
|
||||
when (it) {
|
||||
is WasmStructDeclaration -> appendStructTypeDeclaration(it)
|
||||
is WasmArrayDeclaration -> appendArrayTypeDeclaration(it)
|
||||
is WasmFunctionType -> appendFunctionTypeDeclaration(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,8 +173,8 @@ class WasmIrToBinary(
|
||||
// https://github.com/WebAssembly/extended-name-section/blob/main/document/core/appendix/custom.rst
|
||||
|
||||
appendSection(4u) {
|
||||
appendVectorSize(module.gcTypes.size)
|
||||
module.gcTypes.forEach {
|
||||
appendVectorSize(module.recGroupTypes.size)
|
||||
module.recGroupTypes.forEach {
|
||||
appendModuleFieldReference(it)
|
||||
b.writeString(it.name)
|
||||
}
|
||||
@@ -190,7 +191,7 @@ class WasmIrToBinary(
|
||||
// Experimental fields name section
|
||||
// https://github.com/WebAssembly/gc/issues/193
|
||||
appendSection(10u) {
|
||||
val structDeclarations = module.gcTypes.filterIsInstance<WasmStructDeclaration>()
|
||||
val structDeclarations = module.recGroupTypes.filterIsInstance<WasmStructDeclaration>()
|
||||
appendVectorSize(structDeclarations.size)
|
||||
structDeclarations.forEach {
|
||||
appendModuleFieldReference(it)
|
||||
|
||||
@@ -228,13 +228,14 @@ class WasmIrToText : SExpressionBuilder() {
|
||||
with(module) {
|
||||
newLineList("module") {
|
||||
functionTypes.forEach { appendFunctionTypeDeclaration(it) }
|
||||
gcTypes.forEach {
|
||||
recGroupTypes.forEach {
|
||||
when (it) {
|
||||
is WasmStructDeclaration ->
|
||||
appendStructTypeDeclaration(it)
|
||||
is WasmArrayDeclaration ->
|
||||
appendArrayTypeDeclaration(it)
|
||||
else -> error("Unexpected GC type: $it")
|
||||
is WasmFunctionType ->
|
||||
appendFunctionTypeDeclaration(it)
|
||||
}
|
||||
}
|
||||
importsInOrder.forEach {
|
||||
|
||||
Reference in New Issue
Block a user