summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wasm-interpreter.h17
-rw-r--r--src/wasm-s-parser.h17
-rw-r--r--src/wasm.h15
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 {