summaryrefslogtreecommitdiff
path: root/src/wasm-s-parser.h
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-03-07 17:03:23 -0800
committerAlon Zakai <alonzakai@gmail.com>2016-03-07 17:03:23 -0800
commit8efa11fbb9ff8cfd8bacc9d16642e13e2bbac9b4 (patch)
tree22050fa4bbdfa87d367030d88f5af3c4f11eb7fd /src/wasm-s-parser.h
parentb65a994c24e83694f27cb835845b3b281207fc2f (diff)
parenta94f9938701920fe11c4f21a875ed3174ff7e9ba (diff)
downloadbinaryen-8efa11fbb9ff8cfd8bacc9d16642e13e2bbac9b4.tar.gz
binaryen-8efa11fbb9ff8cfd8bacc9d16642e13e2bbac9b4.tar.bz2
binaryen-8efa11fbb9ff8cfd8bacc9d16642e13e2bbac9b4.zip
Merge pull request #224 from WebAssembly/spec-updates
Spec updates
Diffstat (limited to 'src/wasm-s-parser.h')
-rw-r--r--src/wasm-s-parser.h65
1 files changed, 57 insertions, 8 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 24ca1b811..f3a28fd1a 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -29,6 +29,7 @@
#include "shared-constants.h"
#include "parsing.h"
#include "asm_v_wasm.h"
+#include "ast_utils.h"
namespace wasm {
@@ -380,6 +381,7 @@ private:
if (!autoBlock) {
autoBlock = allocator.alloc<Block>();
autoBlock->list.push_back(func->body);
+ autoBlock->finalize();
func->body = autoBlock;
}
autoBlock->list.push_back(ex);
@@ -567,6 +569,10 @@ public:
}
abort_on(str);
}
+ case 'e': {
+ if (str[1] == 'l') return makeThenOrElse(s);
+ abort_on(str);
+ }
case 'g': {
if (str[1] == 'e') return makeGetLocal(s);
if (str[1] == 'r') return makeHost(s, HostOp::GrowMemory);
@@ -607,6 +613,7 @@ public:
}
case 't': {
if (str[1] == 'a') return makeSwitch(s); // aka tableswitch
+ if (str[1] == 'h') return makeThenOrElse(s);
abort_on(str);
}
case 'u': {
@@ -688,8 +695,9 @@ private:
Expression* makeBlock(Element& s) {
auto ret = allocator.alloc<Block>();
size_t i = 1;
- if (s[1]->isStr()) {
- ret->name = s[1]->str();
+ if (i >= s.size()) return ret; // empty block
+ if (s[i]->isStr()) {
+ ret->name = s[i]->str();
i++;
} else {
ret->name = getPrefixedName("block");
@@ -699,7 +707,21 @@ private:
ret->list.push_back(parseExpression(s[i]));
}
labelStack.pop_back();
- if (ret->list.size() > 0) ret->type = ret->list.back()->type;
+ ret->finalize();
+ return ret;
+ }
+
+ // Similar to block, but the label is handled by the enclosing if (since there might not be a then or else, ick)
+ Expression* makeThenOrElse(Element& s) {
+ auto ret = allocator.alloc<Block>();
+ size_t i = 1;
+ if (s[1]->isStr()) {
+ i++;
+ }
+ for (; i < s.size(); i++) {
+ ret->list.push_back(parseExpression(s[i]));
+ }
+ ret->finalize();
return ret;
}
@@ -788,9 +810,38 @@ private:
Expression* makeIf(Element& s) {
auto ret = allocator.alloc<If>();
ret->condition = parseExpression(s[1]);
- ret->ifTrue = parseExpression(s[2]);
+
+ // ifTrue and ifFalse may get implicit blocks
+ auto handle = [&](const char* title, Element& s) {
+ Name name = getPrefixedName(title);
+ bool explicitThenElse = false;
+ if (s[0]->str() == THEN || s[0]->str() == ELSE) {
+ explicitThenElse = true;
+ if (s[1]->dollared()) {
+ name = s[1]->str();
+ }
+ }
+ labelStack.push_back(name);
+ auto* ret = parseExpression(&s);
+ labelStack.pop_back();
+ if (explicitThenElse) {
+ ret->dyn_cast<Block>()->name = name;
+ } else {
+ // add a block if we must
+ if (BreakSeeker::has(ret, name)) {
+ auto* block = allocator.alloc<Block>();
+ block->name = name;
+ block->list.push_back(ret);
+ block->finalize();
+ ret = block;
+ }
+ }
+ return ret;
+ };
+
+ ret->ifTrue = handle("if-true", *s[2]);
if (s.size() == 4) {
- ret->ifFalse = parseExpression(s[3]);
+ ret->ifFalse = handle("if-else", *s[3]);
ret->finalize();
}
return ret;
@@ -802,9 +853,7 @@ private:
for (; i < s.size() && i < stopAt; i++) {
ret->list.push_back(parseExpression(s[i]));
}
- if (ret->list.size() > 0) {
- ret->type = ret->list.back()->type;
- }
+ ret->finalize();
// Note that we do not name these implicit/synthetic blocks. They
// are the effects of syntactic sugar, and nothing can branch to
// them anyhow.