From d327cbea9aef5b97bb456e2a55e9463dc81b571c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Thu, 5 Jun 2025 09:51:08 +0200 Subject: [PATCH] deps: V8: cherry-pick 249de887a8d3 Original commit message: [explicit-resource-management] Fix parsing for (using of=null;;) Apparently `using of` is allowed in the initializer position of C-style for loops. See https://github.com/tc39/proposal-explicit-resource-management/issues/248 Bug: 42203506 Change-Id: Ia056b161f4ea28a0f3ba4e3e420f1718195274a4 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6594471 Commit-Queue: Shu-yu Guo Reviewed-by: Rezvan Mahdavi Hezaveh Cr-Commit-Position: refs/heads/main@{#100531} Refs: https://github.com/v8/v8/commit/249de887a8d317357ab5a27640e849787e498c06 PR-URL: https://github.com/nodejs/node/pull/58561 Reviewed-By: Richard Lau Reviewed-By: Rafael Gonzaga --- common.gypi | 2 +- deps/v8/src/parsing/parser-base.h | 22 ++++++++++++++----- .../harmony/for-using-of-await-using-of.js | 2 ++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/common.gypi b/common.gypi index d776f69d752..cbe454d9bb0 100644 --- a/common.gypi +++ b/common.gypi @@ -38,7 +38,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.12', + 'v8_embedder_string': '-node.13', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h index 55452b28675..b71cf5cac9a 100644 --- a/deps/v8/src/parsing/parser-base.h +++ b/deps/v8/src/parsing/parser-base.h @@ -1178,15 +1178,16 @@ class ParserBase { scope()->scope_type() == REPL_MODE_SCOPE) && !scope()->is_nonlinear()); } - bool IsNextUsingKeyword(Token::Value token_after_using, bool is_await_using) { + bool IsNextUsingKeyword(bool is_await_using) { // using and await using declarations in for-of statements must be followed - // by a non-pattern ForBinding. In the case of synchronous `using`, `of` is - // disallowed as well with a negative lookahead. + // by a non-pattern ForBinding. // // `of`: for ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using] // of AssignmentExpression[+In, ?Yield, ?Await] ) // // If `using` is not considered a keyword, it is parsed as an identifier. + Token::Value token_after_using = + is_await_using ? PeekAheadAhead() : PeekAhead(); if (v8_flags.js_explicit_resource_management) { switch (token_after_using) { case Token::kIdentifier: @@ -1201,7 +1202,16 @@ class ParserBase { case Token::kAsync: return true; case Token::kOf: - return is_await_using; + if (is_await_using) { + return true; + } else { + // In the case of synchronous `using`, `of` is disallowed as well + // with a negative lookahead for for-of loops. But, cursedly, + // `using of` is allowed as the initializer of C-style for loops, + // e.g. `for (using of = null;;)` parses. + Token::Value token_after_of = PeekAheadAhead(); + return token_after_of == Token::kAssign; + } case Token::kFutureStrictReservedWord: case Token::kEscapedStrictReservedWord: return is_sloppy(language_mode()); @@ -1220,12 +1230,12 @@ class ParserBase { // LineTerminator here] ForBinding[?Yield, +Await, ~Pattern] return ((peek() == Token::kUsing && !scanner()->HasLineTerminatorAfterNext() && - IsNextUsingKeyword(PeekAhead(), /* is_await_using */ false)) || + IsNextUsingKeyword(/* is_await_using */ false)) || (is_await_allowed() && peek() == Token::kAwait && !scanner()->HasLineTerminatorAfterNext() && PeekAhead() == Token::kUsing && !scanner()->HasLineTerminatorAfterNextNext() && - IsNextUsingKeyword(PeekAheadAhead(), /* is_await_using */ true))); + IsNextUsingKeyword(/* is_await_using */ true))); } const PendingCompilationErrorHandler* pending_error_handler() const { return pending_error_handler_; diff --git a/deps/v8/test/mjsunit/harmony/for-using-of-await-using-of.js b/deps/v8/test/mjsunit/harmony/for-using-of-await-using-of.js index 0877208fdbc..e990e517b1a 100644 --- a/deps/v8/test/mjsunit/harmony/for-using-of-await-using-of.js +++ b/deps/v8/test/mjsunit/harmony/for-using-of-await-using-of.js @@ -93,4 +93,6 @@ const reservedWords = for (using using of[]) {} for (using async of []) {} for (using foo of []) {} + // Cursedly, `using of` is a valid binding form in C-style for loops. + for (using of = null;;) break; })();