summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wasm-binary.h24
-rw-r--r--src/wasm/wasm-binary.cpp65
2 files changed, 75 insertions, 14 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index a384d2cd5..0931a8180 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1490,8 +1490,11 @@ private:
MixedArena allocator;
- // storage of source map locations until the section is placed at its final
- // location (shrinking LEBs may cause changes there)
+ // Storage of source map locations until the section is placed at its final
+ // location (shrinking LEBs may cause changes there).
+ //
+ // A null DebugLocation* indicates we have no debug information for that
+ // location.
std::vector<std::pair<size_t, const Function::DebugLocation*>>
sourceMapLocations;
size_t sourceMapLocationsSizeAtSectionStart;
@@ -1522,13 +1525,26 @@ class WasmBinaryReader {
Module& wasm;
MixedArena& allocator;
const std::vector<char>& input;
+
std::istream* sourceMap;
+
struct NextDebugLocation {
uint32_t availablePos;
uint32_t previousPos;
Function::DebugLocation next;
- };
- NextDebugLocation nextDebugLocation;
+ } nextDebugLocation;
+
+ // Whether debug info is present next or not in the next debug location. A
+ // debug location can contain debug info (file:line:col) or it might not. We
+ // need to track this boolean alongside |nextDebugLocation| - that is, we
+ // can't just do something like std::optional<DebugLocation> or such - as we
+ // still need to track the values in |next|, as later positions are relative
+ // to them. That is, if we have line number 100, then no debug info, and then
+ // line number 500, then when we get to 500 we will see "+400" which is
+ // relative to the last existing line number (we "skip" over the place without
+ // debug info).
+ bool nextDebugLocationHasDebugInfo;
+
bool debugInfo = true;
bool DWARF = false;
bool skipFunctionBodies = false;
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 556f52157..d6eb3b235 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1186,12 +1186,16 @@ void WasmBinaryWriter::writeSourceMapEpilog() {
*sourceMap << ",";
}
writeBase64VLQ(*sourceMap, int32_t(offset - lastOffset));
- writeBase64VLQ(*sourceMap, int32_t(loc->fileIndex - lastLoc.fileIndex));
- writeBase64VLQ(*sourceMap, int32_t(loc->lineNumber - lastLoc.lineNumber));
- writeBase64VLQ(*sourceMap,
- int32_t(loc->columnNumber - lastLoc.columnNumber));
- lastLoc = *loc;
lastOffset = offset;
+ if (loc) {
+ // There is debug information for this location, so emit the next 3
+ // fields and update lastLoc.
+ writeBase64VLQ(*sourceMap, int32_t(loc->fileIndex - lastLoc.fileIndex));
+ writeBase64VLQ(*sourceMap, int32_t(loc->lineNumber - lastLoc.lineNumber));
+ writeBase64VLQ(*sourceMap,
+ int32_t(loc->columnNumber - lastLoc.columnNumber));
+ lastLoc = *loc;
+ }
}
*sourceMap << "\"}";
}
@@ -1340,7 +1344,28 @@ void WasmBinaryWriter::writeDebugLocation(Expression* curr, Function* func) {
auto& debugLocations = func->debugLocations;
auto iter = debugLocations.find(curr);
if (iter != debugLocations.end()) {
+ // There is debug information here, write it out.
writeDebugLocation(iter->second);
+ } else {
+ // This expression has no debug location. We need to emit an indication
+ // of that (so that we do not get "smeared" with debug info from anything
+ // before or after us).
+ //
+ // We don't need to write repeated "no debug info" indications, as a
+ // single one is enough to make it clear that the debug information before
+ // us is valid no longer. We also don't need to write one if there is
+ // nothing before us.
+ if (!sourceMapLocations.empty() &&
+ sourceMapLocations.back().second != nullptr) {
+ sourceMapLocations.emplace_back(o.size(), nullptr);
+
+ // Initialize the state of debug info to indicate there is no current
+ // debug info relevant. This sets |lastDebugLocation| to a dummy value,
+ // so that later places with debug info can see that they differ from
+ // it (without this, if we had some debug info, then a nullptr for none,
+ // and then the same debug info, we could get confused).
+ initializeDebugInfo();
+ }
}
}
// If this is an instruction in a function, and if the original wasm had
@@ -1614,7 +1639,8 @@ WasmBinaryReader::WasmBinaryReader(Module& wasm,
FeatureSet features,
const std::vector<char>& input)
: wasm(wasm), allocator(wasm.allocator), input(input),
- sourceMap(nullptr), nextDebugLocation{0, 0, {0, 0, 0}}, debugLocation() {
+ sourceMap(nullptr), nextDebugLocation{0, 0, {0, 0, 0}},
+ nextDebugLocationHasDebugInfo(false), debugLocation() {
wasm.features = features;
}
@@ -2776,6 +2802,10 @@ void WasmBinaryReader::readSourceMapHeader() {
return;
}
// read first debug location
+ // TODO: Handle the case where the very first one has only a position but not
+ // debug info. In practice that does not happen, which needs
+ // investigation (if it does, it will assert in readBase64VLQ, so it
+ // would not be a silent error at least).
uint32_t position = readBase64VLQ(*sourceMap);
uint32_t fileIndex = readBase64VLQ(*sourceMap);
uint32_t lineNumber =
@@ -2783,6 +2813,7 @@ void WasmBinaryReader::readSourceMapHeader() {
uint32_t columnNumber = readBase64VLQ(*sourceMap);
nextDebugLocation = {
position, position, {fileIndex, lineNumber, columnNumber}};
+ nextDebugLocationHasDebugInfo = true;
}
void WasmBinaryReader::readNextDebugLocation() {
@@ -2803,7 +2834,11 @@ void WasmBinaryReader::readNextDebugLocation() {
debugLocation.clear();
// use debugLocation only for function expressions
if (currFunction) {
- debugLocation.insert(nextDebugLocation.next);
+ if (nextDebugLocationHasDebugInfo) {
+ debugLocation.insert(nextDebugLocation.next);
+ } else {
+ debugLocation.clear();
+ }
}
char ch;
@@ -2818,6 +2853,17 @@ void WasmBinaryReader::readNextDebugLocation() {
int32_t positionDelta = readBase64VLQ(*sourceMap);
uint32_t position = nextDebugLocation.availablePos + positionDelta;
+
+ nextDebugLocation.previousPos = nextDebugLocation.availablePos;
+ nextDebugLocation.availablePos = position;
+
+ auto peek = sourceMap->peek();
+ if (peek == ',' || peek == '\"') {
+ // This is a 1-length entry, so the next location has no debug info.
+ nextDebugLocationHasDebugInfo = false;
+ break;
+ }
+
int32_t fileIndexDelta = readBase64VLQ(*sourceMap);
uint32_t fileIndex = nextDebugLocation.next.fileIndex + fileIndexDelta;
int32_t lineNumberDelta = readBase64VLQ(*sourceMap);
@@ -2826,9 +2872,8 @@ void WasmBinaryReader::readNextDebugLocation() {
uint32_t columnNumber =
nextDebugLocation.next.columnNumber + columnNumberDelta;
- nextDebugLocation = {position,
- nextDebugLocation.availablePos,
- {fileIndex, lineNumber, columnNumber}};
+ nextDebugLocation.next = {fileIndex, lineNumber, columnNumber};
+ nextDebugLocationHasDebugInfo = true;
}
}