summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-11-08 10:19:20 -0800
committerAlon Zakai <alonzakai@gmail.com>2015-11-08 10:19:20 -0800
commit92ac805edc6ebe06e5ad850c8a03202bd1a7f397 (patch)
treee5de0747143cb108cb8a3ebe73c2c90719036a70 /src
parent01363d0daeb33c93a166ae00ed5e9791d7de8f9f (diff)
downloadbinaryen-92ac805edc6ebe06e5ad850c8a03202bd1a7f397.tar.gz
binaryen-92ac805edc6ebe06e5ad850c8a03202bd1a7f397.tar.bz2
binaryen-92ac805edc6ebe06e5ad850c8a03202bd1a7f397.zip
switch fixes
Diffstat (limited to 'src')
-rw-r--r--src/wasm-interpreter.h2
-rw-r--r--src/wasm-s-parser.h21
-rw-r--r--src/wasm.h3
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) << "[ ";