summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gen-s-parser.inc8
-rw-r--r--src/parser/contexts.h6
-rw-r--r--src/parser/parsers.h7
-rw-r--r--src/wasm-ir-builder.h2
-rw-r--r--src/wasm-s-parser.h2
-rw-r--r--src/wasm/wasm-ir-builder.cpp11
-rw-r--r--src/wasm/wasm-s-parser.cpp4
7 files changed, 24 insertions, 16 deletions
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 2c284d561..cef0a6b92 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -102,12 +102,12 @@ switch (buf[0]) {
case 'r': {
switch (buf[2]) {
case '\0':
- if (op == "br"sv) { return makeBreak(s); }
+ if (op == "br"sv) { return makeBreak(s, false); }
goto parse_error;
case '_': {
switch (buf[3]) {
case 'i':
- if (op == "br_if"sv) { return makeBreak(s); }
+ if (op == "br_if"sv) { return makeBreak(s, true); }
goto parse_error;
case 'o': {
switch (buf[6]) {
@@ -3749,7 +3749,7 @@ switch (buf[0]) {
switch (buf[2]) {
case '\0':
if (op == "br"sv) {
- CHECK_ERR(makeBreak(ctx, pos));
+ CHECK_ERR(makeBreak(ctx, pos, false));
return Ok{};
}
goto parse_error;
@@ -3757,7 +3757,7 @@ switch (buf[0]) {
switch (buf[3]) {
case 'i':
if (op == "br_if"sv) {
- CHECK_ERR(makeBreak(ctx, pos));
+ CHECK_ERR(makeBreak(ctx, pos, true));
return Ok{};
}
goto parse_error;
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index 1cefb288d..f489a2c05 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -411,7 +411,7 @@ struct NullInstrParserCtx {
Result<> makeCallIndirect(Index, TableIdxT*, TypeUseT, bool) {
return Ok{};
}
- Result<> makeBreak(Index, LabelIdxT) { return Ok{}; }
+ Result<> makeBreak(Index, LabelIdxT, bool) { return Ok{}; }
Result<> makeSwitch(Index, const std::vector<LabelIdxT>&, LabelIdxT) {
return Ok{};
}
@@ -1586,8 +1586,8 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
return withLoc(pos, irBuilder.makeCallIndirect(*t, type, isReturn));
}
- Result<> makeBreak(Index pos, Index label) {
- return withLoc(pos, irBuilder.makeBreak(label));
+ Result<> makeBreak(Index pos, Index label, bool isConditional) {
+ return withLoc(pos, irBuilder.makeBreak(label, isConditional));
}
Result<>
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 601007036..28110a628 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -104,7 +104,7 @@ template<typename Ctx> Result<> makeMemoryFill(Ctx&, Index);
template<typename Ctx> Result<> makePop(Ctx&, Index);
template<typename Ctx> Result<> makeCall(Ctx&, Index, bool isReturn);
template<typename Ctx> Result<> makeCallIndirect(Ctx&, Index, bool isReturn);
-template<typename Ctx> Result<> makeBreak(Ctx&, Index);
+template<typename Ctx> Result<> makeBreak(Ctx&, Index, bool isConditional);
template<typename Ctx> Result<> makeBreakTable(Ctx&, Index);
template<typename Ctx> Result<> makeReturn(Ctx&, Index);
template<typename Ctx> Result<> makeRefNull(Ctx&, Index);
@@ -1432,10 +1432,11 @@ Result<> makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) {
return ctx.makeCallIndirect(pos, table.getPtr(), *type, isReturn);
}
-template<typename Ctx> Result<> makeBreak(Ctx& ctx, Index pos) {
+template<typename Ctx>
+Result<> makeBreak(Ctx& ctx, Index pos, bool isConditional) {
auto label = labelidx(ctx);
CHECK_ERR(label);
- return ctx.makeBreak(pos, *label);
+ return ctx.makeBreak(pos, *label, isConditional);
}
template<typename Ctx> Result<> makeBreakTable(Ctx& ctx, Index pos) {
diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h
index 5add042a6..4b5468014 100644
--- a/src/wasm-ir-builder.h
+++ b/src/wasm-ir-builder.h
@@ -87,7 +87,7 @@ public:
[[nodiscard]] Result<> makeBlock(Name label, Type type);
[[nodiscard]] Result<> makeIf(Name label, Type type);
[[nodiscard]] Result<> makeLoop(Name label, Type type);
- [[nodiscard]] Result<> makeBreak(Index label);
+ [[nodiscard]] Result<> makeBreak(Index label, bool isConditional);
[[nodiscard]] Result<> makeSwitch(const std::vector<Index>& labels,
Index defaultLabel);
// Unlike Builder::makeCall, this assumes the function already exists.
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 7921378de..849632ceb 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -270,7 +270,7 @@ private:
}
enum class LabelType { Break, Exception };
Name getLabel(Element& s, LabelType labelType = LabelType::Break);
- Expression* makeBreak(Element& s);
+ Expression* makeBreak(Element& s, bool isConditional);
Expression* makeBreakTable(Element& s);
Expression* makeReturn(Element& s);
Expression* makeRefNull(Element& s);
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index 43a989c6e..e8a2a2386 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -430,6 +430,11 @@ Result<Expression*> IRBuilder::getBranchValue(Name labelName,
}
Result<> IRBuilder::visitBreak(Break* curr, std::optional<Index> label) {
+ if (curr->condition) {
+ auto cond = pop();
+ CHECK_ERR(cond);
+ curr->condition = *cond;
+ }
auto value = getBranchValue(curr->name, label);
CHECK_ERR(value);
curr->value = *value;
@@ -961,13 +966,15 @@ Result<> IRBuilder::makeLoop(Name label, Type type) {
return visitLoopStart(loop);
}
-Result<> IRBuilder::makeBreak(Index label) {
+Result<> IRBuilder::makeBreak(Index label, bool isConditional) {
auto name = getLabelName(label);
CHECK_ERR(name);
Break curr;
curr.name = *name;
+ // Use a dummy condition value if we need to pop a condition.
+ curr.condition = isConditional ? &curr : nullptr;
CHECK_ERR(visitBreak(&curr, label));
- push(builder.makeBreak(curr.name, curr.value));
+ push(builder.makeBreak(curr.name, curr.value, curr.condition));
return Ok{};
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 9270a19b0..9dbfc88c2 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2580,7 +2580,7 @@ Name SExpressionWasmBuilder::getLabel(Element& s, LabelType labelType) {
}
}
-Expression* SExpressionWasmBuilder::makeBreak(Element& s) {
+Expression* SExpressionWasmBuilder::makeBreak(Element& s, bool isConditional) {
auto ret = allocator.alloc<Break>();
size_t i = 1;
ret->name = getLabel(*s[i]);
@@ -2588,7 +2588,7 @@ Expression* SExpressionWasmBuilder::makeBreak(Element& s) {
if (i == s.size()) {
return ret;
}
- if (elementStartsWith(s, BR_IF)) {
+ if (isConditional) {
if (i + 1 < s.size()) {
ret->value = parseExpression(s[i]);
i++;