diff options
-rw-r--r-- | src/ir/module-splitting.cpp | 9 | ||||
-rw-r--r-- | src/ir/module-splitting.h | 7 | ||||
-rw-r--r-- | src/tools/wasm-split.cpp | 26 | ||||
-rw-r--r-- | test/example/module-splitting.cpp | 4 | ||||
-rw-r--r-- | test/lit/wasm-split/help.test | 2 | ||||
-rw-r--r-- | test/lit/wasm-split/placeholdermap.wast | 24 |
6 files changed, 65 insertions, 7 deletions
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index d6dca8994..9c5c66641 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -272,6 +272,9 @@ struct ModuleSplitter { // names. std::map<Name, Name> exportedPrimaryFuncs; + // Map placeholder indices to the names of the functions they replace. + std::map<size_t, Name> placeholderMap; + // Initialization helpers static std::unique_ptr<Module> initSecondary(const Module& primary); static std::pair<std::set<Name>, std::set<Name>> @@ -483,6 +486,7 @@ void ModuleSplitter::setupTablePatching() { // `importNamespace`.`index`. forEachElement(primary, [&](Name, Name, Index index, Name& elem) { if (secondaryFuncs.count(elem)) { + placeholderMap[index] = elem; auto* secondaryFunc = secondary.getFunction(elem); replacedElems[index] = secondaryFunc; auto placeholder = std::make_unique<Function>(); @@ -655,8 +659,9 @@ void ModuleSplitter::shareImportableItems() { } // anonymous namespace -std::unique_ptr<Module> splitFunctions(Module& primary, const Config& config) { - return std::move(ModuleSplitter(primary, config).secondaryPtr); +Results splitFunctions(Module& primary, const Config& config) { + ModuleSplitter split(primary, config); + return {std::move(split.secondaryPtr), std::move(split.placeholderMap)}; } } // namespace ModuleSplitting diff --git a/src/ir/module-splitting.h b/src/ir/module-splitting.h index 479fba148..cfbd45b14 100644 --- a/src/ir/module-splitting.h +++ b/src/ir/module-splitting.h @@ -68,8 +68,13 @@ struct Config { bool minimizeNewExportNames = false; }; +struct Results { + std::unique_ptr<Module> secondary; + std::map<size_t, Name> placeholderMap; +}; + // Returns the new secondary module and modifies the `primary` module in place. -std::unique_ptr<Module> splitFunctions(Module& primary, const Config& config); +Results splitFunctions(Module& primary, const Config& config); } // namespace ModuleSplitting diff --git a/src/tools/wasm-split.cpp b/src/tools/wasm-split.cpp index 4ac295d0e..261c62a68 100644 --- a/src/tools/wasm-split.cpp +++ b/src/tools/wasm-split.cpp @@ -61,6 +61,7 @@ struct WasmSplitOptions : ToolOptions { bool verbose = false; bool emitBinary = true; bool symbolMap = false; + bool placeholderMap = false; // TODO: Remove this. See the comment in wasm-binary.h. bool emitModuleNames = false; @@ -180,6 +181,13 @@ WasmSplitOptions::WasmSplitOptions() {Mode::Split}, Options::Arguments::Zero, [&](Options* o, const std::string& argument) { symbolMap = true; }) + .add( + "--placeholdermap", + "", + "Write a file mapping placeholder indices to the function names.", + {Mode::Split}, + Options::Arguments::Zero, + [&](Options* o, const std::string& argument) { placeholderMap = true; }) .add("--import-namespace", "", "The namespace from which to import objects from the primary " @@ -690,6 +698,15 @@ void writeSymbolMap(Module& wasm, std::string filename) { runner.run(); } +void writePlaceholderMap(const std::map<size_t, Name> placeholderMap, + std::string filename) { + Output output(filename, Flags::Text); + auto& o = output.getStream(); + for (auto pair : placeholderMap) { + o << pair.first << ':' << pair.second << '\n'; + } +} + void splitModule(const WasmSplitOptions& options) { Module wasm; parseInput(wasm, options); @@ -795,8 +812,8 @@ void splitModule(const WasmSplitOptions& options) { config.newExportPrefix = options.exportPrefix; } config.minimizeNewExportNames = !options.passOptions.debugInfo; - std::unique_ptr<Module> secondary = - ModuleSplitting::splitFunctions(wasm, config); + auto splitResults = ModuleSplitting::splitFunctions(wasm, config); + auto& secondary = splitResults.secondary; adjustTableSize(wasm, options.initialTableSize); adjustTableSize(*secondary, options.initialTableSize); @@ -806,6 +823,11 @@ void splitModule(const WasmSplitOptions& options) { writeSymbolMap(*secondary, options.secondaryOutput + ".symbols"); } + if (options.placeholderMap) { + writePlaceholderMap(splitResults.placeholderMap, + options.primaryOutput + ".placeholders"); + } + // Set the names of the split modules. This can help differentiate them in // stack traces. if (options.emitModuleNames) { diff --git a/test/example/module-splitting.cpp b/test/example/module-splitting.cpp index 2aa67d6d5..9ff2818be 100644 --- a/test/example/module-splitting.cpp +++ b/test/example/module-splitting.cpp @@ -50,7 +50,7 @@ void do_test(const std::set<Name>& keptFuncs, std::string&& module) { ModuleSplitting::Config config; config.primaryFuncs = keptFuncs; config.newExportPrefix = "%"; - auto secondary = splitFunctions(*primary, config); + auto secondary = splitFunctions(*primary, config).secondary; std::cout << "After:\n"; std::cout << *primary.get(); @@ -476,7 +476,7 @@ void test_minimized_exports() { config.newExportPrefix = "%"; config.minimizeNewExportNames = true; - auto secondary = splitFunctions(primary, config); + auto secondary = splitFunctions(primary, config).secondary; std::cout << "Minimized names primary:\n"; std::cout << primary << "\n"; std::cout << "Minimized names secondary:\n"; diff --git a/test/lit/wasm-split/help.test b/test/lit/wasm-split/help.test index de789a362..8159e66db 100644 --- a/test/lit/wasm-split/help.test +++ b/test/lit/wasm-split/help.test @@ -34,6 +34,8 @@ CHECK-NEXT: --secondary-output,-o2 [split] Output file for the s CHECK-NEXT: module. CHECK-NEXT: --symbolmap [split] Write a symbol map file for each CHECK-NEXT: of the output modules. +CHECK-NEXT: --placeholdermap [split] Write a file mapping placeholder +CHECK-NEXT: indices to the function names. CHECK-NEXT: --import-namespace [split] The namespace from which to CHECK-NEXT: import objects from the primary module CHECK-NEXT: into the secondary module. diff --git a/test/lit/wasm-split/placeholdermap.wast b/test/lit/wasm-split/placeholdermap.wast new file mode 100644 index 000000000..dd8598b0b --- /dev/null +++ b/test/lit/wasm-split/placeholdermap.wast @@ -0,0 +1,24 @@ +;; RUN: wasm-split %s --keep-funcs=bar -o1 %t.1.wasm -o2 %t.2.wasm --placeholdermap +;; RUN: filecheck %s --check-prefix MAP < %t.1.wasm.placeholders +;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY + +;; MAP: 0:foo +;; MAP-NEXT: 2:baz +;; MAP-NOT: bar + +;; Check that the names have been stripped. +;; PRIMARY: (func $0 + +(module + (table $table 3 3 funcref) + (elem $table (i32.const 0) $foo $bar $baz) + (func $foo + (nop) + ) + (func $bar + (nop) + ) + (func $baz + (nop) + ) +) |