diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-04-21 18:24:51 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-04-21 18:24:51 -0700 |
commit | 89292a31f04882a51338e6c1b98532de2d4ad750 (patch) | |
tree | 4a391378da1a9c1b1ad87ac5de23bfa1a1db1862 | |
parent | bc8f5204f0ced242dac61957ce0d46e7e9cb6390 (diff) | |
download | binaryen-89292a31f04882a51338e6c1b98532de2d4ad750.tar.gz binaryen-89292a31f04882a51338e6c1b98532de2d4ad750.tar.bz2 binaryen-89292a31f04882a51338e6c1b98532de2d4ad750.zip |
ifs in the binary format always have a break scope
-rw-r--r-- | src/wasm-binary.h | 35 | ||||
-rw-r--r-- | test/unit.wast.fromBinary | 36 |
2 files changed, 47 insertions, 24 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); diff --git a/test/unit.wast.fromBinary b/test/unit.wast.fromBinary index e99eb1309..e80ba999e 100644 --- a/test/unit.wast.fromBinary +++ b/test/unit.wast.fromBinary @@ -68,8 +68,10 @@ ) (i32.const 0) ) - (br $label$0 - (f64.const -3.4) + (block $label$1 + (br $label$0 + (f64.const -3.4) + ) ) ) (if @@ -79,8 +81,10 @@ ) (f64.const 0) ) - (br $label$0 - (f64.const 5.6) + (block $label$2 + (br $label$0 + (f64.const 5.6) + ) ) ) (f64.const 1.2) @@ -96,8 +100,10 @@ (get_local $var$0) (f64.const 0) ) - (br $label$0 - (f64.const 1.2) + (block $label$1 + (br $label$0 + (f64.const 1.2) + ) ) ) (if @@ -105,8 +111,10 @@ (get_local $var$4) (f64.const 0) ) - (br $label$0 - (f64.const -3.4) + (block $label$2 + (br $label$0 + (f64.const -3.4) + ) ) ) (if @@ -114,8 +122,10 @@ (get_local $var$2) (i32.const 0) ) - (br $label$0 - (f64.const 5.6) + (block $label$3 + (br $label$0 + (f64.const 5.6) + ) ) ) (if @@ -123,8 +133,10 @@ (get_local $var$0) (get_local $var$1) ) - (br $label$0 - (get_local $var$0) + (block $label$4 + (br $label$0 + (get_local $var$0) + ) ) ) (get_local $var$1) |