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