Commit 69a82842 authored by Shu-yu Guo's avatar Shu-yu Guo Committed by V8 LUCI CQ

[class] Fix `await`-as-identifier cases in class static blocks

Bug: v8:11718
Change-Id: If903f5e336729fa55bec03acef40025ce20d6ce7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2898176Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74614}
parent 72b4ec49
...@@ -181,6 +181,14 @@ inline bool BindsSuper(FunctionKind kind) { ...@@ -181,6 +181,14 @@ inline bool BindsSuper(FunctionKind kind) {
IsClassConstructor(kind); IsClassConstructor(kind);
} }
inline bool IsAwaitAsIdentifierDisallowed(FunctionKind kind) {
// 'await' is always disallowed as an identifier in module contexts. Callers
// should short-circuit the module case instead of calling this.
DCHECK(!IsModule(kind));
return IsAsyncFunction(kind) ||
kind == FunctionKind::kClassStaticInitializerFunction;
}
inline const char* FunctionKind2String(FunctionKind kind) { inline const char* FunctionKind2String(FunctionKind kind) {
switch (kind) { switch (kind) {
case FunctionKind::kNormalFunction: case FunctionKind::kNormalFunction:
......
...@@ -1060,14 +1060,14 @@ class ParserBase { ...@@ -1060,14 +1060,14 @@ class ParserBase {
bool is_resumable() const { bool is_resumable() const {
return IsResumableFunction(function_state_->kind()); return IsResumableFunction(function_state_->kind());
} }
bool is_class_static_block() const {
return function_state_->kind() ==
FunctionKind::kClassStaticInitializerFunction;
}
bool is_await_allowed() const { bool is_await_allowed() const {
return is_async_function() || (flags().allow_harmony_top_level_await() && return is_async_function() || (flags().allow_harmony_top_level_await() &&
IsModule(function_state_->kind())); IsModule(function_state_->kind()));
} }
bool is_await_as_identifier_disallowed() {
return flags().is_module() ||
IsAwaitAsIdentifierDisallowed(function_state_->kind());
}
const PendingCompilationErrorHandler* pending_error_handler() const { const PendingCompilationErrorHandler* pending_error_handler() const {
return pending_error_handler_; return pending_error_handler_;
} }
...@@ -1652,8 +1652,7 @@ ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) { ...@@ -1652,8 +1652,7 @@ ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) {
} }
if (!Token::IsValidIdentifier(next, language_mode(), is_generator(), if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
flags().is_module() || is_async_function() || is_await_as_identifier_disallowed())) {
is_class_static_block())) {
ReportUnexpectedToken(next); ReportUnexpectedToken(next);
return impl()->EmptyIdentifierString(); return impl()->EmptyIdentifierString();
} }
...@@ -1677,7 +1676,8 @@ typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( ...@@ -1677,7 +1676,8 @@ typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
if (!Token::IsValidIdentifier( if (!Token::IsValidIdentifier(
next, language_mode(), IsGeneratorFunction(function_kind), next, language_mode(), IsGeneratorFunction(function_kind),
flags().is_module() || IsAsyncFunction(function_kind))) { flags().is_module() ||
IsAwaitAsIdentifierDisallowed(function_kind))) {
ReportUnexpectedToken(next); ReportUnexpectedToken(next);
return impl()->EmptyIdentifierString(); return impl()->EmptyIdentifierString();
} }
...@@ -2570,9 +2570,8 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info, ...@@ -2570,9 +2570,8 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info,
// IdentifierReference Initializer? // IdentifierReference Initializer?
DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal); DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
if (!Token::IsValidIdentifier( if (!Token::IsValidIdentifier(name_token, language_mode(), is_generator(),
name_token, language_mode(), is_generator(), is_await_as_identifier_disallowed())) {
flags().is_module() || is_async_function())) {
ReportUnexpectedToken(Next()); ReportUnexpectedToken(Next());
return impl()->NullLiteralProperty(); return impl()->NullLiteralProperty();
} }
......
...@@ -113,6 +113,11 @@ ...@@ -113,6 +113,11 @@
assertArrayEquals([undefined], log); assertArrayEquals([undefined], log);
} }
{
// 'await' is allowed as an identifier name in named function expressions.
class C { static { (function await() {}); } }
}
function assertDoesntParse(expr, context_start, context_end) { function assertDoesntParse(expr, context_start, context_end) {
assertThrows(() => { assertThrows(() => {
eval(`${context_start} class C { static { ${expr} } } ${context_end}`); eval(`${context_start} class C { static { ${expr} } } ${context_end}`);
...@@ -131,4 +136,10 @@ for (let [s, e] of [['', ''], ...@@ -131,4 +136,10 @@ for (let [s, e] of [['', ''],
// 'await' is disallowed as an identifier. // 'await' is disallowed as an identifier.
assertDoesntParse('let await;', s, e); assertDoesntParse('let await;', s, e);
assertDoesntParse('await;', s, e); assertDoesntParse('await;', s, e);
assertDoesntParse('function await() {}', s, e);
assertDoesntParse('class await() {}', s, e);
assertDoesntParse('try {} catch (await) {}', s, e);
assertDoesntParse('try {} catch ({await}) {}', s, e);
assertDoesntParse('var {await} = 0;', s, e);
assertDoesntParse('({await} = 0);', s, e);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment