Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,13 @@

#include <algorithm>
#include <fstream>
#include <iomanip>

#include "ir/eh-utils.h"
#include "ir/module-utils.h"
#include "ir/names.h"
#include "ir/table-utils.h"
#include "ir/type-updating.h"
#include "pass.h"
#include "support/bits.h"
#include "support/debug.h"
#include "support/stdckdint.h"
#include "support/string.h"
#include "wasm-annotations.h"
Expand Down Expand Up @@ -1242,6 +1239,43 @@ void WasmBinaryWriter::writeSourceMapProlog() {
}
}

// Remove unused function names from 'names' field.
if (!wasm->debugInfoSymbolNames.empty()) {
std::vector<std::string> newSymbolNames;
std::map<Index, Index> oldToNewIndex;

// Collect all used symbol name indexes.
for (auto& func : wasm->functions) {
for (auto& [_, location] : func->debugLocations) {
if (location && location->symbolNameIndex) {
uint32_t oldIndex = *location->symbolNameIndex;
assert(oldIndex < wasm->debugInfoSymbolNames.size());
oldToNewIndex[oldIndex] = 0; // placeholder
}
}
}

// Create the new list of names and the mapping from old to new indices.
uint32_t index = 0;
for (auto& [oldIndex, newIndex] : oldToNewIndex) {
newSymbolNames.push_back(wasm->debugInfoSymbolNames[oldIndex]);
newIndex = index++;
}

// Update all debug locations to point to the new indices.
for (auto& func : wasm->functions) {
for (auto& [_, location] : func->debugLocations) {
if (location && location->symbolNameIndex) {
uint32_t oldIndex = *location->symbolNameIndex;
location->symbolNameIndex = oldToNewIndex[oldIndex];
}
}
}

// Replace the old symbol names with the new, pruned list.
wasm->debugInfoSymbolNames = std::move(newSymbolNames);
}

auto writeOptionalString = [&](const char* name, const std::string& str) {
if (!str.empty()) {
*sourceMap << "\"" << name << "\":\"" << str << "\",";
Expand Down Expand Up @@ -1269,10 +1303,6 @@ void WasmBinaryWriter::writeSourceMapProlog() {
writeStringVector("sourcesContent", wasm->debugInfoSourcesContent);
}

// TODO: This field is optional; maybe we should omit if it's empty.
// TODO: Binaryen actually does not correctly preserve symbol names when it
// rewrites the mappings. We should maybe just drop them, or else handle
// them correctly.
writeStringVector("names", wasm->debugInfoSymbolNames);

*sourceMap << "\"mappings\":\"";
Expand Down
32 changes: 32 additions & 0 deletions test/lit/source-map-names.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
;; RUN: wasm-opt %s --remove-unused-module-elements -o %t.wasm -osm %t.map
;; RUN: wasm-dis %t.wasm --source-map %t.map | filecheck %s --check-prefix OUT-WAST
;; RUN: cat %t.map | filecheck %s --check-prefix OUT-MAP

;; After --remove-unused-module-elements, the output source map's 'names' field
;; should NOT contain 'unused'

;; OUT-MAP: "names":["used","used2"]

(module
(export "used" (func $used))
(export "used2" (func $used2))

(func $unused
;;@ src.cpp:1:1:unused
(nop)
)

(func $used
;; OUT-WAST: ;;@ src.cpp:2:1:used
;; OUT-WAST-NEXT: (nop)
;;@ src.cpp:2:1:used
(nop)
)

(func $used2
;; OUT-WAST: ;;@ src.cpp:3:1:used
;; OUT-WAST-NEXT: (nop)
;;@ src.cpp:3:1:used2
(nop)
)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps add another used symbol, to get some coverage of the order of the symbols being deterministic? (not great coverage, but it might help)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: a55a844

Loading