Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index 753391193bf03667a685a24161b83e53ca3ecbda..4faec3d84b7c291e2589d1d12f9ae96d715d2c62 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -1993,7 +1993,7 @@ VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
| Variable* Parser::Declare(Declaration* declaration, |
| DeclarationDescriptor::Kind declaration_kind, |
| - bool resolve, bool* ok) { |
| + bool report_error, bool* ok) { |
|
arv (Not doing code reviews)
2015/07/10 16:56:33
Turned out that all callers always passed resolve
|
| VariableProxy* proxy = declaration->proxy(); |
| DCHECK(proxy->raw_name() != NULL); |
| const AstRawString* name = proxy->raw_name(); |
| @@ -2052,10 +2052,13 @@ Variable* Parser::Declare(Declaration* declaration, |
| if (is_strict(language_mode()) || allow_harmony_sloppy()) { |
| // In harmony we treat re-declarations as early errors. See |
| // ES5 16 for a definition of early errors. |
| - if (declaration_kind == DeclarationDescriptor::NORMAL) { |
| - ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name); |
| - } else { |
| - ParserTraits::ReportMessage(MessageTemplate::kStrictParamDupe); |
| + if (report_error) { |
| + if (declaration_kind == DeclarationDescriptor::NORMAL) { |
| + ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, |
| + name); |
| + } else { |
| + ParserTraits::ReportMessage(MessageTemplate::kStrictParamDupe); |
| + } |
| } |
| *ok = false; |
| return nullptr; |
| @@ -2088,7 +2091,6 @@ Variable* Parser::Declare(Declaration* declaration, |
| if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) { |
| // For global const variables we bind the proxy to a variable. |
| - DCHECK(resolve); // should be set by all callers |
| Variable::Kind kind = Variable::NORMAL; |
| var = new (zone()) Variable(declaration_scope, name, mode, kind, |
| kNeedsInitialization, kNotAssigned); |
| @@ -2102,7 +2104,6 @@ Variable* Parser::Declare(Declaration* declaration, |
| var = new (zone()) Variable(declaration_scope, name, mode, kind, |
| declaration->initialization(), kNotAssigned); |
| var->AllocateTo(VariableLocation::LOOKUP, -1); |
| - resolve = true; |
| } |
| // If requested and we have a local variable, bind the proxy to the variable |
| @@ -2129,7 +2130,7 @@ Variable* Parser::Declare(Declaration* declaration, |
| // initialization code. Thus, inside the 'with' statement, we need |
| // both access to the static and the dynamic context chain; the |
| // runtime needs to provide both. |
| - if (resolve && var != NULL) { |
| + if (var != NULL) { |
| proxy->BindTo(var); |
| } |
| return var; |
| @@ -2217,6 +2218,29 @@ Statement* Parser::ParseFunctionDeclaration( |
| factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| if (names) names->Add(name, zone()); |
| + |
| + // For sloppy function in block we also add a var binding that gets assigned |
| + // to at the location of the FunctionDeclaration -- but only if introducing |
| + // this var binding does not lead to an early error. |
| + if (is_sloppy(language_mode()) && scope_->is_block_scope() && |
| + allow_harmony_sloppy()) { |
| + VariableProxy* var_proxy = NewUnresolved(name, VAR); |
| + Declaration* declaration = |
| + factory()->NewVariableDeclaration(var_proxy, VAR, scope_, pos); |
| + bool var_ok = true; |
| + const bool report_error = false; |
| + Declare(declaration, DeclarationDescriptor::NORMAL, report_error, &var_ok); |
| + if (!var_ok) { |
| + scope_->RemoveUnresolved(var_proxy); |
| + } else { |
| + // At the location of the FunctionDeclaration we assign to the var |
| + // binding. |
| + Assignment* assignment = factory()->NewAssignment( |
| + Token::ASSIGN, var_proxy, NewUnresolved(name, mode), pos); |
| + return factory()->NewExpressionStatement(assignment, |
| + RelocInfo::kNoPosition); |
| + } |
| + } |
| return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| } |