Chromium Code Reviews| 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 |