Skip to content
This repository has been archived by the owner on Mar 25, 2018. It is now read-only.

Commit

Permalink
Reland - Allow lexically declared "arguments" in function scope in sl…
Browse files Browse the repository at this point in the history
…oppy mode.

Lexically declared "arguments" in sloppy mode will throw redeclaration error
currently, this patch fixes it by delaying the declaration of arguments until we
fully parse parameter list and function body.

BUG=v8:4577
LOG=N

Committed: https://crrev.com/70a613dd0a5f5d205b46559b55702764464851fa
Review-Url: https://codereview.chromium.org/2290753003
Cr-Original-Commit-Position: refs/heads/master@{#39109}
Cr-Commit-Position: refs/heads/master@{#39230}
  • Loading branch information
lpy authored and Commit bot committed Sep 7, 2016
1 parent 332bd5e commit 7a38b92
Show file tree
Hide file tree
Showing 11 changed files with 360 additions and 304 deletions.
30 changes: 22 additions & 8 deletions src/ast/scopes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -488,15 +488,32 @@ void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
receiver_ = var;
}

void DeclarationScope::DeclareDefaultFunctionVariables(
AstValueFactory* ast_value_factory) {
void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
DCHECK(is_function_scope());
DCHECK(!is_arrow_scope());

// Check if there's lexically declared variable named arguments to avoid
// redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
Variable* arg_variable = LookupLocal(ast_value_factory->arguments_string());
if (arg_variable != nullptr && IsLexicalVariableMode(arg_variable->mode())) {
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.
arguments_ = Declare(zone(), this, ast_value_factory->arguments_string(), VAR,
Variable::ARGUMENTS, kCreatedInitialized);
if (arg_variable == nullptr) {
arguments_ = Declare(zone(), this, ast_value_factory->arguments_string(),
VAR, Variable::ARGUMENTS, kCreatedInitialized);
} else {
arguments_ = arg_variable;
}
}

void DeclarationScope::DeclareDefaultFunctionVariables(
AstValueFactory* ast_value_factory) {
DCHECK(is_function_scope());
DCHECK(!is_arrow_scope());

new_target_ = Declare(zone(), this, ast_value_factory->new_target_string(),
CONST, Variable::NORMAL, kCreatedInitialized);
Expand Down Expand Up @@ -1524,8 +1541,8 @@ void DeclarationScope::AllocateParameterLocals() {

bool uses_sloppy_arguments = false;

// Functions have 'arguments' declared implicitly in all non arrow functions.
if (arguments_ != nullptr) {
DCHECK(!is_arrow_scope());
// 'arguments' is used. Unless there is also a parameter called
// 'arguments', we must be conservative and allocate all parameters to
// the context assuming they will be captured by the arguments object.
Expand All @@ -1546,9 +1563,6 @@ void DeclarationScope::AllocateParameterLocals() {
// allocate the arguments object by nulling out arguments_.
arguments_ = nullptr;
}

} else {
DCHECK(is_arrow_scope());
}

// The same parameter may occur multiple times in the parameters_ list.
Expand Down
1 change: 1 addition & 0 deletions src/ast/scopes.h
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ class DeclarationScope : public Scope {
void set_asm_function() { asm_module_ = true; }

void DeclareThis(AstValueFactory* ast_value_factory);
void DeclareArguments(AstValueFactory* ast_value_factory);
void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory);

// This lookup corresponds to a lookup in the "intermediate" scope sitting
Expand Down
4 changes: 4 additions & 0 deletions src/parsing/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3555,6 +3555,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(

// Parsing the body may change the language mode in our scope.
language_mode = scope->language_mode();
scope->DeclareArguments(ast_value_factory());
if (main_scope != scope) {
main_scope->DeclareArguments(ast_value_factory());
}

// Validate name and parameter names. We can do this only after parsing the
// function, since the function can declare itself strict.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ bytecodes: [
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),
B(CreateMappedArguments),
B(StaContextSlot), R(context), U8(5),
B(Ldar), R(new_target),
B(StaContextSlot), R(context), U8(6),
B(Ldar), R(new_target),
B(StaContextSlot), R(context), U8(5),
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateClosure), U8(0), U8(2),
/* 36 E> */ B(StaLookupSlotSloppy), U8(1),
Expand Down
Loading

0 comments on commit 7a38b92

Please sign in to comment.