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

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

Powered by Google App Engine
This is Rietveld 408576698