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