[parser] Already break the expression scope chain for function parameters

Otherwise we'll invalidly propagate information from default function parameters outwards to outer arrow scopes.

Bug: chromium:1060023
Change-Id: Id43ecb5e1d354d5250a80c2a4f7e3129759041d5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2134006
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66964}
This commit is contained in:
Toon Verwaest 2020-04-02 14:26:18 +02:00 committed by Commit Bot
parent 800c294cf1
commit 4561500ee4
4 changed files with 19 additions and 8 deletions

View File

@ -1501,16 +1501,14 @@ class ParserBase {
FormalParametersT* parent_parameters_;
};
class FunctionBodyParsingScope {
class FunctionParsingScope {
public:
explicit FunctionBodyParsingScope(Impl* parser)
explicit FunctionParsingScope(Impl* parser)
: parser_(parser), expression_scope_(parser_->expression_scope_) {
parser_->expression_scope_ = nullptr;
}
~FunctionBodyParsingScope() {
parser_->expression_scope_ = expression_scope_;
}
~FunctionParsingScope() { parser_->expression_scope_ = expression_scope_; }
private:
Impl* parser_;
@ -2437,7 +2435,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassInfo* class_info,
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberInitializer(
ClassInfo* class_info, int beg_pos, bool is_static) {
FunctionBodyParsingScope body_parsing_scope(impl());
FunctionParsingScope body_parsing_scope(impl());
DeclarationScope* initializer_scope =
is_static ? class_info->static_fields_scope
: class_info->instance_members_scope;
@ -4157,8 +4155,6 @@ void ParserBase<Impl>::ParseFunctionBody(
StatementListT* body, IdentifierT function_name, int pos,
const FormalParametersT& parameters, FunctionKind kind,
FunctionSyntaxKind function_syntax_kind, FunctionBodyType body_type) {
FunctionBodyParsingScope body_parsing_scope(impl());
if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();
DeclarationScope* function_scope = parameters.scope;
@ -4435,6 +4431,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
Consume(Token::LBRACE);
AcceptINScope scope(this, true);
FunctionParsingScope body_parsing_scope(impl());
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
parameters, kind,
FunctionSyntaxKind::kAnonymousExpression,
@ -4445,6 +4442,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
} else {
Consume(Token::LBRACE);
AcceptINScope scope(this, true);
FunctionParsingScope body_parsing_scope(impl());
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
formal_parameters, kind,
FunctionSyntaxKind::kAnonymousExpression,
@ -4454,6 +4452,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
} else {
// Single-expression body
has_braces = false;
FunctionParsingScope body_parsing_scope(impl());
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
formal_parameters, kind,
FunctionSyntaxKind::kAnonymousExpression,

View File

@ -2733,6 +2733,7 @@ void Parser::ParseFunction(
bool* has_duplicate_parameters, int* expected_property_count,
int* suspend_count,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
FunctionParsingScope function_parsing_scope(this);
ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
FunctionState function_state(&function_state_, &scope_, function_scope);

View File

@ -268,6 +268,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
int function_token_pos, FunctionSyntaxKind function_syntax_kind,
LanguageMode language_mode,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
FunctionParsingScope function_parsing_scope(this);
// Wrapped functions are not parsed in the preparser.
DCHECK_NULL(arguments_for_wrapped_function);
DCHECK_NE(FunctionSyntaxKind::kWrapped, function_syntax_kind);

View File

@ -0,0 +1,10 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class b extends RegExp {
exec() {
(function() { (a = (function({} = this) {})) => {} })
}
}
assertThrows(()=>'a'.match(new b), TypeError);