| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index 261de4eed78e2021a3c8ff4dfa21dd7513bcb977..56199b980a30912a1f9ed0d0561d2ab4d8b27db7 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 eval or another function.
|
| 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
|
|
|