diff options
author | Keith Winstein <keithw@cs.stanford.edu> | 2023-12-05 09:53:44 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-05 09:53:44 -0800 |
commit | 4ce790d24c8ed71a7d23e9a9b4a5fc4ba704d48e (patch) | |
tree | 43980686a0a4c7f3e98998956589085d96d5f641 | |
parent | c3315f035de87b5efef3ce27db0986cd1372d968 (diff) | |
download | wabt-4ce790d24c8ed71a7d23e9a9b4a5fc4ba704d48e.tar.gz wabt-4ce790d24c8ed71a7d23e9a9b4a5fc4ba704d48e.tar.bz2 wabt-4ce790d24c8ed71a7d23e9a9b4a5fc4ba704d48e.zip |
WastParser: tighten parsing of folded `if` (#2349)
This makes the `then` block mandatory per the spec, and parses
multiple foldedinstrs in the `if` predicate (exercised by the new
if.wast test).
-rw-r--r-- | src/wast-parser.cc | 35 | ||||
-rw-r--r-- | test/dump/br-loop-inner.txt | 4 | ||||
-rw-r--r-- | test/parse/expr/bad-if-no-then.txt | 2 | ||||
-rw-r--r-- | test/regress/regress-23.txt | 32 |
4 files changed, 18 insertions, 55 deletions
diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 5d030668..ad4e2e65 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -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; } diff --git a/test/dump/br-loop-inner.txt b/test/dump/br-loop-inner.txt index 2b38abf6..1ac9ae61 100644 --- a/test/dump/br-loop-inner.txt +++ b/test/dump/br-loop-inner.txt @@ -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 diff --git a/test/parse/expr/bad-if-no-then.txt b/test/parse/expr/bad-if-no-then.txt index 46525fe7..437e2ceb 100644 --- a/test/parse/expr/bad-if-no-then.txt +++ b/test/parse/expr/bad-if-no-then.txt @@ -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 ;;) diff --git a/test/regress/regress-23.txt b/test/regress/regress-23.txt index e74c6c2b..8bcf11fa 100644 --- a/test/regress/regress-23.txt +++ b/test/regress/regress-23.txt @@ -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) @@ -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) @@ -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 ;;) |