[parser] binding arguments var declaration in inner_scope
when has_simple_parameters_ is false in DeclareArguments - According to https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-functiondeclarationinstantiation step 28, arguments var declaration in function should be binding to arguments parameterBindings when has_simple_parameters_ is false. - According to https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-funct> step 18, we should set arguments_ is nullptr if "arguments" is an element of lexicalNames only when has_simple_parameters is true. Bug: v8:12671 Change-Id: I542f80e2c8653ae05b65feb0036e4ade2e653a53 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3499251 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#79382}
This commit is contained in:
parent
4620dbc09e
commit
515c3887ed
@ -747,14 +747,28 @@ void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
|
||||
DCHECK(is_function_scope());
|
||||
DCHECK(!is_arrow_scope());
|
||||
|
||||
// Because when arguments_ is not nullptr, we already declared
|
||||
// "arguments exotic object" to add it into parameters before
|
||||
// impl()->InsertShadowingVarBindingInitializers, so here
|
||||
// only declare "arguments exotic object" when arguments_
|
||||
// is nullptr
|
||||
if (arguments_ != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Declare 'arguments' variable which exists in all non arrow functions. Note
|
||||
// that it might never be accessed, in which case it won't be allocated during
|
||||
// variable allocation.
|
||||
bool was_added;
|
||||
bool was_added = false;
|
||||
|
||||
arguments_ =
|
||||
Declare(zone(), ast_value_factory->arguments_string(), VariableMode::kVar,
|
||||
NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
|
||||
if (!was_added && IsLexicalVariableMode(arguments_->mode())) {
|
||||
// According to ES#sec-functiondeclarationinstantiation step 18
|
||||
// we should set argumentsObjectNeeded to false if has lexical
|
||||
// declared arguments only when hasParameterExpressions is false
|
||||
if (!was_added && IsLexicalVariableMode(arguments_->mode()) &&
|
||||
has_simple_parameters_) {
|
||||
// Check if there's lexically declared variable named arguments to avoid
|
||||
// redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
|
||||
arguments_ = nullptr;
|
||||
|
@ -4405,6 +4405,16 @@ void ParserBase<Impl>::ParseFunctionBody(
|
||||
impl()->ReportVarRedeclarationIn(conflict, inner_scope);
|
||||
}
|
||||
}
|
||||
|
||||
// According to ES#sec-functiondeclarationinstantiation step 27,28
|
||||
// when hasParameterExpressions is true, we need bind var declared
|
||||
// arguments to "arguments exotic object", so we here first declare
|
||||
// "arguments exotic object", then var declared arguments will be
|
||||
// initialized with "arguments exotic object"
|
||||
if (!IsArrowFunction(kind)) {
|
||||
function_scope->DeclareArguments(ast_value_factory());
|
||||
}
|
||||
|
||||
impl()->InsertShadowingVarBindingInitializers(inner_block);
|
||||
}
|
||||
}
|
||||
@ -4413,9 +4423,6 @@ void ParserBase<Impl>::ParseFunctionBody(
|
||||
allow_duplicate_parameters);
|
||||
|
||||
if (!IsArrowFunction(kind)) {
|
||||
// Declare arguments after parsing the function since lexical 'arguments'
|
||||
// masks the arguments object. Declare arguments before declaring the
|
||||
// function var since the arguments object masks 'function arguments'.
|
||||
function_scope->DeclareArguments(ast_value_factory());
|
||||
}
|
||||
|
||||
|
74
test/mjsunit/regress/regress-v8-12671.js
Normal file
74
test/mjsunit/regress/regress-v8-12671.js
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
// spec:
|
||||
// https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html
|
||||
// #sec-functiondeclarationinstantiation
|
||||
|
||||
// This regession focus on checking [var declared "arguments" should bind to
|
||||
// "arguments exotic object" when has_simple_parameters_ is false and
|
||||
// inner_scope has var declared "arguments"]
|
||||
|
||||
|
||||
// according to ES#sec-functiondeclarationinstantiation step 8,
|
||||
// hasParameterExpressions is false, and according to step 15-18,
|
||||
// argumentsObjectNeeded is true, according to step 27,
|
||||
// var declared arguments should bind to arguments exotic object
|
||||
function no_parameters_and_non_lexical_arguments() {
|
||||
assertEquals(typeof arguments, 'object');
|
||||
var arguments;
|
||||
}
|
||||
no_parameters_and_non_lexical_arguments()
|
||||
|
||||
// according to ES#sec-functiondeclarationinstantiation step 8,
|
||||
// hasParameterExpressions is false, and according to step 15-18,
|
||||
// argumentsObjectNeeded is true, according to step 28,
|
||||
// var declared arguments should bind to arguments exotic object
|
||||
function destructuring_parameters_and_non_lexical_arguments([_]) {
|
||||
assertEquals(typeof arguments, 'object');
|
||||
var arguments;
|
||||
}
|
||||
destructuring_parameters_and_non_lexical_arguments([])
|
||||
|
||||
// according to ES#sec-functiondeclarationinstantiation step 8,
|
||||
// hasParameterExpressions is false, and according to step 15-18,
|
||||
// argumentsObjectNeeded is true, according to step 28,
|
||||
// var declared arguments should bind to arguments exotic object
|
||||
function rest_parameters_and_non_lexical_arguments(..._) {
|
||||
assertEquals(typeof arguments, 'object');
|
||||
var arguments;
|
||||
}
|
||||
rest_parameters_and_non_lexical_arguments()
|
||||
|
||||
// according to ES#sec-functiondeclarationinstantiation step 8,
|
||||
// hasParameterExpressions is true, and according to step 15-18,
|
||||
// argumentsObjectNeeded is true, according to step 28,
|
||||
// var declared arguments should bind to arguments exotic object
|
||||
function initializer_parameters_and_non_lexical_arguments(_ = 0) {
|
||||
assertEquals(typeof arguments, 'object');
|
||||
var arguments;
|
||||
}
|
||||
initializer_parameters_and_non_lexical_arguments()
|
||||
|
||||
// according to ES#sec-functiondeclarationinstantiation step 8,
|
||||
// hasParameterExpressions is true, and according to step 15-18,
|
||||
// and argumentsObjectNeeded is true, according to step 34, should
|
||||
// throw because access to let declared arguments
|
||||
function initializer_parameters_and_lexical_arguments(_ = 0) {
|
||||
return typeof arguments;
|
||||
let arguments;
|
||||
}
|
||||
|
||||
assertThrows(initializer_parameters_and_lexical_arguments);
|
||||
|
||||
// according to ES#sec-functiondeclarationinstantiation step 8,
|
||||
// hasParameterExpressions is false, and according to step 15-18,
|
||||
// argumentsObjectNeeded is false, according to step 34,
|
||||
// should throw because access to let declared arguments
|
||||
function simple_parameters_and_lexical_arguments(_) {
|
||||
return typeof arguments;
|
||||
let arguments;
|
||||
}
|
||||
|
||||
assertThrows(simple_parameters_and_lexical_arguments);
|
Loading…
Reference in New Issue
Block a user