From 9f496abc5cf1ddbca8c8a4f4e740c412588708ef Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Fri, 1 Nov 2024 17:35:35 -0700 Subject: Module splitting: don't create new tables when splitting with Emscripten (#7050) Emscripten's JS loader code for wasm-split isn't prepared for handling multiple tables that binaryen automatically creates when reference types are enabled (especially in conjunction with dynamic loading). For now, disable creation of multiple tables when using Emscripten's table ABI (distinguished by importing or exporting a table named "__indirect_function_table". --- src/ir/module-splitting.cpp | 24 ++++++++++++++++++------ src/wasm/wasm.cpp | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index f299d7a35..a7ee96fa2 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -146,12 +146,24 @@ void TableSlotManager::addSlot(Name func, Slot slot) { } TableSlotManager::TableSlotManager(Module& module) : module(module) { - if (module.features.hasReferenceTypes()) { - // Just create a new table to manage all primary-to-secondary calls lazily. - // Do not re-use slots for functions that will already be in existing - // tables, since that is not correct in the face of table mutations. - // TODO: Reduce overhead by creating a separate table for each function type - // if WasmGC is enabled. + // If possible, just create a new table to manage all primary-to-secondary + // calls lazily. Do not re-use slots for functions that will already be in + // existing tables, since that is not correct in the face of table mutations. + // However, do not do this for emscripten; its loader code (and dynamic + // loading in particular) do not support this yet. + // TODO: Reduce overhead by creating a separate table for each function type + // if WasmGC is enabled. + Export* emscriptenTableExport = + module.getExportOrNull("__indirect_function_table"); + Table* singletonTable = + module.tables.size() == 1 ? module.tables[0].get() : nullptr; + bool emscriptenTableImport = + singletonTable && singletonTable->imported() && + singletonTable->module == "env" && + singletonTable->base == "__indirect_function_table"; + + if (module.features.hasReferenceTypes() && !emscriptenTableExport && + !emscriptenTableImport) { return; } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 4150af5b4..a1ac076e0 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1631,7 +1631,7 @@ Importable* Module::getImport(ModuleItemKind kind, Name name) { Importable* Module::getImportOrNull(ModuleItemKind kind, Name name) { auto doReturn = [](Importable* importable) { - return importable->imported() ? importable : nullptr; + return importable ? importable->imported() ? importable : nullptr : nullptr; }; switch (kind) { -- cgit v1.2.3