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