2424#include " wasm-binary.h"
2525#include " wasm-traversal.h"
2626#include " wasm.h"
27+ #include < cstdint>
2728
2829namespace wasm {
2930
@@ -154,7 +155,10 @@ class BinaryInstWriter : public OverriddenVisitor<BinaryInstWriter> {
154155template <typename SubType>
155156class BinaryenIRWriter : public Visitor <BinaryenIRWriter<SubType>> {
156157public:
157- BinaryenIRWriter (Function* func) : func(func) {}
158+ BinaryenIRWriter (Function* func)
159+ : func(func), lastDebugLocation({static_cast <uint32_t >(-1 ),
160+ static_cast <uint32_t >(-1 ),
161+ static_cast <uint32_t >(-1 )}) {}
158162
159163 void write ();
160164
@@ -168,6 +172,9 @@ class BinaryenIRWriter : public Visitor<BinaryenIRWriter<SubType>> {
168172
169173protected:
170174 Function* func = nullptr ;
175+ Function::DebugLocation lastDebugLocation; // /< last debug location
176+ uint32_t lastDebugLocationDepth = static_cast <uint32_t >(-1 ); // /< last debug location depth
177+ uint32_t depth = 0U ; // /< depth of current write cursor
171178
172179private:
173180 void emit (Expression* curr) { static_cast <SubType*>(this )->emit (curr); }
@@ -239,6 +246,7 @@ void BinaryenIRWriter<SubType>::visit(Expression* curr) {
239246 // unreachable block is a source of unreachability, which means we don't need
240247 // to emit an extra `unreachable` before the end of the block to prevent type
241248 // errors.
249+ depth++;
242250 bool hasUnreachableChild = false ;
243251 for (auto * child : ValueChildIterator (curr)) {
244252 visit (child);
@@ -251,14 +259,28 @@ void BinaryenIRWriter<SubType>::visit(Expression* curr) {
251259 // `curr` is not reachable, so don't emit it.
252260 return ;
253261 }
254- emitDebugLocation (curr);
262+
263+ if (func != nullptr ) {
264+ const auto & debugLocationIterator = func->debugLocations .find (curr);
265+ if (debugLocationIterator != func->debugLocations .cend ()) {
266+ if (lastDebugLocation != debugLocationIterator->second || depth < lastDebugLocationDepth) {
267+ emitDebugLocation (curr);
268+ lastDebugLocationDepth = depth;
269+ lastDebugLocation = debugLocationIterator->second ;
270+ }
271+ }
272+ } else {
273+ emitDebugLocation (curr); // for global expression write, no func value, directly write it
274+ }
275+ depth--;
255276 // Control flow requires special handling, but most instructions can be
256277 // emitted directly after their children.
257278 if (Properties::isControlFlowStructure (curr)) {
258279 Visitor<BinaryenIRWriter>::visit (curr);
259280 } else {
260281 emit (curr);
261282 }
283+
262284}
263285
264286template <typename SubType>
0 commit comments