Skip to content

Commit

Permalink
Recording all label and their sequence; also all debug sections.
Browse files Browse the repository at this point in the history
  • Loading branch information
yurydelendik committed Apr 20, 2016
1 parent 13e9da4 commit 310b759
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 34 deletions.
55 changes: 52 additions & 3 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ struct PrintSExpression : public Visitor<PrintSExpression> {

size_t lastDebugLocationId = 0;
std::vector<DebugLocation>* functionDebugLocations = nullptr;
size_t lastLabelId = 0;
std::vector<Name>* functionLabels = nullptr;

bool minify;
const char *maybeSpace;
Expand Down Expand Up @@ -79,8 +81,17 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}

void visit(Expression *curr) {
if (curr->debugLocationIndex != lastDebugLocationId) {
lastDebugLocationId = curr->debugLocationIndex;
if (curr->debugInfo.labelIndex != lastLabelId) {
lastLabelId = curr->debugInfo.labelIndex;
if (functionLabels) { // no labels -- skipping
const Name& labelName = (*functionLabels)[lastLabelId];
o << "(;!bookmark " << labelName.str << ";)";
o << maybeNewLine;
!minify && doIndent(o, indent);
}
}
if (curr->debugInfo.locationIndex != lastDebugLocationId) {
lastDebugLocationId = curr->debugInfo.locationIndex;
// skipping location id 0 or debug information is absent
if (functionDebugLocations && lastDebugLocationId) {
const DebugLocation& debugLocation = (*functionDebugLocations)[lastDebugLocationId];
Expand All @@ -91,7 +102,8 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
Visitor<PrintSExpression>::visit(curr);
// keeping previously set location for next siblings
lastDebugLocationId = curr->debugLocationIndex;
lastDebugLocationId = curr->debugInfo.locationIndex;
lastLabelId = curr->debugInfo.labelIndex;
}

void visitBlock(Block *curr) {
Expand Down Expand Up @@ -456,6 +468,10 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
currFunction = curr;
printOpening(o, "func ", true) << curr->name;
functionDebugLocations = &(curr->debugLocations);
lastDebugLocationId = 0;
functionLabels = &(curr->labels);
lastLabelId = 0;

if (curr->type.is()) {
o << maybeSpace << "(type " << curr->type << ')';
}
Expand All @@ -475,6 +491,12 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
printMinorOpening(o, "local ") << printableLocal(i) << ' ' << printWasmType(curr->getLocalType(i)) << ")";
o << maybeNewLine;
}
if (functionLabels) { // no labels -- skipping
const Name& labelName = (*functionLabels)[0]; // first label is normally a function name
doIndent(o, indent);
o << "(;!bookmark " << labelName.str << ";)";
o << maybeNewLine;
}
// It is ok to emit a block here, as a function can directly contain a list, even if our
// ast avoids that for simplicity. We can just do that optimization here..
if (!fullAST && curr->body->is<Block>() && curr->body->cast<Block>()->name.isNull()) {
Expand All @@ -494,6 +516,32 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
o << ')';
}
void printDebugSections(Module *curr) {
bool hasSequences = false;
for (auto& child : curr->functions) {
if (child->labels.size() > 0) {
hasSequences = true;
}
}
if (hasSequences) {
doIndent(o, indent);
o << "(;!dbg_section .label_sequences\n";
for (auto& child : curr->functions) {
o << "\t.function";
for (auto item : child->labels) {
o << " " << item.str;
}
o << '\n';
}
o << ";)";
o << maybeNewLine;
}
for (auto& child : curr->debugSections) {
doIndent(o, indent);
o << "(;!dbg_section " << child.c_str() << ";)";
o << maybeNewLine;
}
}
void visitModule(Module *curr) {
printOpening(o, "module", true);
incIndent();
Expand Down Expand Up @@ -570,6 +618,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
visitFunction(child);
o << maybeNewLine;
}
printDebugSections(curr);
decIndent();
o << maybeNewLine;
}
Expand Down
72 changes: 44 additions & 28 deletions src/s2wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,11 +473,7 @@ class S2WasmBuilder {
else if (match("ident")) {}
else if (match("section")) parseToplevelSection();
else if (match("align") || match("p2align")) s = strchr(s, '\n');
else if (match("Lfunc_end")) {
// skip the next line, which has a .size we can ignore
s = strstr(s, ".size");
s = strchr(s, '\n');
} else if (match("globl")) parseGlobl();
else if (match("globl")) parseGlobl();
else abort_on("process");
}
}
Expand All @@ -486,8 +482,11 @@ class S2WasmBuilder {
auto section = getCommaSeparated();
// Skipping .debug_ sections
if (!strncmp(section.c_str(), ".debug_", strlen(".debug_"))) {
s -= strlen(section.c_str()); // we want name as well
const char *next = strstr(s, ".section");
s = next ? next : s + strlen(s);
if (!next) next = s + strlen(s);
wasm.debugSections.emplace_back(s, next);
s = next;
return;
}
// Initializers are anything in a section whose name begins with .init_array
Expand Down Expand Up @@ -579,6 +578,9 @@ class S2WasmBuilder {
std::vector<DebugLocation> debugLocations;
debugLocations.emplace_back(); // reserve 0 slot
size_t currentDebugLocationIndex = 0;
std::vector<Name> labels;
labels.emplace_back(name); // reserve 0 slot for function name (which is a label too)
size_t currentLabelIndex = 0;

auto recordFile = [&]() {
if (debug) dump("file");
Expand All @@ -602,6 +604,9 @@ class S2WasmBuilder {
};
auto recordLabel = [&]() {
if (debug) dump("label");
Name label = getStrToSep();
labels.emplace_back(label);
currentLabelIndex++;
// TODO: track and create map of labels and their ranges for our AST
s = strchr(s, '\n');
};
Expand Down Expand Up @@ -700,7 +705,7 @@ class S2WasmBuilder {
auto curr = allocator.alloc<GetLocal>();
curr->index = func->getLocalIndex(getStrToSep());
curr->type = func->getLocalType(curr->index);
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
inputs[i] = curr;
}
if (*s == ')') s++; // tolerate 0(argument) syntax, where we started at the 'a'
Expand Down Expand Up @@ -728,7 +733,7 @@ class S2WasmBuilder {
set->index = func->getLocalIndex(assign);
set->value = curr;
set->type = curr->type;
set->debugLocationIndex = currentDebugLocationIndex;
set->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
addToBlock(set);
}
};
Expand Down Expand Up @@ -758,7 +763,7 @@ class S2WasmBuilder {
auto inputs = getInputs(2);
curr->left = inputs[0];
curr->right = inputs[1];
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
curr->finalize();
assert(curr->type == type);
setOutput(curr, assign);
Expand All @@ -770,29 +775,29 @@ class S2WasmBuilder {
curr->op = op;
curr->value = getInput();
curr->type = type;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
setOutput(curr, assign);
};
auto makeHost = [&](HostOp op) {
Name assign = getAssign();
auto curr = allocator.alloc<Host>();
curr->op = op;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
setOutput(curr, assign);
};
auto makeHost1 = [&](HostOp op) {
Name assign = getAssign();
auto curr = allocator.alloc<Host>();
curr->op = op;
curr->operands.push_back(getInput());
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
setOutput(curr, assign);
};
auto makeLoad = [&](WasmType type) {
skipComma();
auto curr = allocator.alloc<Load>();
curr->type = type;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
int32_t bytes = getInt() / CHAR_BIT;
curr->bytes = bytes > 0 ? bytes : getWasmTypeSize(type);
curr->signed_ = match("_s");
Expand All @@ -813,7 +818,7 @@ class S2WasmBuilder {
skipComma();
auto curr = allocator.alloc<Store>();
curr->type = type;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
int32_t bytes = getInt() / CHAR_BIT;
curr->bytes = bytes > 0 ? bytes : getWasmTypeSize(type);
Name assign = getAssign();
Expand All @@ -840,7 +845,7 @@ class S2WasmBuilder {
curr->condition = inputs[2];
assert(curr->condition->type == i32);
curr->type = type;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
setOutput(curr, assign);
};
auto makeCall = [&](WasmType type) {
Expand All @@ -855,7 +860,7 @@ class S2WasmBuilder {
auto* funcType = ensureFunctionType(getSig(type, operands), &wasm, allocator);
assert(type == funcType->result);
auto* indirect = builder.makeCallIndirect(funcType, target, std::move(operands));
indirect->debugLocationIndex = currentDebugLocationIndex;
indirect->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
setOutput(indirect, assign);

} else {
Expand All @@ -875,7 +880,7 @@ class S2WasmBuilder {
curr = specific;
}
curr->type = type;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
skipWhitespace();
if (*s == ',') {
skipComma();
Expand Down Expand Up @@ -914,7 +919,7 @@ class S2WasmBuilder {
// may be a relocation
auto curr = allocator.alloc<Const>();
curr->type = curr->value.type = i32;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
getConst((uint32_t*)curr->value.geti32Ptr());
setOutput(curr, assign);
} else {
Expand Down Expand Up @@ -1075,7 +1080,7 @@ class S2WasmBuilder {
} else if (match("block")) {
auto curr = allocator.alloc<Block>();
curr->name = getNextLabel();
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
addToBlock(curr);
bstack.push_back(curr);
} else if (match("end_block")) {
Expand All @@ -1092,11 +1097,11 @@ class S2WasmBuilder {
addToBlock(curr);
curr->in = getNextLabel();
curr->out = getNextLabel();
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
auto block = allocator.alloc<Block>();
block->name = curr->out; // temporary, fake - this way, on bstack we have the right label at the right offset for a br
curr->body = block;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
loopBlocks.push_back(block);
bstack.push_back(block);
bstack.push_back(curr);
Expand All @@ -1112,7 +1117,7 @@ class S2WasmBuilder {
assert(curr->targets.size() > 0);
curr->default_ = curr->targets.back();
curr->targets.pop_back();
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
addToBlock(curr);
} else if (match("br")) {
auto curr = allocator.alloc<Break>();
Expand All @@ -1122,7 +1127,7 @@ class S2WasmBuilder {
hasCondition = true;
}
curr->name = getBranchLabel(getInt());
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
if (hasCondition) {
skipComma();
curr->condition = getInput();
Expand All @@ -1142,27 +1147,37 @@ class S2WasmBuilder {
skipComma();
curr->value = getInput();
curr->type = curr->value->type;
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
setOutput(curr, assign);
} else if (match("return")) {
auto curr = builder.makeReturn(*s == '$' ? getInput() : nullptr);
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
addToBlock(curr);
} else if (match("unreachable")) {
auto curr = allocator.alloc<Unreachable>();
curr->debugLocationIndex = currentDebugLocationIndex;
curr->setDebugInfo(currentDebugLocationIndex, currentLabelIndex);
addToBlock(curr);
} else if (match("memory_size")) {
makeHost(CurrentMemory);
} else if (match("grow_memory")) {
makeHost1(GrowMemory);
} else if (peek(".Lfunc_end")) {
// TODO fix handwritten tests to have .endfunc
recordLabel();
s = strchr(s, '\n');
s++;
// skip the next line, which has a .size we can ignore
s = strstr(s, ".size");
s = strchr(s, '\n');
break; // the function is done
} else if (match(".endfunc")) {
skipWhitespace();
// getting all labels at the end of function
while (peek(".L") && strchr(s, ':') < strchr(s, '\n')) {
recordLabel();
skipWhitespace();
}
// skip the next line, which has a .size we can ignore
s = strstr(s, ".size");
s = strchr(s, '\n');
break; // the function is done
} else if (match(".file")) {
recordFile();
Expand All @@ -1183,6 +1198,7 @@ class S2WasmBuilder {
}
func->body->dynCast<Block>()->finalize();
func->debugLocations.swap(debugLocations);
func->labels.swap(labels);
wasm.addFunction(func);
}

Expand Down
Loading

0 comments on commit 310b759

Please sign in to comment.