diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-09 19:19:19 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-09 19:19:19 -0800 |
commit | b8b815a6cc5f6d43222f623e63f9e665ff460085 (patch) | |
tree | c969ec13bf05ac1ddd7287b3383a6b87c81d63f9 /src | |
parent | 9c6476efe9403658bb69851bfa3aa30f67a32868 (diff) | |
download | binaryen-b8b815a6cc5f6d43222f623e63f9e665ff460085.tar.gz binaryen-b8b815a6cc5f6d43222f623e63f9e665ff460085.tar.bz2 binaryen-b8b815a6cc5f6d43222f623e63f9e665ff460085.zip |
update control flow operators, blacklist some new float errors for now
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-s-parser.h | 56 | ||||
-rw-r--r-- | src/wasm.h | 9 |
2 files changed, 25 insertions, 40 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index f92aeed43..0832139d4 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -490,7 +490,6 @@ public: if (op[1] == 'u') return makeBinary(s, BinaryOp::Sub, type); if (op[1] == 'q') return makeUnary(s, UnaryOp::Sqrt, type); if (op[1] == 't') return makeStore(s, type); - if (op[1] == 'w') return makeSwitch(s, type); abort_on(op); } case 't': { @@ -565,6 +564,10 @@ public: if (str[1] == 'e') return makeReturn(s); abort_on(str); } + case 't': { + if (str[1] == 'a') return makeSwitch(s); // aka tableswitch + abort_on(str); + } default: abort_on(str); } } @@ -918,17 +921,17 @@ private: Expression* makeLoop(Element& s) { auto ret = allocator.alloc<Loop>(); size_t i = 1; - if (s[i]->isStr()) { - ret->in = s[i]->str(); + if (s[i]->isStr() && s[i+1]->isStr()) { // out can only be named if both are + ret->out = s[i]->str(); i++; } else { - ret->in = getPrefixedName("loop-in"); + ret->out = getPrefixedName("loop-out"); } if (s[i]->isStr()) { - ret->out = s[i]->str(); + ret->in = s[i]->str(); i++; } else { - ret->out = getPrefixedName("loop-out"); + ret->in = getPrefixedName("loop-in"); } labelStack.push_back(ret->out); labelStack.push_back(ret->in); @@ -1002,9 +1005,8 @@ private: return ret; } - Expression* makeSwitch(Element& s, WasmType type) { + Expression* makeSwitch(Element& s) { auto ret = allocator.alloc<Switch>(); - ret->type = type; size_t i = 1; if (s[i]->isStr()) { ret->name = s[i]->str(); @@ -1014,38 +1016,20 @@ private: } ret->value = parseExpression(s[i]); i++; - ret->default_ = getPrefixedName("switch-default"); + Element& table = *s[i]; + i++; + for (size_t j = 1; j < table.size(); j++) { + ret->targets.push_back((*table[j])[1]->str()); + } + ret->default_ = (*s[i])[1]->str(); + 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) { - ret->targets.push_back(ret->default_); - } - Name name = getPrefixedName("switch-case"); - ret->targets.push_back(name); - Expression* body; - size_t size = curr.size(); - if (size == 2) { - body = allocator.alloc<Nop>(); // trivial fallthrough - } else { - size_t j = 2; - bool fallThrough = curr[size-1]->isStr() && curr[size-1]->str() == IString("fallthrough"); - body = makeMaybeBlock(curr, j, fallThrough ? size-1 : size); - if (!fallThrough) { - 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)); - } + assert(curr[0]->str() == CASE); + ret->cases.emplace_back(curr[1]->str(), makeMaybeBlock(curr, 2, curr.size())); } ret->updateCaseMap(); + ret->type = ret->cases[0].body->type; return ret; } diff --git a/src/wasm.h b/src/wasm.h index 2a7a9b804..68bee7e5a 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -338,11 +338,12 @@ public: std::ostream& doPrint(std::ostream &o, unsigned indent) { printOpening(o, "loop"); + if (out.is()) { + o << ' ' << out; + assert(in.is()); // if just one is printed, it must be the in + } if (in.is()) { o << ' ' << in; - if (out.is()) { - o << ' ' << out; - } } incIndent(o, indent); printFullLine(o, indent, body); @@ -405,7 +406,7 @@ public: } std::ostream& doPrint(std::ostream &o, unsigned indent) { - printOpening(o, "switch "); + printOpening(o, "tableswitch "); if (name.is()) o << name; incIndent(o, indent); printFullLine(o, indent, value); |