From 0596fcf44d83eb6470abbc066ecce2a9f1130514 Mon Sep 17 00:00:00 2001 From: Martin Kustermann Date: Thu, 18 Jun 2026 11:13:58 +0200 Subject: [PATCH] Add --emit-module-names to wasm-opt The `wasm-split` command has this `--emit-module-names` flag already and this adds it to `wasm-opt` as well. Wasm runtimes may not know the URL where a wasm file came from, it may only be given the bytes. Currently e.g. V8 prints a V8 specific hash of the wasm file in stack traces. If we have the ability to keep module names, then it would print the module name (fallback if the url is not available) -- which would allow a stack trace decoding tool to tie the module name back to the right wasm module of an app. --- src/tools/wasm-opt.cpp | 16 ++++++++++++++++ test/lit/emit-module-names.wast | 15 +++++++++++++++ test/lit/help/wasm-opt.test | 4 ++++ 3 files changed, 35 insertions(+) create mode 100644 test/lit/emit-module-names.wast diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp index 9bdfa4b06f7..7e363e2b21d 100644 --- a/src/tools/wasm-opt.cpp +++ b/src/tools/wasm-opt.cpp @@ -95,6 +95,7 @@ int main(int argc, const char* argv[]) { std::string outputSourceMapFilename; std::string outputSourceMapUrl; bool emitExnref = false; + bool emitModuleNames = false; const std::string WasmOptOption = "wasm-opt options"; @@ -269,6 +270,15 @@ For more on how to optimize effectively, see [&outputSourceMapUrl](Options* o, const std::string& argument) { outputSourceMapUrl = argument; }) + .add( + "--emit-module-names", + "", + "Emit module names, even if not emitting the rest of the names section", + WasmOptOption, + Options::Arguments::Zero, + [&emitModuleNames](Options*, const std::string&) { + emitModuleNames = true; + }) .add_positional("INFILE", Options::Arguments::One, [](Options* o, const std::string& argument) { @@ -407,6 +417,9 @@ For more on how to optimize effectively, see ModuleWriter writer(options.passOptions); writer.setBinary(emitBinary); writer.setDebugInfo(options.passOptions.debugInfo); + if (emitModuleNames) { + writer.setEmitModuleName(true); + } writer.write(wasm, options.extra["output"]); firstOutput = runCommand(extraFuzzCommand); std::cout << "[extra-fuzz-command first output:]\n" << firstOutput << '\n'; @@ -496,6 +509,9 @@ For more on how to optimize effectively, see ModuleWriter writer(options.passOptions); writer.setBinary(emitBinary); writer.setDebugInfo(options.passOptions.debugInfo); + if (emitModuleNames) { + writer.setEmitModuleName(true); + } if (outputSourceMapFilename.size()) { writer.setSourceMapFilename(outputSourceMapFilename); writer.setSourceMapUrl(outputSourceMapUrl); diff --git a/test/lit/emit-module-names.wast b/test/lit/emit-module-names.wast new file mode 100644 index 00000000000..8849d383636 --- /dev/null +++ b/test/lit/emit-module-names.wast @@ -0,0 +1,15 @@ +;; Check that --emit-module-names without -g strips function names but generates +;; and keeps the module name. + +;; RUN: wasm-opt %s --emit-module-names -o %t.wasm +;; RUN: wasm-dis %t.wasm -o - | filecheck %s + +;; CHECK: (module $module-name +;; CHECK: (func $0 +;; CHECK-NOT: $foo + +(module $module-name + (func $foo + (nop) + ) +) diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test index 4dec96a4104..afe7bb209de 100644 --- a/test/lit/help/wasm-opt.test +++ b/test/lit/help/wasm-opt.test @@ -98,6 +98,10 @@ ;; CHECK-NEXT: --output-source-map-url,-osu Emit specified string as source ;; CHECK-NEXT: map URL ;; CHECK-NEXT: +;; CHECK-NEXT: --emit-module-names Emit module names, even if not +;; CHECK-NEXT: emitting the rest of the names +;; CHECK-NEXT: section +;; CHECK-NEXT: ;; CHECK-NEXT: --experimental-new-eh Deprecated; same as ;; CHECK-NEXT: --emit-exnref ;; CHECK-NEXT: