diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen-s-parser.inc | 8 | ||||
-rw-r--r-- | src/parser/contexts.h | 6 | ||||
-rw-r--r-- | src/parser/parsers.h | 7 | ||||
-rw-r--r-- | src/wasm-ir-builder.h | 2 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 2 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 11 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 4 |
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++; |