Skip to content

Commit 6896d05

Browse files
authored
[Parser] Propagate debug locations like the old parser (#6377)
Add a pass that propagates debug locations to unannotated child and sibling expressions after parsing. The new parser on its own only attaches debug locations to directly annotated instructions, but this pass, which we run unconditionally, emulates the behavior of the previous parser for compatibility with existing programs. It does unintuitive things to programs using the non-nested format because it runs on nested Binaryen IR, so we may want to rethink this at some point.
1 parent 00ed411 commit 6896d05

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

src/parser/wat-parser.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "ir/names.h"
2020
#include "lexer.h"
2121
#include "parsers.h"
22+
#include "pass.h"
2223
#include "wasm-type.h"
2324
#include "wasm.h"
2425

@@ -90,6 +91,58 @@ Result<> parseDefs(Ctx& ctx,
9091
return Ok{};
9192
}
9293

94+
void propagateDebugLocations(Module& wasm) {
95+
// Copy debug locations from parents or previous siblings to expressions that
96+
// do not already have their own debug locations.
97+
struct Propagator : WalkerPass<ExpressionStackWalker<Propagator>> {
98+
using Super = WalkerPass<ExpressionStackWalker<Propagator>>;
99+
bool isFunctionParallel() override { return true; }
100+
bool modifiesBinaryenIR() override { return false; }
101+
bool requiresNonNullableLocalFixups() override { return false; }
102+
void runOnFunction(Module* module, Function* func) override {
103+
if (!func->debugLocations.empty()) {
104+
Super::runOnFunction(module, func);
105+
}
106+
}
107+
108+
// Unannotated instructions inherit either their previous sibling's location
109+
// or their parent's location. Look up whichever is current for a given
110+
// parent.
111+
std::unordered_map<Expression*, Function::DebugLocation> parentDefaults;
112+
113+
static void doPreVisit(Propagator* self, Expression** currp) {
114+
Super::doPreVisit(self, currp);
115+
auto* curr = *currp;
116+
auto& locs = self->getFunction()->debugLocations;
117+
auto& parentDefaults = self->parentDefaults;
118+
if (auto it = locs.find(curr); it != locs.end()) {
119+
// Children will inherit this location.
120+
parentDefaults[curr] = it->second;
121+
if (auto* parent = self->getParent()) {
122+
// Subsequent siblings will inherit this location.
123+
parentDefaults[parent] = it->second;
124+
}
125+
} else {
126+
// No annotation, see if we should inherit one.
127+
if (auto* parent = self->getParent()) {
128+
if (auto defaultIt = parentDefaults.find(parent);
129+
defaultIt != parentDefaults.end()) {
130+
// We have a default to inherit. Our children will inherit it, too.
131+
locs[curr] = parentDefaults[curr] = defaultIt->second;
132+
}
133+
}
134+
}
135+
}
136+
137+
std::unique_ptr<Pass> create() override {
138+
return std::make_unique<Propagator>();
139+
}
140+
};
141+
PassRunner runner(&wasm);
142+
runner.add(std::make_unique<Propagator>());
143+
runner.run();
144+
}
145+
93146
// ================
94147
// Parser Functions
95148
// ================
@@ -212,6 +265,8 @@ Result<> parseModule(Module& wasm, std::string_view input) {
212265
}
213266
}
214267

268+
propagateDebugLocations(wasm);
269+
215270
return Ok{};
216271
}
217272

test/lit/wat-kitchen-sink.wast

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5192,6 +5192,32 @@
51925192
end
51935193
)
51945194

5195+
;; CHECK: (func $source-map-propagation (type $void)
5196+
;; CHECK-NEXT: ;;@ src.cpp:20:1
5197+
;; CHECK-NEXT: (drop
5198+
;; CHECK-NEXT: (i32.add
5199+
;; CHECK-NEXT: ;;@ src.cpp:10:1
5200+
;; CHECK-NEXT: (i32.const 0)
5201+
;; CHECK-NEXT: ;;@ src.cpp:10:1
5202+
;; CHECK-NEXT: (i32.const 1)
5203+
;; CHECK-NEXT: )
5204+
;; CHECK-NEXT: )
5205+
;; CHECK-NEXT: ;;@ src.cpp:20:1
5206+
;; CHECK-NEXT: (drop
5207+
;; CHECK-NEXT: (i32.const 2)
5208+
;; CHECK-NEXT: )
5209+
;; CHECK-NEXT: )
5210+
(func $source-map-propagation
5211+
;;@ src.cpp:10:1
5212+
i32.const 0
5213+
i32.const 1
5214+
i32.add
5215+
;;@ src.cpp:20:1
5216+
drop
5217+
i32.const 2
5218+
drop
5219+
)
5220+
51955221
;; CHECK: (func $use-types (type $104) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) (param $15 (ref $all-types))
51965222
;; CHECK-NEXT: (nop)
51975223
;; CHECK-NEXT: )

0 commit comments

Comments
 (0)