diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-20 09:58:10 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-20 09:58:10 -0800 |
commit | b974e9351405880fe1d021e3ae7fda92f1b3bb4f (patch) | |
tree | e5f2b9fb512a3adf649516f54adc60bb9584272c | |
parent | 39891e0c123103ceef18150c9d1145924dced2bf (diff) | |
download | binaryen-b974e9351405880fe1d021e3ae7fda92f1b3bb4f.tar.gz binaryen-b974e9351405880fe1d021e3ae7fda92f1b3bb4f.tar.bz2 binaryen-b974e9351405880fe1d021e3ae7fda92f1b3bb4f.zip |
br_if
-rw-r--r-- | src/wasm-interpreter.h | 17 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 17 | ||||
-rw-r--r-- | src/wasm.h | 15 |
3 files changed, 35 insertions, 14 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 3f69d36e5..e20d3a358 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -211,14 +211,19 @@ private: } Flow visitBreak(Break *curr) override { NOTE_ENTER("Break"); + bool condition = true; + if (curr->condition) { + Flow flow = visit(curr->condition); + if (flow.breaking()) return flow; + condition = flow.value.getInteger(); + } + Flow flow(curr->name); if (curr->value) { - Flow flow = visit(curr->value); - if (!flow.breaking()) { - flow.breakTo = curr->name; - } - return flow; + flow = visit(curr->value); + if (flow.breaking()) return flow; + flow.breakTo = curr->name; } - return Flow(curr->name); + return condition ? flow : Flow(); } Flow visitSwitch(Switch *curr) override { NOTE_ENTER("Switch"); diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index ec7d6c6dc..8fbedcbf2 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -32,6 +32,7 @@ IString MODULE("module"), CALL("call"), CALL_IMPORT("call_import"), CALL_INDIRECT("call_indirect"), + BR_IF("br_if"), INFINITY_("infinity"), NEG_INFINITY("-infinity"), NAN_("nan"), @@ -989,16 +990,22 @@ private: Expression* makeBreak(Element& s) { auto ret = allocator.alloc<Break>(); - if (s[1]->dollared()) { - ret->name = s[1]->str(); + size_t i = 1; + if (s[0]->str() == BR_IF) { + ret->condition = parseExpression(s[i]); + i++; + } + if (s[i]->dollared()) { + ret->name = s[i]->str(); } else { // offset, break to nth outside label - size_t offset = atol(s[1]->c_str()); + size_t offset = atol(s[i]->c_str()); assert(offset < labelStack.size()); ret->name = labelStack[labelStack.size() - 1 - offset]; } - if (s.size() == 3) { - ret->value = parseExpression(s[2]); + i++; + if (i < s.size()) { + ret->value = parseExpression(s[i]); } return ret; } diff --git a/src/wasm.h b/src/wasm.h index 49951c14a..eb4d69fd4 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -392,14 +392,22 @@ public: class Break : public Expression { public: - Break() : Expression(BreakId), value(nullptr) {} + Break() : Expression(BreakId), condition(nullptr), value(nullptr) {} + Expression *condition; Name name; Expression *value; std::ostream& doPrint(std::ostream &o, unsigned indent) { - printOpening(o, "br ") << name; - incIndent(o, indent); + if (condition) { + printOpening(o, "br_if"); + incIndent(o, indent); + printFullLine(o, indent, condition); + doIndent(o, indent) << name << '\n'; + } else { + printOpening(o, "br ") << name; + incIndent(o, indent); + } if (value) printFullLine(o, indent, value); return decIndent(o, indent); } @@ -1261,6 +1269,7 @@ struct WasmWalker : public WasmVisitor<void> { } void visitLabel(Label *curr) override {} void visitBreak(Break *curr) override { + parent.walk(curr->condition); parent.walk(curr->value); } void visitSwitch(Switch *curr) override { |