summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-11-09 19:19:19 -0800
committerAlon Zakai <alonzakai@gmail.com>2015-11-09 19:19:19 -0800
commitb8b815a6cc5f6d43222f623e63f9e665ff460085 (patch)
treec969ec13bf05ac1ddd7287b3383a6b87c81d63f9 /src
parent9c6476efe9403658bb69851bfa3aa30f67a32868 (diff)
downloadbinaryen-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.h56
-rw-r--r--src/wasm.h9
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);