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

Side by Side Diff: src/parser.cc

Issue 716833002: Various clean-ups after top-level lexical declarations are done. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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
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/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 } 897 }
898 898
899 899
900 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, 900 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
901 Scope** eval_scope) { 901 Scope** eval_scope) {
902 DCHECK(scope_ == NULL); 902 DCHECK(scope_ == NULL);
903 DCHECK(target_stack_ == NULL); 903 DCHECK(target_stack_ == NULL);
904 904
905 FunctionLiteral* result = NULL; 905 FunctionLiteral* result = NULL;
906 { 906 {
907 *scope = NewScope(scope_, GLOBAL_SCOPE); 907 *scope = NewScope(scope_, SCRIPT_SCOPE);
908 info->SetGlobalScope(*scope); 908 info->SetScriptScope(*scope);
909 if (!info->context().is_null() && !info->context()->IsNativeContext()) { 909 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
910 *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone()); 910 *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone());
rossberg 2014/11/12 09:49:27 Might be worth having an assertion after this:
Dmitry Lomov (no reviews) 2014/11/12 10:16:26 Done.
911 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this 911 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
912 // means the Parser cannot operate independent of the V8 heap. Tell the 912 // means the Parser cannot operate independent of the V8 heap. Tell the
913 // string table to internalize strings and values right after they're 913 // string table to internalize strings and values right after they're
914 // created. 914 // created.
915 ast_value_factory()->Internalize(isolate()); 915 ast_value_factory()->Internalize(isolate());
916 } 916 }
917 original_scope_ = *scope; 917 original_scope_ = *scope;
918 if (info->is_eval()) { 918 if (info->is_eval()) {
919 if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) { 919 if (!(*scope)->is_script_scope() || info->strict_mode() == STRICT) {
920 *scope = NewScope(*scope, EVAL_SCOPE); 920 *scope = NewScope(*scope, EVAL_SCOPE);
921 } 921 }
922 } else if (info->is_global()) { 922 } else if (info->is_global()) {
923 *scope = NewScope(*scope, GLOBAL_SCOPE); 923 *scope = NewScope(*scope, SCRIPT_SCOPE);
924 } 924 }
925 (*scope)->set_start_position(0); 925 (*scope)->set_start_position(0);
926 // End position will be set by the caller. 926 // End position will be set by the caller.
927 927
928 // Compute the parsing mode. 928 // Compute the parsing mode.
929 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 929 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
930 if (allow_natives_syntax() || extension_ != NULL || 930 if (allow_natives_syntax() || extension_ != NULL ||
931 (*scope)->is_eval_scope()) { 931 (*scope)->is_eval_scope()) {
932 mode = PARSE_EAGERLY; 932 mode = PARSE_EAGERLY;
933 } 933 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 const AstRawString* raw_name = ast_value_factory()->GetString(name); 1035 const AstRawString* raw_name = ast_value_factory()->GetString(name);
1036 fni_->PushEnclosingName(raw_name); 1036 fni_->PushEnclosingName(raw_name);
1037 1037
1038 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 1038 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1039 1039
1040 // Place holder for the result. 1040 // Place holder for the result.
1041 FunctionLiteral* result = NULL; 1041 FunctionLiteral* result = NULL;
1042 1042
1043 { 1043 {
1044 // Parse the function literal. 1044 // Parse the function literal.
1045 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); 1045 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
1046 info()->SetGlobalScope(scope); 1046 info()->SetScriptScope(scope);
1047 if (!info()->closure().is_null()) { 1047 if (!info()->closure().is_null()) {
1048 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, 1048 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
1049 zone()); 1049 zone());
1050 } 1050 }
1051 original_scope_ = scope; 1051 original_scope_ = scope;
1052 AstNodeFactory<AstConstructionVisitor> function_factory( 1052 AstNodeFactory<AstConstructionVisitor> function_factory(
1053 ast_value_factory()); 1053 ast_value_factory());
1054 FunctionState function_state(&function_state_, &scope_, scope, 1054 FunctionState function_state(&function_state_, &scope_, scope,
1055 &function_factory); 1055 &function_factory);
1056 DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); 1056 DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 literal->raw_value()->AsString() == 1140 literal->raw_value()->AsString() ==
1141 ast_value_factory()->use_strict_string() && 1141 ast_value_factory()->use_strict_string() &&
1142 token_loc.end_pos - token_loc.beg_pos == 1142 token_loc.end_pos - token_loc.beg_pos ==
1143 ast_value_factory()->use_strict_string()->length() + 2) { 1143 ast_value_factory()->use_strict_string()->length() + 2) {
1144 // TODO(mstarzinger): Global strict eval calls, need their own scope 1144 // TODO(mstarzinger): Global strict eval calls, need their own scope
1145 // as specified in ES5 10.4.2(3). The correct fix would be to always 1145 // as specified in ES5 10.4.2(3). The correct fix would be to always
1146 // add this scope in DoParseProgram(), but that requires adaptations 1146 // add this scope in DoParseProgram(), but that requires adaptations
1147 // all over the code base, so we go with a quick-fix for now. 1147 // all over the code base, so we go with a quick-fix for now.
1148 // In the same manner, we have to patch the parsing mode. 1148 // In the same manner, we have to patch the parsing mode.
1149 if (is_eval && !scope_->is_eval_scope()) { 1149 if (is_eval && !scope_->is_eval_scope()) {
1150 DCHECK(scope_->is_global_scope()); 1150 DCHECK(scope_->is_script_scope());
1151 Scope* scope = NewScope(scope_, EVAL_SCOPE); 1151 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1152 scope->set_start_position(scope_->start_position()); 1152 scope->set_start_position(scope_->start_position());
1153 scope->set_end_position(scope_->end_position()); 1153 scope->set_end_position(scope_->end_position());
1154 scope_ = scope; 1154 scope_ = scope;
1155 if (eval_scope != NULL) { 1155 if (eval_scope != NULL) {
1156 // Caller will correct the positions of the ad hoc eval scope. 1156 // Caller will correct the positions of the ad hoc eval scope.
1157 *eval_scope = scope; 1157 *eval_scope = scope;
1158 } 1158 }
1159 mode_ = PARSE_EAGERLY; 1159 mode_ = PARSE_EAGERLY;
1160 } 1160 }
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 // will be added to the scope so that the declaration can be added 1774 // will be added to the scope so that the declaration can be added
1775 // to the corresponding activation frame at runtime if necessary. 1775 // to the corresponding activation frame at runtime if necessary.
1776 // For instance declarations inside an eval scope need to be added 1776 // For instance declarations inside an eval scope need to be added
1777 // to the calling function context. 1777 // to the calling function context.
1778 // Similarly, strict mode eval scope does not leak variable declarations to 1778 // Similarly, strict mode eval scope does not leak variable declarations to
1779 // the caller's scope so we declare all locals, too. 1779 // the caller's scope so we declare all locals, too.
1780 if (declaration_scope->is_function_scope() || 1780 if (declaration_scope->is_function_scope() ||
1781 declaration_scope->is_strict_eval_scope() || 1781 declaration_scope->is_strict_eval_scope() ||
1782 declaration_scope->is_block_scope() || 1782 declaration_scope->is_block_scope() ||
1783 declaration_scope->is_module_scope() || 1783 declaration_scope->is_module_scope() ||
1784 declaration_scope->is_global_scope()) { 1784 declaration_scope->is_script_scope()) {
1785 // Declare the variable in the declaration scope. 1785 // Declare the variable in the declaration scope.
1786 // For the global scope, we have to check for collisions with earlier 1786 var = declaration_scope->LookupLocal(name);
1787 // (i.e., enclosing) global scopes, to maintain the illusion of a single
1788 // global scope.
1789 var = declaration_scope->is_global_scope()
1790 ? declaration_scope->Lookup(name)
1791 : declaration_scope->LookupLocal(name);
1792 if (var == NULL) { 1787 if (var == NULL) {
1793 // Declare the name. 1788 // Declare the name.
1794 var = declaration_scope->DeclareLocal(name, mode, 1789 var = declaration_scope->DeclareLocal(name, mode,
1795 declaration->initialization(), 1790 declaration->initialization(),
1796 kNotAssigned, proxy->interface()); 1791 kNotAssigned, proxy->interface());
1797 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode()) 1792 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
1798 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && 1793 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1799 !declaration_scope->is_global_scope())) { 1794 !declaration_scope->is_script_scope())) {
1800 // The name was declared in this scope before; check for conflicting 1795 // The name was declared in this scope before; check for conflicting
1801 // re-declarations. We have a conflict if either of the declarations is 1796 // re-declarations. We have a conflict if either of the declarations is
1802 // not a var (in the global scope, we also have to ignore legacy const for 1797 // not a var (in the script scope, we also have to ignore legacy const for
rossberg 2014/11/12 09:49:27 Nit: s/the script/a script/
Dmitry Lomov (no reviews) 2014/11/12 10:16:26 Done.
1803 // compatibility). There is similar code in runtime.cc in the Declare 1798 // compatibility). There is similar code in runtime.cc in the Declare
1804 // functions. The function CheckConflictingVarDeclarations checks for 1799 // functions. The function CheckConflictingVarDeclarations checks for
1805 // var and let bindings from different scopes whereas this is a check for 1800 // var and let bindings from different scopes whereas this is a check for
1806 // conflicting declarations within the same scope. This check also covers 1801 // conflicting declarations within the same scope. This check also covers
1807 // the special case 1802 // the special case
1808 // 1803 //
1809 // function () { let x; { var x; } } 1804 // function () { let x; { var x; } }
1810 // 1805 //
1811 // because the var declaration is hoisted to the function scope where 'x' 1806 // because the var declaration is hoisted to the function scope where 'x'
1812 // is already bound. 1807 // is already bound.
(...skipping 24 matching lines...) Expand all
1837 // bound during variable resolution time unless it was pre-bound 1832 // bound during variable resolution time unless it was pre-bound
1838 // below. 1833 // below.
1839 // 1834 //
1840 // WARNING: This will lead to multiple declaration nodes for the 1835 // WARNING: This will lead to multiple declaration nodes for the
1841 // same variable if it is declared several times. This is not a 1836 // same variable if it is declared several times. This is not a
1842 // semantic issue as long as we keep the source order, but it may be 1837 // semantic issue as long as we keep the source order, but it may be
1843 // a performance issue since it may lead to repeated 1838 // a performance issue since it may lead to repeated
1844 // RuntimeHidden_DeclareLookupSlot calls. 1839 // RuntimeHidden_DeclareLookupSlot calls.
1845 declaration_scope->AddDeclaration(declaration); 1840 declaration_scope->AddDeclaration(declaration);
1846 1841
1847 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) { 1842 if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) {
1848 // For global const variables we bind the proxy to a variable. 1843 // For global const variables we bind the proxy to a variable.
1849 DCHECK(resolve); // should be set by all callers 1844 DCHECK(resolve); // should be set by all callers
1850 Variable::Kind kind = Variable::NORMAL; 1845 Variable::Kind kind = Variable::NORMAL;
1851 var = new (zone()) 1846 var = new (zone())
1852 Variable(declaration_scope, name, mode, true, kind, 1847 Variable(declaration_scope, name, mode, true, kind,
1853 kNeedsInitialization, kNotAssigned, proxy->interface()); 1848 kNeedsInitialization, kNotAssigned, proxy->interface());
1854 } else if (declaration_scope->is_eval_scope() && 1849 } else if (declaration_scope->is_eval_scope() &&
1855 declaration_scope->strict_mode() == SLOPPY) { 1850 declaration_scope->strict_mode() == SLOPPY) {
1856 // For variable declarations in a sloppy eval scope the proxy is bound 1851 // For variable declarations in a sloppy eval scope the proxy is bound
1857 // to a lookup variable to force a dynamic declaration using the 1852 // to a lookup variable to force a dynamic declaration using the
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 &is_strict_reserved, CHECK_OK); 1971 &is_strict_reserved, CHECK_OK);
1977 FunctionLiteral* fun = 1972 FunctionLiteral* fun =
1978 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved, 1973 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
1979 is_generator ? FunctionKind::kGeneratorFunction 1974 is_generator ? FunctionKind::kGeneratorFunction
1980 : FunctionKind::kNormalFunction, 1975 : FunctionKind::kNormalFunction,
1981 pos, FunctionLiteral::DECLARATION, 1976 pos, FunctionLiteral::DECLARATION,
1982 FunctionLiteral::NORMAL_ARITY, CHECK_OK); 1977 FunctionLiteral::NORMAL_ARITY, CHECK_OK);
1983 // Even if we're not at the top-level of the global or a function 1978 // Even if we're not at the top-level of the global or a function
1984 // scope, we treat it as such and introduce the function with its 1979 // scope, we treat it as such and introduce the function with its
1985 // initial value upon entering the corresponding scope. 1980 // initial value upon entering the corresponding scope.
1986 // In ES6, a function behaves as a lexical binding, except in the 1981 // In ES6, a function behaves as a lexical binding, except in the
rossberg 2014/11/12 09:49:27 Nit: s/except in the/except in a/
Dmitry Lomov (no reviews) 2014/11/12 10:16:26 Done.
1987 // global scope, or the initial scope of eval or another function. 1982 // script scope, or the initial scope of eval or another function.
1988 VariableMode mode = 1983 VariableMode mode =
1989 allow_harmony_scoping() && strict_mode() == STRICT && 1984 allow_harmony_scoping() && strict_mode() == STRICT &&
1990 !(scope_->is_global_scope() || scope_->is_eval_scope() || 1985 !(scope_->is_script_scope() || scope_->is_eval_scope() ||
1991 scope_->is_function_scope()) ? LET : VAR; 1986 scope_->is_function_scope()) ? LET : VAR;
1992 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); 1987 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
1993 Declaration* declaration = 1988 Declaration* declaration =
1994 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); 1989 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
1995 Declare(declaration, true, CHECK_OK); 1990 Declare(declaration, true, CHECK_OK);
1996 if (names) names->Add(name, zone()); 1991 if (names) names->Add(name, zone());
1997 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1992 return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
1998 } 1993 }
1999 1994
2000 1995
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 // *not* touched until the variable declaration statement is 2326 // *not* touched until the variable declaration statement is
2332 // executed. 2327 // executed.
2333 // 2328 //
2334 // Executing the variable declaration statement will always 2329 // Executing the variable declaration statement will always
2335 // guarantee to give the global object an own property. 2330 // guarantee to give the global object an own property.
2336 // This way, global variable declarations can shadow 2331 // This way, global variable declarations can shadow
2337 // properties in the prototype chain, but only after the variable 2332 // properties in the prototype chain, but only after the variable
2338 // declaration statement has been executed. This is important in 2333 // declaration statement has been executed. This is important in
2339 // browsers where the global object (window) has lots of 2334 // browsers where the global object (window) has lots of
2340 // properties defined in prototype objects. 2335 // properties defined in prototype objects.
2341 if (initialization_scope->is_global_scope() && 2336 if (initialization_scope->is_script_scope() &&
2342 !IsLexicalVariableMode(mode)) { 2337 !IsLexicalVariableMode(mode)) {
2343 // Compute the arguments for the runtime call. 2338 // Compute the arguments for the runtime call.
2344 ZoneList<Expression*>* arguments = 2339 ZoneList<Expression*>* arguments =
2345 new(zone()) ZoneList<Expression*>(3, zone()); 2340 new(zone()) ZoneList<Expression*>(3, zone());
2346 // We have at least 1 parameter. 2341 // We have at least 1 parameter.
2347 arguments->Add(factory()->NewStringLiteral(name, pos), zone()); 2342 arguments->Add(factory()->NewStringLiteral(name, pos), zone());
2348 CallRuntime* initialize; 2343 CallRuntime* initialize;
2349 2344
2350 if (is_const) { 2345 if (is_const) {
2351 arguments->Add(value, zone()); 2346 arguments->Add(value, zone());
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 Expression* generator = factory()->NewVariableProxy( 2623 Expression* generator = factory()->NewVariableProxy(
2629 function_state_->generator_object_variable()); 2624 function_state_->generator_object_variable());
2630 Expression* yield = factory()->NewYield( 2625 Expression* yield = factory()->NewYield(
2631 generator, return_value, Yield::kFinal, loc.beg_pos); 2626 generator, return_value, Yield::kFinal, loc.beg_pos);
2632 result = factory()->NewExpressionStatement(yield, loc.beg_pos); 2627 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2633 } else { 2628 } else {
2634 result = factory()->NewReturnStatement(return_value, loc.beg_pos); 2629 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2635 } 2630 }
2636 2631
2637 Scope* decl_scope = scope_->DeclarationScope(); 2632 Scope* decl_scope = scope_->DeclarationScope();
2638 if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { 2633 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2639 ReportMessageAt(loc, "illegal_return"); 2634 ReportMessageAt(loc, "illegal_return");
2640 *ok = false; 2635 *ok = false;
2641 return NULL; 2636 return NULL;
2642 } 2637 }
2643 return result; 2638 return result;
2644 } 2639 }
2645 2640
2646 2641
2647 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, 2642 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels,
2648 bool* ok) { 2643 bool* ok) {
(...skipping 2374 matching lines...) Expand 10 before | Expand all | Expand 10 after
5023 5018
5024 // We cannot internalize on a background thread; a foreground task will take 5019 // We cannot internalize on a background thread; a foreground task will take
5025 // care of calling Parser::Internalize just before compilation. 5020 // care of calling Parser::Internalize just before compilation.
5026 5021
5027 if (compile_options() == ScriptCompiler::kProduceParserCache) { 5022 if (compile_options() == ScriptCompiler::kProduceParserCache) {
5028 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 5023 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
5029 log_ = NULL; 5024 log_ = NULL;
5030 } 5025 }
5031 } 5026 }
5032 } } // namespace v8::internal 5027 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698