summaryrefslogtreecommitdiff
path: root/src/wasm-s-parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-s-parser.h')
-rw-r--r--src/wasm-s-parser.h56
1 files changed, 20 insertions, 36 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;
}