diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/module-splitting.cpp | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index 50809a9a4..22f8b301f 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -147,15 +147,23 @@ 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. + return; + } + // TODO: Reject or handle passive element segments - // TODO: If reference types are enabled, just create a fresh table to make bad - // interactions with user code impossible. auto funcref = Type(HeapType::func, Nullable); auto it = std::find_if( module.tables.begin(), module.tables.end(), [&](std::unique_ptr<Table>& table) { return table->type == funcref; }); if (it == module.tables.end()) { + // There is no indirect function table, so we will create one lazily. return; } @@ -560,18 +568,15 @@ void ModuleSplitter::indirectReferencesToSecondaryFunctions() { } gatherer(*this); gatherer.walkModule(&primary); - // Find all RefFuncs in active elementSegments, which we can ignore: tables - // are the means by which we connect the modules, and are handled directly. - // Passive segments, however, are like RefFuncs in code, and we need to not - // ignore them here. + // Ignore references to secondary functions that occur in the active segment + // that will contain the imported placeholders. Indirect calls to table slots + // initialized by that segment will already go to the right place once the + // secondary module has been loaded and the table has been patched. std::unordered_set<RefFunc*> ignore; - for (auto& seg : primary.elementSegments) { - if (!seg->table.is()) { - continue; - } - for (auto* curr : seg->data) { - if (auto* refFunc = curr->dynCast<RefFunc>()) { - ignore.insert(refFunc); + if (tableManager.activeSegment) { + for (auto* expr : tableManager.activeSegment->data) { + if (auto* ref = expr->dynCast<RefFunc>()) { + ignore.insert(ref); } } } |