@@ -565,14 +565,20 @@ void WasmBinaryWriter::writeUserSection(const UserSection& section) {
565565 finishSection (start);
566566}
567567
568+ void WasmBinaryWriter::writeDebugLocation (const Function::DebugLocation& loc) {
569+ if (loc == lastDebugLocation) {
570+ return ;
571+ }
572+ auto offset = o.size ();
573+ sourceMapLocations.emplace_back (offset, &loc);
574+ lastDebugLocation = loc;
575+ }
576+
568577void WasmBinaryWriter::writeDebugLocation (Expression* curr, Function* func) {
569578 auto & debugLocations = func->debugLocations ;
570579 auto iter = debugLocations.find (curr);
571- if (iter != debugLocations.end () && iter->second != lastDebugLocation) {
572- auto offset = o.size ();
573- auto & loc = iter->second ;
574- sourceMapLocations.emplace_back (offset, &loc);
575- lastDebugLocation = loc;
580+ if (iter != debugLocations.end ()) {
581+ writeDebugLocation (iter->second );
576582 }
577583}
578584
@@ -1058,11 +1064,19 @@ void WasmBinaryBuilder::readFunctions() {
10581064 throwError (" empty function size" );
10591065 }
10601066 endOfFunction = pos + size;
1067+
1068+ Function *func = new Function;
1069+ func->name = Name::fromInt (i);
1070+ currFunction = func;
1071+
1072+ readNextDebugLocation ();
1073+
10611074 auto type = functionTypes[i];
10621075 if (debug) std::cerr << " reading " << i << std::endl;
1063- std::vector<Type> params, vars;
1076+ func->type = type->name ;
1077+ func->result = type->result ;
10641078 for (size_t j = 0 ; j < type->params .size (); j++) {
1065- params.emplace_back (type->params [j]);
1079+ func-> params .emplace_back (type->params [j]);
10661080 }
10671081 size_t numLocalTypes = getU32LEB ();
10681082 for (size_t t = 0 ; t < numLocalTypes; t++) {
@@ -1077,23 +1091,16 @@ void WasmBinaryBuilder::readFunctions() {
10771091 throwError (" too many locals, wasm VMs would not accept this binary" );
10781092 }
10791093 while (num > 0 ) {
1080- vars.emplace_back (type);
1094+ func-> vars .push_back (type);
10811095 num--;
10821096 }
10831097 }
1084- auto func = Builder (wasm).makeFunction (
1085- Name::fromInt (i),
1086- std::move (params),
1087- type->result ,
1088- std::move (vars)
1089- );
1090- func->type = type->name ;
1091- currFunction = func;
1098+ std::swap (func->prologLocation , debugLocation);
10921099 {
10931100 // process the function body
10941101 if (debug) std::cerr << " processing function: " << i << std::endl;
10951102 nextLabel = 0 ;
1096- useDebugLocation = false ;
1103+ debugLocation. clear () ;
10971104 willBeIgnored = false ;
10981105 // process body
10991106 assert (breakTargetNames.size () == 0 );
@@ -1111,8 +1118,9 @@ void WasmBinaryBuilder::readFunctions() {
11111118 throwError (" binary offset at function exit not at expected location" );
11121119 }
11131120 }
1121+ std::swap (func->epilogLocation , debugLocation);
11141122 currFunction = nullptr ;
1115- useDebugLocation = false ;
1123+ debugLocation. clear () ;
11161124 functions.push_back (func);
11171125 }
11181126 if (debug) std::cerr << " end function bodies" << std::endl;
@@ -1268,26 +1276,38 @@ void WasmBinaryBuilder::readSourceMapHeader() {
12681276void WasmBinaryBuilder::readNextDebugLocation () {
12691277 if (!sourceMap) return ;
12701278
1271- char ch;
1272- *sourceMap >> ch;
1273- if (ch == ' \" ' ) { // end of records
1274- nextDebugLocation.first = 0 ;
1275- return ;
1276- }
1277- if (ch != ' ,' ) {
1278- throw MapParseException (" Unexpected delimiter" );
1279- }
1279+ while (nextDebugLocation.first && nextDebugLocation.first <= pos) {
1280+ if (nextDebugLocation.first < pos) {
1281+ std::cerr << " skipping debug location info for 0x" ;
1282+ std::cerr << std::hex << nextDebugLocation.first << std::dec << std::endl;
1283+ }
1284+ debugLocation.clear ();
1285+ // use debugLocation only for function expressions
1286+ if (currFunction) {
1287+ debugLocation.insert (nextDebugLocation.second );
1288+ }
12801289
1281- int32_t positionDelta = readBase64VLQ (*sourceMap);
1282- uint32_t position = nextDebugLocation.first + positionDelta;
1283- int32_t fileIndexDelta = readBase64VLQ (*sourceMap);
1284- uint32_t fileIndex = nextDebugLocation.second .fileIndex + fileIndexDelta;
1285- int32_t lineNumberDelta = readBase64VLQ (*sourceMap);
1286- uint32_t lineNumber = nextDebugLocation.second .lineNumber + lineNumberDelta;
1287- int32_t columnNumberDelta = readBase64VLQ (*sourceMap);
1288- uint32_t columnNumber = nextDebugLocation.second .columnNumber + columnNumberDelta;
1290+ char ch;
1291+ *sourceMap >> ch;
1292+ if (ch == ' \" ' ) { // end of records
1293+ nextDebugLocation.first = 0 ;
1294+ break ;
1295+ }
1296+ if (ch != ' ,' ) {
1297+ throw MapParseException (" Unexpected delimiter" );
1298+ }
12891299
1290- nextDebugLocation = { position, { fileIndex, lineNumber, columnNumber } };
1300+ int32_t positionDelta = readBase64VLQ (*sourceMap);
1301+ uint32_t position = nextDebugLocation.first + positionDelta;
1302+ int32_t fileIndexDelta = readBase64VLQ (*sourceMap);
1303+ uint32_t fileIndex = nextDebugLocation.second .fileIndex + fileIndexDelta;
1304+ int32_t lineNumberDelta = readBase64VLQ (*sourceMap);
1305+ uint32_t lineNumber = nextDebugLocation.second .lineNumber + lineNumberDelta;
1306+ int32_t columnNumberDelta = readBase64VLQ (*sourceMap);
1307+ uint32_t columnNumber = nextDebugLocation.second .columnNumber + columnNumberDelta;
1308+
1309+ nextDebugLocation = { position, { fileIndex, lineNumber, columnNumber } };
1310+ }
12911311}
12921312
12931313Expression* WasmBinaryBuilder::readExpression () {
@@ -1345,6 +1365,7 @@ void WasmBinaryBuilder::processExpressions() {
13451365 auto peek = input[pos];
13461366 if (peek == BinaryConsts::End || peek == BinaryConsts::Else) {
13471367 if (debug) std::cerr << " == processExpressions finished with unreachable" << std::endl;
1368+ readNextDebugLocation ();
13481369 lastSeparator = BinaryConsts::ASTNodes (peek);
13491370 pos++;
13501371 return ;
@@ -1654,15 +1675,10 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
16541675 throwError (" Reached function end without seeing End opcode" );
16551676 }
16561677 if (debug) std::cerr << " zz recurse into " << ++depth << " at " << pos << std::endl;
1657- if (nextDebugLocation.first ) {
1658- while (nextDebugLocation.first && nextDebugLocation.first <= pos) {
1659- if (nextDebugLocation.first < pos) {
1660- std::cerr << " skipping debug location info for " << nextDebugLocation.first << std::endl;
1661- }
1662- debugLocation = nextDebugLocation.second ;
1663- useDebugLocation = currFunction != NULL ; // using only for function expressions
1664- readNextDebugLocation ();
1665- }
1678+ readNextDebugLocation ();
1679+ std::set<Function::DebugLocation> currDebugLocation;
1680+ if (debugLocation.size ()) {
1681+ currDebugLocation.insert (*debugLocation.begin ());
16661682 }
16671683 uint8_t code = getInt8 ();
16681684 if (debug) std::cerr << " readExpression seeing " << (int )code << std::endl;
@@ -1710,8 +1726,8 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
17101726 break ;
17111727 }
17121728 }
1713- if (useDebugLocation && curr ) {
1714- currFunction->debugLocations [curr] = debugLocation ;
1729+ if (curr && currDebugLocation. size () ) {
1730+ currFunction->debugLocations [curr] = *currDebugLocation. begin () ;
17151731 }
17161732 if (debug) std::cerr << " zz recurse from " << depth-- << " at " << pos << std::endl;
17171733 return BinaryConsts::ASTNodes (code);
@@ -1764,13 +1780,18 @@ void WasmBinaryBuilder::visitBlock(Block* curr) {
17641780 curr->name = getNextLabel ();
17651781 breakStack.push_back ({curr->name , curr->type != none});
17661782 stack.push_back (curr);
1767- if (getInt8 () == BinaryConsts::Block) {
1783+ auto peek = input[pos];
1784+ if (peek == BinaryConsts::Block) {
17681785 // a recursion
1786+ readNextDebugLocation ();
17691787 curr = allocator.alloc <Block>();
1788+ pos++;
1789+ if (debugLocation.size ()) {
1790+ currFunction->debugLocations [curr] = *debugLocation.begin ();
1791+ }
17701792 continue ;
17711793 } else {
17721794 // end of recursion
1773- ungetInt8 ();
17741795 break ;
17751796 }
17761797 }
0 commit comments