OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 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.
| |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |