Skip to content

Commit

Permalink
Allows parsing of debug information in .S files
Browse files Browse the repository at this point in the history
Currently it ignores this information. Also it allows parse files with -asm-verbose=true.
  • Loading branch information
yurydelendik committed May 26, 2016
1 parent 45618dd commit 349cc00
Show file tree
Hide file tree
Showing 4 changed files with 445 additions and 12 deletions.
3 changes: 3 additions & 0 deletions src/compiler-support.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@
# define WASM_UNREACHABLE() abort()
#endif

#define WASM_UNUSED(expr) \
do { if (sizeof expr) { (void)0; } } while (0)

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

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

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

void parseFile() {
assert(*s == '"');
if (*s != '"') {
// TODO: optimize, see recordFile below
size_t fileId = getInt();
skipWhitespace();
std::vector<char> 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 +501,31 @@ class S2WasmBuilder {

mustMatch(":");

if (match(".Lfunc_begin")) {
auto recordFile = [&]() {
if (debug) dump("file");
size_t fileId = getInt();
skipWhitespace();
std::vector<char> 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 +559,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 +689,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 +981,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
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 +1048,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

0 comments on commit 349cc00

Please sign in to comment.