Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index e3ce0f0172a4c340c0a904d30c6511b7b9bb476a..3d547e6c6bd1562dcb4752529cb6b54322672c62 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* inner_block) { |
+ // For each var-binding that shadows a parameter, insert an assignment |
+ // initializing the variable with the parameter. |
+ Scope* inner_scope = inner_block->scope(); |
+ DCHECK(inner_scope->is_declaration_scope()); |
+ Scope* function_scope = inner_scope->outer_scope(); |
+ DCHECK(function_scope->is_function_scope()); |
+ ZoneList<Declaration*>* decls = inner_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 = inner_scope->NewUnresolved(factory(), name); |
+ VariableProxy* from = factory()->NewVariableProxy(parameter); |
+ Expression* assignment = factory()->NewAssignment( |
+ Token::ASSIGN, to, from, RelocInfo::kNoPosition); |
+ Statement* statement = factory()->NewExpressionStatement( |
+ assignment, RelocInfo::kNoPosition); |
+ inner_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, |