summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler-support.h6
-rw-r--r--src/s2wasm.h96
-rw-r--r--test/dot_s/debug.s307
-rw-r--r--test/dot_s/debug.wast51
4 files changed, 448 insertions, 12 deletions
diff --git a/src/compiler-support.h b/src/compiler-support.h
index 9e298b278..bf2885993 100644
--- a/src/compiler-support.h
+++ b/src/compiler-support.h
@@ -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) \
+ do { if (sizeof expr) { (void)0; } } while (0)
+
#endif // wasm_compiler_support_h
diff --git a/src/s2wasm.h b/src/s2wasm.h
index c0ab0998b..2228ae900 100644
--- a/src/s2wasm.h
+++ b/src/s2wasm.h
@@ -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);
@@ -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();
@@ -449,7 +455,16 @@ 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 != '"') {
@@ -457,7 +472,7 @@ class S2WasmBuilder {
s++;
}
s++;
- // TODO: use the filename?
+ WASM_UNUSED(filename); // TODO: use the filename
}
void parseGlobl() {
@@ -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]() {
@@ -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));
@@ -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);
};
@@ -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
+ 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);
@@ -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");
}
diff --git a/test/dot_s/debug.s b/test/dot_s/debug.s
new file mode 100644
index 000000000..045b1ddad
--- /dev/null
+++ b/test/dot_s/debug.s
@@ -0,0 +1,307 @@
+ .text
+ .file "fib.bc"
+ .hidden fib
+ .globl fib
+ .type fib,@function
+fib:
+.Lfunc_begin0:
+ .file 1 "fib.c"
+ .loc 1 1 0
+ .param i32
+ .result i32
+ .local i32, i32, i32, i32
+.Ltmp0:
+ i32.const $3=, 0
+.Ltmp1:
+ i32.const $2=, -1
+ i32.const $4=, 1
+.LBB0_1:
+ loop
+ i32.const $push1=, 1
+.Ltmp2:
+ .loc 1 3 17 prologue_end discriminator 1
+ i32.add $2=, $2, $pop1
+ .loc 1 3 3 is_stmt 0 discriminator 1
+ i32.ge_s $push0=, $2, $0
+ br_if 1, $pop0
+.Ltmp3:
+ .loc 1 4 11 is_stmt 1
+ i32.add $1=, $4, $3
+.Ltmp4:
+ copy_local $3=, $4
+ copy_local $4=, $1
+ br 0
+.Ltmp5:
+.LBB0_3:
+ end_loop
+.Ltmp6:
+ .loc 1 6 3
+ return $4
+.Ltmp7:
+ .endfunc
+.Lfunc_end0:
+ .size fib, .Lfunc_end0-fib
+
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang version 3.9.0 (trunk 266025)"
+.Linfo_string1:
+ .asciz "fib.c"
+.Linfo_string2:
+ .asciz "/Users/yury/llvmwasm"
+.Linfo_string3:
+ .asciz "fib"
+.Linfo_string4:
+ .asciz "int"
+.Linfo_string5:
+ .asciz "n"
+.Linfo_string6:
+ .asciz "a"
+.Linfo_string7:
+ .asciz "b"
+.Linfo_string8:
+ .asciz "i"
+.Linfo_string9:
+ .asciz "t"
+ .section .debug_loc,"",@progbits
+.Ldebug_loc0:
+ .int32 .Lfunc_begin0-.Lfunc_begin0
+ .int32 .Lfunc_end0-.Lfunc_begin0
+ .int16 1
+ .int8 150
+ .int32 0
+ .int32 0
+.Ldebug_loc1:
+ .int32 .Ltmp0-.Lfunc_begin0
+ .int32 .Ltmp6-.Lfunc_begin0
+ .int16 3
+ .int8 17
+ .int8 0
+ .int8 159
+ .int32 .Ltmp6-.Lfunc_begin0
+ .int32 .Lfunc_end0-.Lfunc_begin0
+ .int16 1
+ .int8 150
+ .int32 0
+ .int32 0
+.Ldebug_loc2:
+ .int32 .Ltmp0-.Lfunc_begin0
+ .int32 .Ltmp4-.Lfunc_begin0
+ .int16 3
+ .int8 17
+ .int8 1
+ .int8 159
+ .int32 .Ltmp4-.Lfunc_begin0
+ .int32 .Lfunc_end0-.Lfunc_begin0
+ .int16 1
+ .int8 150
+ .int32 0
+ .int32 0
+.Ldebug_loc3:
+ .int32 .Ltmp4-.Lfunc_begin0
+ .int32 .Lfunc_end0-.Lfunc_begin0
+ .int16 1
+ .int8 150
+ .int32 0
+ .int32 0
+ .section .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+ .int8 1
+ .int8 17
+ .int8 1
+ .int8 37
+ .int8 14
+ .int8 19
+ .int8 5
+ .int8 3
+ .int8 14
+ .int8 16
+ .int8 23
+ .int8 27
+ .int8 14
+ .ascii "\341\177"
+ .int8 25
+ .int8 17
+ .int8 1
+ .int8 18
+ .int8 6
+ .int8 0
+ .int8 0
+ .int8 2
+ .int8 46
+ .int8 1
+ .int8 17
+ .int8 1
+ .int8 18
+ .int8 6
+ .ascii "\347\177"
+ .int8 25
+ .int8 64
+ .int8 24
+ .int8 3
+ .int8 14
+ .int8 58
+ .int8 11
+ .int8 59
+ .int8 11
+ .int8 39
+ .int8 25
+ .int8 73
+ .int8 19
+ .int8 63
+ .int8 25
+ .ascii "\341\177"
+ .int8 25
+ .int8 0
+ .int8 0
+ .int8 3
+ .int8 5
+ .int8 0
+ .int8 2
+ .int8 23
+ .int8 3
+ .int8 14
+ .int8 58
+ .int8 11
+ .int8 59
+ .int8 11
+ .int8 73
+ .int8 19
+ .int8 0
+ .int8 0
+ .int8 4
+ .int8 52
+ .int8 0
+ .int8 2
+ .int8 23
+ .int8 3
+ .int8 14
+ .int8 58
+ .int8 11
+ .int8 59
+ .int8 11
+ .int8 73
+ .int8 19
+ .int8 0
+ .int8 0
+ .int8 5
+ .int8 52
+ .int8 0
+ .int8 28
+ .int8 13
+ .int8 3
+ .int8 14
+ .int8 58
+ .int8 11
+ .int8 59
+ .int8 11
+ .int8 73
+ .int8 19
+ .int8 0
+ .int8 0
+ .int8 6
+ .int8 36
+ .int8 0
+ .int8 3
+ .int8 14
+ .int8 62
+ .int8 11
+ .int8 11
+ .int8 11
+ .int8 0
+ .int8 0
+ .int8 0
+ .section .debug_info,"",@progbits
+.Lsection_info:
+.Lcu_begin0:
+ .int32 135
+ .int16 4
+ .int32 .Lsection_abbrev
+ .int8 4
+ .int8 1
+ .int32 .Linfo_string0
+ .int16 12
+ .int32 .Linfo_string1
+ .int32 .Lline_table_start0
+ .int32 .Linfo_string2
+
+ .int32 .Lfunc_begin0
+ .int32 .Lfunc_end0-.Lfunc_begin0
+ .int8 2
+ .int32 .Lfunc_begin0
+ .int32 .Lfunc_end0-.Lfunc_begin0
+
+ .int8 0
+ .int32 .Linfo_string3
+ .int8 1
+ .int8 1
+
+ .int32 131
+
+
+ .int8 3
+ .int32 .Ldebug_loc0
+ .int32 .Linfo_string5
+ .int8 1
+ .int8 1
+ .int32 131
+ .int8 4
+ .int32 .Ldebug_loc1
+ .int32 .Linfo_string6
+ .int8 1
+ .int8 2
+ .int32 131
+ .int8 4
+ .int32 .Ldebug_loc2
+ .int32 .Linfo_string7
+ .int8 1
+ .int8 2
+ .int32 131
+ .int8 5
+ .int8 0
+ .int32 .Linfo_string8
+ .int8 1
+ .int8 2
+ .int32 131
+ .int8 4
+ .int32 .Ldebug_loc3
+ .int32 .Linfo_string9
+ .int8 1
+ .int8 2
+ .int32 131
+ .int8 0
+ .int8 6
+ .int32 .Linfo_string4
+ .int8 5
+ .int8 4
+ .int8 0
+ .section .debug_ranges,"",@progbits
+.Ldebug_range:
+ .section .debug_macinfo,"",@progbits
+.Ldebug_macinfo:
+.Lcu_macro_begin0:
+ .int8 0
+ .section .debug_pubnames,"",@progbits
+ .int32 .LpubNames_end0-.LpubNames_begin0
+.LpubNames_begin0:
+ .int16 2
+ .int32 .Lcu_begin0
+ .int32 139
+ .int32 38
+ .asciz "fib"
+ .int32 0
+.LpubNames_end0:
+ .section .debug_pubtypes,"",@progbits
+ .int32 .LpubTypes_end0-.LpubTypes_begin0
+.LpubTypes_begin0:
+ .int16 2
+ .int32 .Lcu_begin0
+ .int32 139
+ .int32 131
+ .asciz "int"
+ .int32 0
+.LpubTypes_end0:
+
+ .ident "clang version 3.9.0 (trunk 266025)"
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/test/dot_s/debug.wast b/test/dot_s/debug.wast
new file mode 100644
index 000000000..3a859fd0d
--- /dev/null
+++ b/test/dot_s/debug.wast
@@ -0,0 +1,51 @@
+(module
+ (memory 1)
+ (export "memory" memory)
+ (export "fib" $fib)
+ (func $fib (param $0 i32) (result i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (set_local $3
+ (i32.const 0)
+ )
+ (set_local $2
+ (i32.const -1)
+ )
+ (set_local $4
+ (i32.const 1)
+ )
+ (loop $label$1 $label$0
+ (set_local $2
+ (i32.add
+ (get_local $2)
+ (i32.const 1)
+ )
+ )
+ (br_if $label$1
+ (i32.ge_s
+ (get_local $2)
+ (get_local $0)
+ )
+ )
+ (set_local $1
+ (i32.add
+ (get_local $4)
+ (get_local $3)
+ )
+ )
+ (set_local $3
+ (get_local $4)
+ )
+ (set_local $4
+ (get_local $1)
+ )
+ (br $label$0)
+ )
+ (return
+ (get_local $4)
+ )
+ )
+)
+;; METADATA: { "asmConsts": {},"staticBump": 12, "initializers": [] }