diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-08 10:19:20 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-08 10:19:20 -0800 |
commit | 92ac805edc6ebe06e5ad850c8a03202bd1a7f397 (patch) | |
tree | e5de0747143cb108cb8a3ebe73c2c90719036a70 /src | |
parent | 01363d0daeb33c93a166ae00ed5e9791d7de8f9f (diff) | |
download | binaryen-92ac805edc6ebe06e5ad850c8a03202bd1a7f397.tar.gz binaryen-92ac805edc6ebe06e5ad850c8a03202bd1a7f397.tar.bz2 binaryen-92ac805edc6ebe06e5ad850c8a03202bd1a7f397.zip |
switch fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-interpreter.h | 2 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 21 | ||||
-rw-r--r-- | src/wasm.h | 3 |
3 files changed, 18 insertions, 8 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 834b0bc52..97c92cd04 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -142,12 +142,10 @@ private: } }; #define NOTE_ENTER(x) IndentHandler indentHandler(instance.indent, x, curr); - #define NOTE_EVAL() { doIndent(std::cout, instance.indent); std::cout << "eval " << indentHandler.name << '\n'; } #define NOTE_EVAL1(p0) { doIndent(std::cout, instance.indent); std::cout << "eval " << indentHandler.name << '(' << p0 << ")\n"; } #define NOTE_EVAL2(p0, p1) { doIndent(std::cout, instance.indent); std::cout << "eval " << indentHandler.name << '(' << p0 << ", " << p1 << ")\n"; } #else #define NOTE_ENTER(x) - #define NOTE_EVAL() #define NOTE_EVAL1(p0) #define NOTE_EVAL2(p0, p1) #endif diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 83d9b7e66..20867191d 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -945,14 +945,14 @@ private: if (s[i]->isStr()) { ret->name = s[i]->str(); i++; + } else { + ret->name = getPrefixedName(otherIndex++, "switch"); } ret->value = parseExpression(s[i]); i++; - Element& cases = *s[i]; - i++; ret->default_ = getPrefixedName(otherIndex++, "switch-default"); - for (; i < cases.size(); i++) { - Element& curr = *cases[i]; + for (; i < s.size(); i++) { + Element& curr = *s[i]; if (curr[0]->str() == CASE) { int32_t caseIndex = atoi(curr[1]->c_str()); while (ret->targets.size() < caseIndex) { @@ -960,7 +960,18 @@ private: } Name name = getPrefixedName(otherIndex++, "switch-case"); ret->targets.push_back(name); - ret->cases.emplace_back(name, parseExpression(curr[2])); + // if there is no body at all, this is a trivial fallthrough + auto body = curr.size() < 3 ? allocator.alloc<Nop>() : parseExpression(curr[2]); + // if not fallthrough, add a break on the switch itself + if (curr.size() == 4) { + assert(curr[3]->str() == IString("fallthru")); + } else if (curr.size() == 3) { + Break *exit = allocator.alloc<Break>(); + exit->name = ret->name; + exit->value = body; + body = exit; + } + ret->cases.emplace_back(name, body); } else { // the default ret->cases.emplace_back(ret->default_, parseExpression(curr)); diff --git a/src/wasm.h b/src/wasm.h index 6eee9d8a2..38a08a27e 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -377,7 +377,8 @@ public: } std::ostream& doPrint(std::ostream &o, unsigned indent) { - printOpening(o, "switch ") << name; + printOpening(o, "switch "); + if (name.is()) o << name; incIndent(o, indent); printFullLine(o, indent, value); doIndent(o, indent) << "[ "; |