Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index e3ce0f0172a4c340c0a904d30c6511b7b9bb476a..69ea36b1038ae6cb7f761ab66695c8b4674c3bc8 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -4676,6 +4676,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| inner_scope = inner_scope->FinalizeBlockScope(); |
| if (inner_scope != nullptr) { |
| CheckConflictingVarDeclarations(inner_scope, CHECK_OK); |
| + InsertShadowingVarBindingInitializers(inner_block); |
| } |
| result->Add(init_block, zone()); |
| @@ -4936,8 +4937,7 @@ Literal* Parser::GetLiteralUndefined(int position) { |
| void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| if (decl != NULL) { |
| - // In harmony mode we treat conflicting variable bindinds as early |
| - // errors. See ES5 16 for a definition of early errors. |
| + // In ES6, conflicting variable bindings are early errors. |
| const AstRawString* name = decl->proxy()->raw_name(); |
| int position = decl->proxy()->position(); |
| Scanner::Location location = position == RelocInfo::kNoPosition |
| @@ -4950,6 +4950,31 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| } |
| +void Parser::InsertShadowingVarBindingInitializers(Block* block) { |
| + // For each var-binding that shadows a parameter, insert an assignment |
| + // initializing the variable with the parameter. |
| + Scope* scope = block->scope(); |
|
adamk
2015/09/29 18:28:29
Can you give this a clearer name than "scope"? "bo
rossberg
2015/09/30 14:50:48
Done.
|
| + DCHECK(scope->is_declaration_scope()); |
| + Scope* function_scope = scope->outer_scope(); |
|
adamk
2015/09/29 18:28:29
And this would be "parameter_scope"? Otherwise, to
rossberg
2015/09/30 14:50:48
I elsewhere used parameter_scope for the (yet diff
|
| + DCHECK(function_scope->is_function_scope()); |
| + ZoneList<Declaration*>* decls = scope->declarations(); |
| + for (int i = 0; i < decls->length(); ++i) { |
| + Declaration* decl = decls->at(i); |
| + if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue; |
| + const AstRawString* name = decl->proxy()->raw_name(); |
| + Variable* parameter = function_scope->LookupLocal(name); |
| + if (parameter == nullptr) continue; |
| + VariableProxy* to = scope->NewUnresolved(factory(), name); |
| + VariableProxy* from = function_scope->NewUnresolved(factory(), name); |
|
adamk
2015/09/29 18:28:29
Given that you already have the parameter Variable
rossberg
2015/09/30 14:50:48
Done.
|
| + Expression* assignment = factory()->NewAssignment( |
| + Token::ASSIGN, to, from, RelocInfo::kNoPosition); |
| + Statement* statement = factory()->NewExpressionStatement( |
| + assignment, RelocInfo::kNoPosition); |
| + block->statements()->InsertAt(0, statement, zone()); |
| + } |
| +} |
| + |
| + |
| void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) { |
| // For each variable which is used as a function declaration in a sloppy |
| // block, |