Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/parser.cc

Issue 377513006: Fix several issues with ES6 redeclaration checks (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/harmony/block-conflicts.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 // For the global scope, we have to check for collisions with earlier 1701 // For the global scope, we have to check for collisions with earlier
1702 // (i.e., enclosing) global scopes, to maintain the illusion of a single 1702 // (i.e., enclosing) global scopes, to maintain the illusion of a single
1703 // global scope. 1703 // global scope.
1704 var = declaration_scope->is_global_scope() 1704 var = declaration_scope->is_global_scope()
1705 ? declaration_scope->Lookup(name) 1705 ? declaration_scope->Lookup(name)
1706 : declaration_scope->LookupLocal(name); 1706 : declaration_scope->LookupLocal(name);
1707 if (var == NULL) { 1707 if (var == NULL) {
1708 // Declare the name. 1708 // Declare the name.
1709 var = declaration_scope->DeclareLocal( 1709 var = declaration_scope->DeclareLocal(
1710 name, mode, declaration->initialization(), proxy->interface()); 1710 name, mode, declaration->initialization(), proxy->interface());
1711 } else if ((mode != VAR || var->mode() != VAR) && 1711 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
1712 (!declaration_scope->is_global_scope() || 1712 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1713 IsLexicalVariableMode(mode) || 1713 !declaration_scope->is_global_scope())) {
1714 IsLexicalVariableMode(var->mode()))) {
1715 // The name was declared in this scope before; check for conflicting 1714 // The name was declared in this scope before; check for conflicting
1716 // re-declarations. We have a conflict if either of the declarations is 1715 // re-declarations. We have a conflict if either of the declarations is
1717 // not a var (in the global scope, we also have to ignore legacy const for 1716 // not a var (in the global scope, we also have to ignore legacy const for
1718 // compatibility). There is similar code in runtime.cc in the Declare 1717 // compatibility). There is similar code in runtime.cc in the Declare
1719 // functions. The function CheckNonConflictingScope checks for conflicting 1718 // functions. The function CheckConflictingVarDeclarations checks for
1720 // var and let bindings from different scopes whereas this is a check for 1719 // var and let bindings from different scopes whereas this is a check for
1721 // conflicting declarations within the same scope. This check also covers 1720 // conflicting declarations within the same scope. This check also covers
1722 // the special case 1721 // the special case
1723 // 1722 //
1724 // function () { let x; { var x; } } 1723 // function () { let x; { var x; } }
1725 // 1724 //
1726 // because the var declaration is hoisted to the function scope where 'x' 1725 // because the var declaration is hoisted to the function scope where 'x'
1727 // is already bound. 1726 // is already bound.
1728 ASSERT(IsDeclaredVariableMode(var->mode())); 1727 ASSERT(IsDeclaredVariableMode(var->mode()));
1729 if (allow_harmony_scoping() && strict_mode() == STRICT) { 1728 if (allow_harmony_scoping() && strict_mode() == STRICT) {
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 scanner()->location(), 1891 scanner()->location(),
1893 is_strict_reserved, 1892 is_strict_reserved,
1894 is_generator, 1893 is_generator,
1895 pos, 1894 pos,
1896 FunctionLiteral::DECLARATION, 1895 FunctionLiteral::DECLARATION,
1897 FunctionLiteral::NORMAL_ARITY, 1896 FunctionLiteral::NORMAL_ARITY,
1898 CHECK_OK); 1897 CHECK_OK);
1899 // Even if we're not at the top-level of the global or a function 1898 // Even if we're not at the top-level of the global or a function
1900 // scope, we treat it as such and introduce the function with its 1899 // scope, we treat it as such and introduce the function with its
1901 // initial value upon entering the corresponding scope. 1900 // initial value upon entering the corresponding scope.
1902 // In extended mode, a function behaves as a lexical binding, except in the 1901 // In ES6, a function behaves as a lexical binding, except in the
1903 // global scope. 1902 // global scope, or the initial scope of eval or another function.
1904 VariableMode mode = 1903 VariableMode mode =
1905 allow_harmony_scoping() && 1904 allow_harmony_scoping() && strict_mode() == STRICT &&
1906 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; 1905 !(scope_->is_global_scope() || scope_->is_eval_scope() ||
1906 scope_->is_function_scope()) ? LET : VAR;
1907 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); 1907 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1908 Declaration* declaration = 1908 Declaration* declaration =
1909 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); 1909 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
1910 Declare(declaration, true, CHECK_OK); 1910 Declare(declaration, true, CHECK_OK);
1911 if (names) names->Add(name, zone()); 1911 if (names) names->Add(name, zone());
1912 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1912 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1913 } 1913 }
1914 1914
1915 1915
1916 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { 1916 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 // is entered, the global variable must be declared, so that if it 2205 // is entered, the global variable must be declared, so that if it
2206 // doesn't exist (on the global object itself, see ES5 errata) it 2206 // doesn't exist (on the global object itself, see ES5 errata) it
2207 // gets created with an initial undefined value. This is handled 2207 // gets created with an initial undefined value. This is handled
2208 // by the declarations part of the function representing the 2208 // by the declarations part of the function representing the
2209 // top-level global code; see Runtime::DeclareGlobalVariable. If 2209 // top-level global code; see Runtime::DeclareGlobalVariable. If
2210 // it already exists (in the object or in a prototype), it is 2210 // it already exists (in the object or in a prototype), it is
2211 // *not* touched until the variable declaration statement is 2211 // *not* touched until the variable declaration statement is
2212 // executed. 2212 // executed.
2213 // 2213 //
2214 // Executing the variable declaration statement will always 2214 // Executing the variable declaration statement will always
2215 // guarantee to give the global object a "local" variable; a 2215 // guarantee to give the global object an own property.
2216 // variable defined in the global object and not in any 2216 // This way, global variable declarations can shadow
2217 // prototype. This way, global variable declarations can shadow
2218 // properties in the prototype chain, but only after the variable 2217 // properties in the prototype chain, but only after the variable
2219 // declaration statement has been executed. This is important in 2218 // declaration statement has been executed. This is important in
2220 // browsers where the global object (window) has lots of 2219 // browsers where the global object (window) has lots of
2221 // properties defined in prototype objects. 2220 // properties defined in prototype objects.
2222 if (initialization_scope->is_global_scope() && 2221 if (initialization_scope->is_global_scope() &&
2223 !IsLexicalVariableMode(mode)) { 2222 !IsLexicalVariableMode(mode)) {
2224 // Compute the arguments for the runtime call. 2223 // Compute the arguments for the runtime call.
2225 ZoneList<Expression*>* arguments = 2224 ZoneList<Expression*>* arguments =
2226 new(zone()) ZoneList<Expression*>(3, zone()); 2225 new(zone()) ZoneList<Expression*>(3, zone());
2227 // We have at least 1 parameter. 2226 // We have at least 1 parameter.
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after
3549 eval_args_error_log, 3548 eval_args_error_log,
3550 dupe_error_loc, 3549 dupe_error_loc,
3551 reserved_loc, 3550 reserved_loc,
3552 CHECK_OK); 3551 CHECK_OK);
3553 CheckOctalLiteral(scope->start_position(), 3552 CheckOctalLiteral(scope->start_position(),
3554 scope->end_position(), 3553 scope->end_position(),
3555 CHECK_OK); 3554 CHECK_OK);
3556 } 3555 }
3557 ast_properties = *factory()->visitor()->ast_properties(); 3556 ast_properties = *factory()->visitor()->ast_properties();
3558 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); 3557 dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
3559 }
3560 3558
3561 if (allow_harmony_scoping() && strict_mode() == STRICT) { 3559 if (allow_harmony_scoping() && strict_mode() == STRICT) {
3562 CheckConflictingVarDeclarations(scope, CHECK_OK); 3560 CheckConflictingVarDeclarations(scope, CHECK_OK);
3561 }
3563 } 3562 }
3564 3563
3565 FunctionLiteral::IsGeneratorFlag generator = is_generator 3564 FunctionLiteral::IsGeneratorFlag generator = is_generator
3566 ? FunctionLiteral::kIsGenerator 3565 ? FunctionLiteral::kIsGenerator
3567 : FunctionLiteral::kNotGenerator; 3566 : FunctionLiteral::kNotGenerator;
3568 FunctionLiteral* function_literal = 3567 FunctionLiteral* function_literal =
3569 factory()->NewFunctionLiteral(function_name, 3568 factory()->NewFunctionLiteral(function_name,
3570 ast_value_factory_, 3569 ast_value_factory_,
3571 scope, 3570 scope,
3572 body, 3571 body,
(...skipping 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after
4866 info()->SetAstValueFactory(ast_value_factory_); 4865 info()->SetAstValueFactory(ast_value_factory_);
4867 } 4866 }
4868 ast_value_factory_ = NULL; 4867 ast_value_factory_ = NULL;
4869 4868
4870 InternalizeUseCounts(); 4869 InternalizeUseCounts();
4871 4870
4872 return (result != NULL); 4871 return (result != NULL);
4873 } 4872 }
4874 4873
4875 } } // namespace v8::internal 4874 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/harmony/block-conflicts.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698