Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index 261de4eed78e2021a3c8ff4dfa21dd7513bcb977..013da49e6048982b3f70b61f95cd540a803e6c52 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -1708,15 +1708,14 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
| // Declare the name. |
| var = declaration_scope->DeclareLocal( |
| name, mode, declaration->initialization(), proxy->interface()); |
| - } else if ((mode != VAR || var->mode() != VAR) && |
| - (!declaration_scope->is_global_scope() || |
| - IsLexicalVariableMode(mode) || |
| - IsLexicalVariableMode(var->mode()))) { |
| + } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode()) |
| + || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && |
| + !declaration_scope->is_global_scope())) { |
| // The name was declared in this scope before; check for conflicting |
| // re-declarations. We have a conflict if either of the declarations is |
| // not a var (in the global scope, we also have to ignore legacy const for |
| // compatibility). There is similar code in runtime.cc in the Declare |
| - // functions. The function CheckNonConflictingScope checks for conflicting |
| + // functions. The function CheckConflictingVarDeclarations checks for |
| // var and let bindings from different scopes whereas this is a check for |
| // conflicting declarations within the same scope. This check also covers |
| // the special case |
| @@ -1899,11 +1898,12 @@ Statement* Parser::ParseFunctionDeclaration( |
| // Even if we're not at the top-level of the global or a function |
| // scope, we treat it as such and introduce the function with its |
| // initial value upon entering the corresponding scope. |
| - // In extended mode, a function behaves as a lexical binding, except in the |
| - // global scope. |
| + // In ES6, a function behaves as a lexical binding, except in the |
| + // global scope, or the initial scope of another function. |
|
ulan
2014/07/09 08:49:32
The comment doesn't mention the eval scope case.
rossberg
2014/07/09 11:30:41
Done.
|
| VariableMode mode = |
| - allow_harmony_scoping() && |
| - strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
| + allow_harmony_scoping() && strict_mode() == STRICT && |
| + !(scope_->is_global_scope() || scope_->is_eval_scope() || |
| + scope_->is_function_scope()) ? LET : VAR; |
| VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| Declaration* declaration = |
| factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| @@ -2212,9 +2212,8 @@ Block* Parser::ParseVariableDeclarations( |
| // executed. |
| // |
| // Executing the variable declaration statement will always |
| - // guarantee to give the global object a "local" variable; a |
| - // variable defined in the global object and not in any |
| - // prototype. This way, global variable declarations can shadow |
| + // guarantee to give the global object an own property. |
| + // This way, global variable declarations can shadow |
| // properties in the prototype chain, but only after the variable |
| // declaration statement has been executed. This is important in |
| // browsers where the global object (window) has lots of |
| @@ -3556,10 +3555,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| } |
| ast_properties = *factory()->visitor()->ast_properties(); |
| dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); |
| - } |
| - if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| - CheckConflictingVarDeclarations(scope, CHECK_OK); |
| + if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| + CheckConflictingVarDeclarations(scope, CHECK_OK); |
| + } |
| } |
| FunctionLiteral::IsGeneratorFlag generator = is_generator |