summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-04-21 18:24:51 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-04-21 18:24:51 -0700
commit89292a31f04882a51338e6c1b98532de2d4ad750 (patch)
tree4a391378da1a9c1b1ad87ac5de23bfa1a1db1862 /src
parentbc8f5204f0ced242dac61957ce0d46e7e9cb6390 (diff)
downloadbinaryen-89292a31f04882a51338e6c1b98532de2d4ad750.tar.gz
binaryen-89292a31f04882a51338e6c1b98532de2d4ad750.tar.bz2
binaryen-89292a31f04882a51338e6c1b98532de2d4ad750.zip
ifs in the binary format always have a break scope
Diffstat (limited to 'src')
-rw-r--r--src/wasm-binary.h35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 3e4002c0e..3c2833069 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -805,10 +805,14 @@ public:
if (debug) std::cerr << "zz node: If" << std::endl;
recurse(curr->condition);
o << int8_t(BinaryConsts::If);
- recurse(curr->ifTrue); // TODO: emit block contents directly, if block with no name
+ breakStack.push_back(IMPOSSIBLE_CONTINUE); // the binary format requires this; we have a block if we need one; TODO: optimize
+ recurse(curr->ifTrue); // TODO: emit block contents directly, if possible
+ breakStack.pop_back();
if (curr->ifFalse) {
o << int8_t(BinaryConsts::Else);
+ breakStack.push_back(IMPOSSIBLE_CONTINUE); // TODO ditto
recurse(curr->ifFalse);
+ breakStack.pop_back();
}
o << int8_t(BinaryConsts::End);
}
@@ -1678,24 +1682,31 @@ public:
auto start = expressionStack.size();
processExpressions();
size_t end = expressionStack.size();
- if (end - start == 1) {
- return popExpression();
- } else {
- auto* body = allocator.alloc<Block>();
- for (size_t i = start; i < end; i++) {
- body->list.push_back(expressionStack[i]);
- }
- expressionStack.resize(start);
- return body;
+ // TODO: optimize case of 1 expression and 0 breaks in this scope
+ auto* block = allocator.alloc<Block>();
+ for (size_t i = start; i < end; i++) {
+ block->list.push_back(expressionStack[i]);
}
+ block->finalize();
+ expressionStack.resize(start);
+ return block;
+ }
+
+ Expression* getBlock() {
+ Name label = getNextLabel();
+ breakStack.push_back(label);
+ auto* block = getMaybeBlock()->cast<Block>(); // TODO: when getMaybeBlock is optimized, blockify only when needed
+ breakStack.pop_back();
+ block->name = label;
+ return block;
}
void visitIf(If *curr) {
if (debug) std::cerr << "zz node: If" << std::endl;
curr->condition = popExpression();
- curr->ifTrue = getMaybeBlock();
+ curr->ifTrue = getBlock();
if (lastSeparator == BinaryConsts::Else) {
- curr->ifFalse = getMaybeBlock();
+ curr->ifFalse = getBlock();
curr->finalize();
}
assert(lastSeparator == BinaryConsts::End);