Skip to content

Commit

Permalink
WastParser: tighten parsing of folded if (#2349)
Browse files Browse the repository at this point in the history
This makes the `then` block mandatory per the spec, and parses
multiple foldedinstrs in the `if` predicate (exercised by the new
if.wast test).
  • Loading branch information
keithw committed Dec 5, 2023
1 parent c3315f0 commit 4ce790d
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 55 deletions.
35 changes: 13 additions & 22 deletions src/wast-parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3090,36 +3090,27 @@ Result WastParser::ParseExpr(ExprList* exprs) {
CHECK_RESULT(ParseLabelOpt(&expr->true_.label));
CHECK_RESULT(ParseBlockDeclaration(&expr->true_.decl));

if (PeekMatchExpr()) {
while (PeekMatchExpr()) {
ExprList cond;
CHECK_RESULT(ParseExpr(&cond));
exprs->splice(exprs->end(), cond);
}

if (MatchLpar(TokenType::Then)) {
CHECK_RESULT(ParseTerminatingInstrList(&expr->true_.exprs));
expr->true_.end_loc = GetLocation();
EXPECT(Rpar);

if (MatchLpar(TokenType::Else)) {
CHECK_RESULT(ParseTerminatingInstrList(&expr->false_));
EXPECT(Rpar);
} else if (PeekMatchExpr()) {
CHECK_RESULT(ParseExpr(&expr->false_));
}
expr->false_end_loc = GetLocation();
} else if (PeekMatchExpr()) {
CHECK_RESULT(ParseExpr(&expr->true_.exprs));
expr->true_.end_loc = GetLocation();
if (PeekMatchExpr()) {
CHECK_RESULT(ParseExpr(&expr->false_));
expr->false_end_loc = GetLocation();
}
} else {
ConsumeIfLpar();
EXPECT(Lpar);
if (!Match(TokenType::Then)) {
return ErrorExpected({"then block"}, "(then ...)");
}

CHECK_RESULT(ParseTerminatingInstrList(&expr->true_.exprs));
expr->true_.end_loc = GetLocation();
EXPECT(Rpar);

if (MatchLpar(TokenType::Else)) {
CHECK_RESULT(ParseTerminatingInstrList(&expr->false_));
EXPECT(Rpar);
}
expr->false_end_loc = GetLocation();

exprs->push_back(std::move(expr));
break;
}
Expand Down
4 changes: 2 additions & 2 deletions test/dump/br-loop-inner.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
(func
(block $exit (loop $cont
(if (i32.const 1)
(br $exit))
(then (br $exit)))
(if (i32.const 2)
(br $cont))))))
(then (br $cont)))))))
(;; STDERR ;;;
0000000: 0061 736d ; WASM_BINARY_MAGIC
0000004: 0100 0000 ; WASM_BINARY_VERSION
Expand Down
2 changes: 1 addition & 1 deletion test/parse/expr/bad-if-no-then.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
;;; ERROR: 1
(module (func (if (i32.const 0))))
(;; STDERR ;;;
out/test/parse/expr/bad-if-no-then.txt:3:32: error: unexpected token ")", expected then block (e.g. (then ...)).
out/test/parse/expr/bad-if-no-then.txt:3:32: error: unexpected token ), expected (.
(module (func (if (i32.const 0))))
^
;;; STDERR ;;)
32 changes: 2 additions & 30 deletions test/regress/regress-23.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,6 @@
;; This regression test makes sure that the end_loc of `if` blocks is properly
;; set when using the folded format.

;; if/else shorthand format, error in true branch.
(func (result i32)
(if (result i32)
(i32.const 0)
(block
(unreachable)
)
(i32.const 0)
)
)

;; if/else with `then`/`else` keywords, error in true branch.
(func (result i32)
(if (result i32)
Expand All @@ -30,17 +19,6 @@
)
)

;; if/else shorthand format, error in false branch.
(func (result i32)
(if (result i32)
(i32.const 0)
(i32.const 0)
(block
(unreachable)
)
)
)

;; if/else with `then`/`else` keywords, error in false branch.
(func (result i32)
(if (result i32)
Expand All @@ -56,16 +34,10 @@
)
)
(;; STDERR ;;;
out/test/regress/regress-23.txt:13:5: error: type mismatch in `if true` branch, expected [i32] but got []
)
^
out/test/regress/regress-23.txt:25:7: error: type mismatch in `if true` branch, expected [i32] but got []
out/test/regress/regress-23.txt:14:7: error: type mismatch in `if true` branch, expected [i32] but got []
)
^
out/test/regress/regress-23.txt:41:3: error: type mismatch in `if false` branch, expected [i32] but got []
)
^
out/test/regress/regress-23.txt:56:3: error: type mismatch in `if false` branch, expected [i32] but got []
out/test/regress/regress-23.txt:34:3: error: type mismatch in `if false` branch, expected [i32] but got []
)
^
;;; STDERR ;;)

0 comments on commit 4ce790d

Please sign in to comment.