| 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 |