Skip to content

Allows parsing debug information in the .S files #544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/compiler-support.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@
# define WASM_UNREACHABLE() abort()
#endif

// The code might contain TODOs or stubs that read some values but do nothing
// with them. The compiler might fail with [-Werror,-Wunused-variable].
// The WASM_UNUSED(varible) is a wrapper that helps to suppress the error.
#define WASM_UNUSED(expr) \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this wasn't obvious to me what it does, please add a comment

do { if (sizeof expr) { (void)0; } } while (0)

#endif // wasm_compiler_support_h
96 changes: 84 additions & 12 deletions src/s2wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ class S2WasmBuilder {
abort(); \
}

bool peek(const char *pattern) {
return strncmp(s, pattern, strlen(pattern)) == 0;
}

// match and skip the pattern, if matched
bool match(const char *pattern) {
size_t size = strlen(pattern);
Expand Down Expand Up @@ -396,17 +400,19 @@ 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");
}
}

void parseToplevelSection() {
auto section = getCommaSeparated();
// Skipping .debug_ sections
if (!strncmp(section.c_str(), ".debug_", strlen(".debug_"))) {
const char *next = strstr(s, ".section");
s = !next ? s + strlen(s) : next;
return;
}
// Initializers are anything in a section whose name begins with .init_array
if (!strncmp(section.c_str(), ".init_array", strlen(".init_array") - 1)) {
parseInitializer();
Expand Down Expand Up @@ -449,15 +455,24 @@ class S2WasmBuilder {
}

void parseFile() {
assert(*s == '"');
if (*s != '"') {
// TODO: optimize, see recordFile below
size_t fileId = getInt();
skipWhitespace();
auto quoted = getQuoted();
WASM_UNUSED(fileId); WASM_UNUSED(quoted); // TODO: use the fileId and quoted
s = strchr(s, '\n');
return;
}
// '.file' without first index argument points to bc-file
s++;
std::string filename;
while (*s != '"') {
filename += *s;
s++;
}
s++;
// TODO: use the filename?
WASM_UNUSED(filename); // TODO: use the filename
}

void parseGlobl() {
Expand Down Expand Up @@ -485,11 +500,31 @@ class S2WasmBuilder {

mustMatch(":");

if (match(".Lfunc_begin")) {
auto recordFile = [&]() {
if (debug) dump("file");
size_t fileId = getInt();
skipWhitespace();
auto quoted = getQuoted();
WASM_UNUSED(fileId); WASM_UNUSED(quoted); // TODO: use the fileId and quoted
s = strchr(s, '\n');
s++;
};
auto recordLoc = [&]() {
if (debug) dump("loc");
size_t fileId = getInt();
skipWhitespace();
}
size_t row = getInt();
skipWhitespace();
size_t column = getInt();
WASM_UNUSED(fileId); WASM_UNUSED(row); WASM_UNUSED(column); // TODO: use the fileId, row and column
s = strchr(s, '\n');
};
auto recordLabel = [&]() {
if (debug) dump("label");
Name label = getStrToSep();
// TODO: track and create map of labels and their ranges for our AST
WASM_UNUSED(label);
s = strchr(s, '\n');
};

unsigned nextId = 0;
auto getNextId = [&nextId]() {
Expand Down Expand Up @@ -523,6 +558,15 @@ class S2WasmBuilder {
skipWhitespace();
if (!match(",")) break;
}
} else if (match(".file")) {
recordFile();
skipWhitespace();
} else if (match(".loc")) {
recordLoc();
skipWhitespace();
} else if (peek(".Lfunc_begin")) {
recordLabel();
skipWhitespace();
} else break;
}
Function* func = builder.makeFunction(name, std::move(params), resultType, std::move(vars));
Expand Down Expand Up @@ -644,6 +688,7 @@ class S2WasmBuilder {
auto curr = allocator->alloc<Unary>();
curr->op = op;
curr->value = getInput();
curr->type = type;
curr->finalize();
setOutput(curr, assign);
};
Expand Down Expand Up @@ -935,8 +980,13 @@ class S2WasmBuilder {
} else if (match("end_block")) {
bstack.back()->cast<Block>()->finalize();
bstack.pop_back();
} else if (match(".LBB")) {
s = strchr(s, '\n');
} else if (peek(".LBB")) {
// FIXME legacy tests: it can be leftover from "loop" or "block", but it can be a label too
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sunfishcode: what's the status of .LBB and Lfunc_end? Looks like this PR has to introduce workarounds for them. Are they gone from .s now? Do we just need to update handwritten tests?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Lfunc_end is still in the .s file, but is emitted after the .end_func so s2wasm doesn't consider it to be part of the function body. .LBB is still present and isn't referenced from the actual code, though it probably is referenced by debug info, which is probably why this patch needs to parse it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, thanks @sunfishcode.

Ok, @yurydelendik, looks like the right approach to me in this pull. So aside from the comments I noted, lgtm.

auto p = s;
while (*p && *p != ':' && *p != '#' && *p != '\n') p++;
if (*p == ':') { // it's a label
recordLabel();
} else s = strchr(s, '\n');
} else if (match("loop")) {
auto curr = allocator->alloc<Loop>();
addToBlock(curr);
Expand Down Expand Up @@ -997,8 +1047,30 @@ class S2WasmBuilder {
makeHost(CurrentMemory);
} else if (match("grow_memory")) {
makeHost1(GrowMemory);
} else if (peek(".Lfunc_end")) {
// TODO fix handwritten tests to have .endfunc
recordLabel();
// 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();
} else if (match(".loc")) {
recordLoc();
} else if (peek(".L") && strchr(s, ':') < strchr(s, '\n')) {
recordLabel();
} else {
abort_on("function element");
}
Expand Down
Loading