-
Notifications
You must be signed in to change notification settings - Fork 843
Add sourcemap support to wasm-metadce and wasm-merge #6372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
206edf6
18b2d63
5a3caa4
824eda0
ad6acac
8ddd780
b37f66c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |||||
| */ | ||||||
|
|
||||||
| #include "module-utils.h" | ||||||
| #include "ir/debug.h" | ||||||
| #include "ir/intrinsics.h" | ||||||
| #include "ir/manipulation.h" | ||||||
| #include "ir/properties.h" | ||||||
|
|
@@ -23,17 +24,46 @@ | |||||
|
|
||||||
| namespace wasm::ModuleUtils { | ||||||
|
|
||||||
| static void updateLocationSet(std::set<Function::DebugLocation>& locations, | ||||||
| std::vector<Index>* indexMap) { | ||||||
|
||||||
| std::vector<Index>* indexMap) { | |
| std::vector<Index>& indexMap) { |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We prefer this pattern:
| std::vector<Index>* indexMap) { | |
| std::optional<std::vector<Index>> indexMap = std::nullopt) { |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this could be fileIndexMap to clarify what it refers to?
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -324,9 +324,26 @@ void renameInputItems(Module& input) { | |
| } | ||
|
|
||
| void copyModuleContents(Module& input, Name inputName) { | ||
| // First, copy the regular module items (functions, globals) etc. which we | ||
| // Source map filename index mapping | ||
| std::vector<Index> indexMap; | ||
| std::unordered_map<std::string, Index> debugInfoFileIndices; | ||
| for (Index i = 0; i < merged.debugInfoFileNames.size(); i++) { | ||
| debugInfoFileIndices[merged.debugInfoFileNames[i]] = i; | ||
| } | ||
| for (Index i = 0; i < input.debugInfoFileNames.size(); i++) { | ||
| std::string file = input.debugInfoFileNames[i]; | ||
| auto iter = debugInfoFileIndices.find(file); | ||
| if (iter == debugInfoFileIndices.end()) { | ||
| Index index = merged.debugInfoFileNames.size(); | ||
| merged.debugInfoFileNames.push_back(file); | ||
| debugInfoFileIndices[file] = index; | ||
| } | ||
| indexMap.push_back(debugInfoFileIndices[file]); | ||
| } | ||
|
|
||
| // Copy the regular module items (functions, globals) etc. which we | ||
| // have proper names for, and can just copy. | ||
| ModuleUtils::copyModuleItems(input, merged); | ||
| ModuleUtils::copyModuleItems(input, merged, &indexMap); | ||
|
||
|
|
||
| // We must handle exports in a special way, as we need to note their origin | ||
| // module as we copy them in (also, they are not importable or exportable, so | ||
|
|
@@ -452,6 +469,9 @@ int main(int argc, const char* argv[]) { | |
| std::vector<std::string> inputFileNames; | ||
| bool emitBinary = true; | ||
| bool debugInfo = false; | ||
| std::map<size_t, std::string> inputSourceMapFilenames; | ||
| std::string outputSourceMapFilename; | ||
| std::string outputSourceMapUrl; | ||
|
|
||
| const std::string WasmMergeOption = "wasm-merge options"; | ||
|
|
||
|
|
@@ -464,7 +484,11 @@ For example, | |
|
|
||
| will read foo.wasm and bar.wasm, with names 'foo' and 'bar' respectively, so if the second imports from 'foo', we will see that as an import from the first module after the merge. The merged output will be written to merged.wasm. | ||
|
|
||
| Note that filenames and modules names are interleaved (which is hopefully less confusing).)"); | ||
| Note that filenames and modules names are interleaved (which is hopefully less confusing). | ||
|
|
||
| Input source maps can be specified by adding an --ism option right after the module name: | ||
|
|
||
| wasm-merge foo.wasm foo --ism foo.wasm.map ...)"); | ||
|
|
||
| options | ||
| .add("--output", | ||
|
|
@@ -485,6 +509,37 @@ Note that filenames and modules names are interleaved (which is hopefully less c | |
| inputFileNames.push_back(argument); | ||
| } | ||
| }) | ||
| .add("--input-source-map", | ||
| "-ism", | ||
| "Consume source maps from the specified files", | ||
| WasmMergeOption, | ||
| Options::Arguments::N, | ||
| [&](Options* o, const std::string& argument) { | ||
| size_t pos = inputFiles.size(); | ||
| if (pos == 0 || pos != inputFileNames.size() || | ||
| inputSourceMapFilenames.count(pos - 1)) { | ||
| std::cerr << "Option '-ism " << argument | ||
| << "' should be right after the module name\n"; | ||
| exit(EXIT_FAILURE); | ||
| } | ||
| inputSourceMapFilenames.insert({pos - 1, argument}); | ||
| }) | ||
| .add("--output-source-map", | ||
| "-osm", | ||
| "Emit source map to the specified file", | ||
| WasmMergeOption, | ||
| Options::Arguments::One, | ||
| [&outputSourceMapFilename](Options* o, const std::string& argument) { | ||
| outputSourceMapFilename = argument; | ||
| }) | ||
| .add("--output-source-map-url", | ||
| "-osu", | ||
| "Emit specified string as source map URL", | ||
| WasmMergeOption, | ||
| Options::Arguments::One, | ||
| [&outputSourceMapUrl](Options* o, const std::string& argument) { | ||
| outputSourceMapUrl = argument; | ||
| }) | ||
| .add("--rename-export-conflicts", | ||
| "-rec", | ||
| "Rename exports to avoid conflicts (rather than error)", | ||
|
|
@@ -529,6 +584,9 @@ Note that filenames and modules names are interleaved (which is hopefully less c | |
| for (Index i = 0; i < inputFiles.size(); i++) { | ||
| auto inputFile = inputFiles[i]; | ||
| auto inputFileName = inputFileNames[i]; | ||
| auto iter = inputSourceMapFilenames.find(i); | ||
| auto inputSourceMapFilename = | ||
| (iter == inputSourceMapFilenames.end()) ? "" : iter->second; | ||
|
|
||
| if (options.debug) { | ||
| std::cerr << "reading input '" << inputFile << "' as '" << inputFileName | ||
|
|
@@ -550,7 +608,7 @@ Note that filenames and modules names are interleaved (which is hopefully less c | |
|
|
||
| ModuleReader reader; | ||
| try { | ||
| reader.read(inputFile, *currModule); | ||
| reader.read(inputFile, *currModule, inputSourceMapFilename); | ||
| } catch (ParseException& p) { | ||
| p.dump(std::cerr); | ||
| Fatal() << "error in parsing wasm input: " << inputFile; | ||
|
|
@@ -606,6 +664,10 @@ Note that filenames and modules names are interleaved (which is hopefully less c | |
| ModuleWriter writer; | ||
| writer.setBinary(emitBinary); | ||
| writer.setDebugInfo(debugInfo); | ||
| if (outputSourceMapFilename.size()) { | ||
| writer.setSourceMapFilename(outputSourceMapFilename); | ||
| writer.setSourceMapUrl(outputSourceMapUrl); | ||
| } | ||
| writer.write(merged, options.extra["output"]); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -365,6 +365,9 @@ int main(int argc, const char* argv[]) { | |
| bool debugInfo = false; | ||
| std::string graphFile; | ||
| bool dump = false; | ||
| std::string inputSourceMapFilename; | ||
| std::string outputSourceMapFilename; | ||
| std::string outputSourceMapUrl; | ||
|
|
||
| const std::string WasmMetaDCEOption = "wasm-opt options"; | ||
|
|
||
|
|
@@ -423,6 +426,30 @@ int main(int argc, const char* argv[]) { | |
| o->extra["output"] = argument; | ||
| Colors::setEnabled(false); | ||
| }) | ||
| .add("--input-source-map", | ||
| "-ism", | ||
| "Consume source map from the specified file", | ||
| WasmMetaDCEOption, | ||
| Options::Arguments::One, | ||
| [&inputSourceMapFilename](Options* o, const std::string& argument) { | ||
| inputSourceMapFilename = argument; | ||
| }) | ||
| .add("--output-source-map", | ||
| "-osm", | ||
| "Emit source map to the specified file", | ||
| WasmMetaDCEOption, | ||
| Options::Arguments::One, | ||
| [&outputSourceMapFilename](Options* o, const std::string& argument) { | ||
| outputSourceMapFilename = argument; | ||
| }) | ||
| .add("--output-source-map-url", | ||
| "-osu", | ||
| "Emit specified string as source map URL", | ||
| WasmMetaDCEOption, | ||
| Options::Arguments::One, | ||
| [&outputSourceMapUrl](Options* o, const std::string& argument) { | ||
| outputSourceMapUrl = argument; | ||
| }) | ||
| .add("--emit-text", | ||
| "-S", | ||
| "Emit text instead of binary for the output file", | ||
|
|
@@ -470,7 +497,7 @@ int main(int argc, const char* argv[]) { | |
| ModuleReader reader; | ||
| reader.setDWARF(debugInfo); | ||
| try { | ||
| reader.read(options.extra["infile"], wasm); | ||
| reader.read(options.extra["infile"], wasm, input); | ||
| } catch (ParseException& p) { | ||
| p.dump(std::cerr); | ||
| Fatal() << "error in parsing wasm input"; | ||
|
|
@@ -578,6 +605,10 @@ int main(int argc, const char* argv[]) { | |
| ModuleWriter writer; | ||
| writer.setBinary(emitBinary); | ||
| writer.setDebugInfo(debugInfo); | ||
| if (outputSourceMapFilename.size()) { | ||
| writer.setSourceMapFilename(outputSourceMapFilename); | ||
| writer.setSourceMapUrl(outputSourceMapUrl); | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a test for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have also updated the test for |
||
| writer.write(wasm, options.extra["output"]); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. | ||
|
|
||
| ;; RUN: wasm-merge %s first %s.second second -S -o - | filecheck %s | ||
|
|
||
| ;; Test that sourcemap information is preserved | ||
|
|
||
| (module | ||
| ;;@ a:1:1 | ||
| (func (export "f") | ||
| ;;@ a:2:1 | ||
| (nop) | ||
| ;;@ a:3:1 | ||
| ) | ||
| ) | ||
| ;; CHECK: (type $0 (func)) | ||
|
|
||
| ;; CHECK: (export "f" (func $0)) | ||
|
|
||
| ;; CHECK: (export "g" (func $0_1)) | ||
|
|
||
| ;; CHECK: ;;@ a:1:1 | ||
| ;; CHECK-NEXT: (func $0 | ||
| ;; CHECK-NEXT: ;;@ a:2:1 | ||
| ;; CHECK-NEXT: (nop) | ||
| ;; CHECK-NEXT: ;;@ a:3:1 | ||
| ;; CHECK-NEXT: ) | ||
|
|
||
| ;; CHECK: ;;@ b:1:2 | ||
| ;; CHECK-NEXT: (func $0_1 | ||
| ;; CHECK-NEXT: ;;@ b:2:2 | ||
| ;; CHECK-NEXT: (nop) | ||
| ;; CHECK-NEXT: ;;@ b:3:2 | ||
| ;; CHECK-NEXT: ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| (module | ||
| ;;@ b:1:2 | ||
| (func (export "g") | ||
| ;;@ b:2:2 | ||
| (nop) | ||
| ;;@ b:3:2 | ||
| ) | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment explaining what this function does.