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
45 changes: 38 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,44 @@ void WasmBinaryWriter::writeSourceMapProlog() {
}
}

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

// Collect all used symbol name indexes.
for (auto& func : wasm->functions) {
for (auto& pair : func->debugLocations) {
if (pair.second && pair.second->symbolNameIndex) {
uint32_t oldIndex = *pair.second->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 newIndex = 0;
for (auto& pair : oldToNewIndex) {
// pair.first is the oldIndex
newSymbolNames.push_back(wasm->debugInfoSymbolNames[pair.first]);
pair.second = newIndex++; // update placeholder to new index
}

// Update all debug locations to point to the new indices.
for (auto& func : wasm->functions) {
for (auto& pair : func->debugLocations) {
if (pair.second && pair.second->symbolNameIndex) {
uint32_t oldIndex = *pair.second->symbolNameIndex;
pair.second->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 +1304,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
24 changes: 24 additions & 0 deletions test/lit/source-map-names.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
;; 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"]

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

(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)
)
)
Loading