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,10 @@ class BinaryenIRWriter : public Visitor<BinaryenIRWriter<SubType>> {
168172
169173protected:
170174 Function* func = nullptr ;
175+ Function::DebugLocation lastDebugLocation; // /< last debug location
176+ uint32_t lastDebugLocationDepth =
177+ static_cast <uint32_t >(-1 ); // /< last debug location depth
178+ uint32_t depth = 0U ; // /< depth of current write cursor
171179
172180private:
173181 void emit (Expression* curr) { static_cast <SubType*>(this )->emit (curr); }
@@ -239,6 +247,7 @@ void BinaryenIRWriter<SubType>::visit(Expression* curr) {
239247 // unreachable block is a source of unreachability, which means we don't need
240248 // to emit an extra `unreachable` before the end of the block to prevent type
241249 // errors.
250+ depth++;
242251 bool hasUnreachableChild = false ;
243252 for (auto * child : ValueChildIterator (curr)) {
244253 visit (child);
@@ -251,7 +260,22 @@ void BinaryenIRWriter<SubType>::visit(Expression* curr) {
251260 // `curr` is not reachable, so don't emit it.
252261 return ;
253262 }
254- emitDebugLocation (curr);
263+
264+ if (func != nullptr ) {
265+ const auto & debugLocationIterator = func->debugLocations .find (curr);
266+ if (debugLocationIterator != func->debugLocations .cend ()) {
267+ if (lastDebugLocation != debugLocationIterator->second ||
268+ depth < lastDebugLocationDepth) {
269+ emitDebugLocation (curr);
270+ lastDebugLocationDepth = depth;
271+ lastDebugLocation = debugLocationIterator->second ;
272+ }
273+ }
274+ } else {
275+ emitDebugLocation (
276+ curr); // for global expression write, no func value, directly write it
277+ }
278+ depth--;
255279 // Control flow requires special handling, but most instructions can be
256280 // emitted directly after their children.
257281 if (Properties::isControlFlowStructure (curr)) {
0 commit comments