diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2020-12-16 16:40:15 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-16 13:40:15 -0800 |
commit | 83114c51d5aedcb540d578790dbf3173d1775d5c (patch) | |
tree | caace0fed6e225496243121fcb0beed95ad71512 /src/ir/module-splitting.cpp | |
parent | b50bdf3491dcd8f1c379df6d64bc8fbc10518326 (diff) | |
download | binaryen-83114c51d5aedcb540d578790dbf3173d1775d5c.tar.gz binaryen-83114c51d5aedcb540d578790dbf3173d1775d5c.tar.bz2 binaryen-83114c51d5aedcb540d578790dbf3173d1775d5c.zip |
Fix wasm-split name collision bug (#3447)
During module splitting, a map is constructed from internal names to their
corresponding export names. This code previously did not take into account the
fact that the same internal name may be used by different kinds of
entities (e.g. a table and a memory may have the same internal name), which
resulted in the secondary module incorrectly using the same import name for all
of the entities that shared an internal name. This PR fixes the problem by
including the ExternalKind of the entity in the keys of the export map.
Diffstat (limited to 'src/ir/module-splitting.cpp')
-rw-r--r-- | src/ir/module-splitting.cpp | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index aad43fc75..f4f00c9af 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -80,6 +80,19 @@ #include "wasm-builder.h" #include "wasm.h" +namespace std { + +// Used in ModuleSplitter::shareImportableItems +template<> struct hash<pair<wasm::ExternalKind, wasm::Name>> { + size_t operator()(const pair<wasm::ExternalKind, wasm::Name>& p) const { + auto digest = wasm::hash(p.first); + wasm::rehash(digest, p.second); + return digest; + } +}; + +} // namespace std + namespace wasm { namespace ModuleSplitting { @@ -496,10 +509,10 @@ void ModuleSplitter::shareImportableItems() { // Map internal names to (one of) their corresponding export names. Don't // consider functions because they have already been imported and exported as // necessary. - std::unordered_map<Name, Name> exports; + std::unordered_map<std::pair<ExternalKind, Name>, Name> exports; for (auto& ex : primary.exports) { if (ex->kind != ExternalKind::Function) { - exports[ex->value] = ex->name; + exports[std::make_pair(ex->kind, ex->value)] = ex->name; } } @@ -510,7 +523,7 @@ void ModuleSplitter::shareImportableItems() { secondaryItem.name = primaryItem.name; secondaryItem.hasExplicitName = primaryItem.hasExplicitName; secondaryItem.module = config.importNamespace; - auto exportIt = exports.find(primaryItem.name); + auto exportIt = exports.find(std::make_pair(kind, primaryItem.name)); if (exportIt != exports.end()) { secondaryItem.base = exportIt->second; } else { |