Skip to content

Commit 5a3caa4

Browse files
committed
wasm-merge: copy sourcemap information
1 parent 18b2d63 commit 5a3caa4

File tree

3 files changed

+70
-10
lines changed

3 files changed

+70
-10
lines changed

src/ir/module-utils.cpp

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include "module-utils.h"
18+
#include "ir/debug.h"
1819
#include "ir/intrinsics.h"
1920
#include "ir/manipulation.h"
2021
#include "ir/properties.h"
@@ -23,17 +24,46 @@
2324

2425
namespace wasm::ModuleUtils {
2526

27+
static void updateLocationSet(std::set<Function::DebugLocation>& locations,
28+
std::vector<Index>* indexMap) {
29+
std::set<Function::DebugLocation> updatedLocations;
30+
31+
for (auto iter : locations) {
32+
iter.fileIndex = (*indexMap)[iter.fileIndex];
33+
updatedLocations.insert(iter);
34+
}
35+
locations.clear();
36+
std::swap(locations, updatedLocations);
37+
}
38+
2639
// Copies a function into a module. If newName is provided it is used as the
27-
// name of the function (otherwise the original name is copied).
28-
Function* copyFunction(Function* func, Module& out, Name newName) {
40+
// name of the function (otherwise the original name is copied). If indexMap is
41+
// specified, it is used to rename source map filename indices when copying the
42+
// function from one module to another one.
43+
Function* copyFunction(Function* func,
44+
Module& out,
45+
Name newName,
46+
std::vector<Index>* indexMap) {
2947
auto ret = std::make_unique<Function>();
3048
ret->name = newName.is() ? newName : func->name;
3149
ret->type = func->type;
3250
ret->vars = func->vars;
3351
ret->localNames = func->localNames;
3452
ret->localIndices = func->localIndices;
35-
ret->debugLocations = func->debugLocations;
3653
ret->body = ExpressionManipulator::copy(func->body, out);
54+
if (ret->body) {
55+
debug::copyDebugInfo(func->body, ret->body, func, ret.get());
56+
}
57+
ret->prologLocation = func->prologLocation;
58+
ret->epilogLocation = func->epilogLocation;
59+
// Update file indices if needed
60+
if (indexMap) {
61+
for (auto& iter : ret->debugLocations) {
62+
iter.second.fileIndex = (*indexMap)[iter.second.fileIndex];
63+
}
64+
updateLocationSet(ret->prologLocation, indexMap);
65+
updateLocationSet(ret->epilogLocation, indexMap);
66+
}
3767
ret->module = func->module;
3868
ret->base = func->base;
3969
ret->noFullInline = func->noFullInline;
@@ -135,9 +165,13 @@ DataSegment* copyDataSegment(const DataSegment* segment, Module& out) {
135165

136166
// Copies named toplevel module items (things of kind ModuleItemKind). See
137167
// copyModule() for something that also copies exports, the start function, etc.
138-
void copyModuleItems(const Module& in, Module& out) {
168+
// The indexMap is used to update source map information when copying functions
169+
// from one module to another.
170+
void copyModuleItems(const Module& in,
171+
Module& out,
172+
std::vector<Index>* indexMap) {
139173
for (auto& curr : in.functions) {
140-
copyFunction(curr.get(), out);
174+
copyFunction(curr.get(), out, Name(), indexMap);
141175
}
142176
for (auto& curr : in.globals) {
143177
copyGlobal(curr.get(), out);

src/ir/module-utils.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@
2424
namespace wasm::ModuleUtils {
2525

2626
// Copies a function into a module. If newName is provided it is used as the
27-
// name of the function (otherwise the original name is copied).
28-
Function* copyFunction(Function* func, Module& out, Name newName = Name());
27+
// name of the function (otherwise the original name is copied). If indexMap is
28+
// specified, it is used to rename source map filename indices when copying the
29+
// function from one module to another one.
30+
Function* copyFunction(Function* func,
31+
Module& out,
32+
Name newName = Name(),
33+
std::vector<Index>* indexMap = 0);
2934

3035
Global* copyGlobal(Global* global, Module& out);
3136

@@ -41,7 +46,11 @@ DataSegment* copyDataSegment(const DataSegment* segment, Module& out);
4146

4247
// Copies named toplevel module items (things of kind ModuleItemKind). See
4348
// copyModule() for something that also copies exports, the start function, etc.
44-
void copyModuleItems(const Module& in, Module& out);
49+
// The indexMap is used to update source map information when copying functions
50+
// from one module to another.
51+
void copyModuleItems(const Module& in,
52+
Module& out,
53+
std::vector<Index>* indexMap = 0);
4554

4655
void copyModule(const Module& in, Module& out);
4756

src/tools/wasm-merge.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,26 @@ void renameInputItems(Module& input) {
324324
}
325325

326326
void copyModuleContents(Module& input, Name inputName) {
327-
// First, copy the regular module items (functions, globals) etc. which we
327+
// Source map filename index mapping
328+
std::vector<Index> indexMap;
329+
std::unordered_map<std::string, Index> debugInfoFileIndices;
330+
for (Index i = 0; i < merged.debugInfoFileNames.size(); i++) {
331+
debugInfoFileIndices[merged.debugInfoFileNames[i]] = i;
332+
}
333+
for (Index i = 0; i < input.debugInfoFileNames.size(); i++) {
334+
std::string file = input.debugInfoFileNames[i];
335+
auto iter = debugInfoFileIndices.find(file);
336+
if (iter == debugInfoFileIndices.end()) {
337+
Index index = merged.debugInfoFileNames.size();
338+
merged.debugInfoFileNames.push_back(file);
339+
debugInfoFileIndices[file] = index;
340+
}
341+
indexMap.push_back(debugInfoFileIndices[file]);
342+
}
343+
344+
// Copy the regular module items (functions, globals) etc. which we
328345
// have proper names for, and can just copy.
329-
ModuleUtils::copyModuleItems(input, merged);
346+
ModuleUtils::copyModuleItems(input, merged, &indexMap);
330347

331348
// We must handle exports in a special way, as we need to note their origin
332349
// module as we copy them in (also, they are not importable or exportable, so

0 commit comments

Comments
 (0)