|
15 | 15 | */ |
16 | 16 |
|
17 | 17 | #include "module-utils.h" |
| 18 | +#include "ir/debug.h" |
18 | 19 | #include "ir/intrinsics.h" |
19 | 20 | #include "ir/manipulation.h" |
20 | 21 | #include "ir/properties.h" |
|
23 | 24 |
|
24 | 25 | namespace wasm::ModuleUtils { |
25 | 26 |
|
| 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 | + |
26 | 39 | // 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) { |
29 | 47 | auto ret = std::make_unique<Function>(); |
30 | 48 | ret->name = newName.is() ? newName : func->name; |
31 | 49 | ret->type = func->type; |
32 | 50 | ret->vars = func->vars; |
33 | 51 | ret->localNames = func->localNames; |
34 | 52 | ret->localIndices = func->localIndices; |
35 | | - ret->debugLocations = func->debugLocations; |
36 | 53 | 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 | + } |
37 | 67 | ret->module = func->module; |
38 | 68 | ret->base = func->base; |
39 | 69 | ret->noFullInline = func->noFullInline; |
@@ -135,9 +165,13 @@ DataSegment* copyDataSegment(const DataSegment* segment, Module& out) { |
135 | 165 |
|
136 | 166 | // Copies named toplevel module items (things of kind ModuleItemKind). See |
137 | 167 | // 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) { |
139 | 173 | for (auto& curr : in.functions) { |
140 | | - copyFunction(curr.get(), out); |
| 174 | + copyFunction(curr.get(), out, Name(), indexMap); |
141 | 175 | } |
142 | 176 | for (auto& curr : in.globals) { |
143 | 177 | copyGlobal(curr.get(), out); |
|
0 commit comments