OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <cmath> | 5 #include <cmath> |
6 | 6 |
7 #include "src/allocation.h" | 7 #include "src/allocation.h" |
8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" |
10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 101 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
102 LanguageMode language_mode, FunctionKind kind, ParserRecorder* log) { | 102 LanguageMode language_mode, FunctionKind kind, ParserRecorder* log) { |
103 log_ = log; | 103 log_ = log; |
104 // Lazy functions always have trivial outer scopes (no with/catch scopes). | 104 // Lazy functions always have trivial outer scopes (no with/catch scopes). |
105 Scope* top_scope = NewScope(scope_, SCRIPT_SCOPE); | 105 Scope* top_scope = NewScope(scope_, SCRIPT_SCOPE); |
106 PreParserFactory top_factory(NULL); | 106 PreParserFactory top_factory(NULL); |
107 FunctionState top_state(&function_state_, &scope_, top_scope, kNormalFunction, | 107 FunctionState top_state(&function_state_, &scope_, top_scope, kNormalFunction, |
108 &top_factory); | 108 &top_factory); |
109 scope_->SetLanguageMode(language_mode); | 109 scope_->SetLanguageMode(language_mode); |
110 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE); | 110 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE); |
| 111 Scope* function_body = NewScope(function_scope, FUNCTION_BODY_SCOPE); |
| 112 DCHECK_EQ(function_scope->function_body(), function_body); |
111 PreParserFactory function_factory(NULL); | 113 PreParserFactory function_factory(NULL); |
112 FunctionState function_state(&function_state_, &scope_, function_scope, kind, | 114 FunctionState function_state(&function_state_, &scope_, function_scope, kind, |
113 &function_factory); | 115 &function_factory); |
114 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 116 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
115 bool ok = true; | 117 bool ok = true; |
116 int start_position = peek_position(); | 118 int start_position = peek_position(); |
117 ParseLazyFunctionLiteralBody(&ok); | 119 { |
| 120 DCHECK(scope_->is_function_scope()); |
| 121 BlockState(&scope_, function_body); |
| 122 ParseLazyFunctionLiteralBody(&ok); |
| 123 } |
118 if (stack_overflow()) return kPreParseStackOverflow; | 124 if (stack_overflow()) return kPreParseStackOverflow; |
119 if (!ok) { | 125 if (!ok) { |
120 ReportUnexpectedToken(scanner()->current_token()); | 126 ReportUnexpectedToken(scanner()->current_token()); |
121 } else { | 127 } else { |
122 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 128 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
123 if (is_strict(scope_->language_mode())) { | 129 if (is_strict(scope_->language_mode())) { |
124 int end_pos = scanner()->location().end_pos; | 130 int end_pos = scanner()->location().end_pos; |
125 CheckStrictOctalLiteral(start_position, end_pos, &ok); | 131 CheckStrictOctalLiteral(start_position, end_pos, &ok); |
126 if (!ok) return kPreParseSuccess; | 132 if (!ok) return kPreParseSuccess; |
127 | 133 |
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 Identifier function_name, Scanner::Location function_name_location, | 995 Identifier function_name, Scanner::Location function_name_location, |
990 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 996 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
991 FunctionLiteral::FunctionType function_type, | 997 FunctionLiteral::FunctionType function_type, |
992 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 998 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
993 // Function :: | 999 // Function :: |
994 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1000 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
995 | 1001 |
996 // Parse function body. | 1002 // Parse function body. |
997 bool outer_is_script_scope = scope_->is_script_scope(); | 1003 bool outer_is_script_scope = scope_->is_script_scope(); |
998 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE); | 1004 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE); |
| 1005 Scope* function_body = NewScope(function_scope, FUNCTION_BODY_SCOPE); |
| 1006 DCHECK_EQ(function_scope->function_body(), function_body); |
999 PreParserFactory factory(NULL); | 1007 PreParserFactory factory(NULL); |
1000 FunctionState function_state(&function_state_, &scope_, function_scope, kind, | 1008 FunctionState function_state(&function_state_, &scope_, function_scope, kind, |
1001 &factory); | 1009 &factory); |
1002 FormalParameterErrorLocations error_locs; | 1010 FormalParameterErrorLocations error_locs; |
1003 | 1011 |
1004 bool is_rest = false; | 1012 bool is_rest = false; |
1005 Expect(Token::LPAREN, CHECK_OK); | 1013 Expect(Token::LPAREN, CHECK_OK); |
1006 int start_position = scanner()->location().beg_pos; | 1014 int start_position = scanner()->location().beg_pos; |
1007 function_scope->set_start_position(start_position); | 1015 function_scope->set_start_position(start_position); |
| 1016 function_body->set_start_position(start_position); |
1008 int num_parameters; | 1017 int num_parameters; |
| 1018 bool has_initializers = false; |
1009 { | 1019 { |
1010 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 1020 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
1011 num_parameters = ParseFormalParameterList(&duplicate_finder, &error_locs, | 1021 PreParserExpressionList initializers = NewExpressionList(0, zone()); |
1012 &is_rest, CHECK_OK); | 1022 num_parameters = |
| 1023 ParseFormalParameterList(&duplicate_finder, &error_locs, initializers, |
| 1024 &has_initializers, &is_rest, CHECK_OK); |
1013 } | 1025 } |
1014 Expect(Token::RPAREN, CHECK_OK); | 1026 Expect(Token::RPAREN, CHECK_OK); |
1015 int formals_end_position = scanner()->location().end_pos; | 1027 int formals_end_position = scanner()->location().end_pos; |
1016 | 1028 |
1017 CheckArityRestrictions(num_parameters, arity_restriction, start_position, | 1029 CheckArityRestrictions(num_parameters, arity_restriction, start_position, |
1018 formals_end_position, CHECK_OK); | 1030 formals_end_position, CHECK_OK); |
1019 | 1031 |
1020 // See Parser::ParseFunctionLiteral for more information about lazy parsing | 1032 // See Parser::ParseFunctionLiteral for more information about lazy parsing |
1021 // and lazy compilation. | 1033 // and lazy compilation. |
1022 bool is_lazily_parsed = | 1034 bool is_lazily_parsed = |
1023 (outer_is_script_scope && allow_lazy() && !parenthesized_function_); | 1035 (outer_is_script_scope && allow_lazy() && !parenthesized_function_); |
1024 parenthesized_function_ = false; | 1036 parenthesized_function_ = false; |
1025 | 1037 |
1026 Expect(Token::LBRACE, CHECK_OK); | 1038 Expect(Token::LBRACE, CHECK_OK); |
1027 if (is_lazily_parsed) { | 1039 { |
1028 ParseLazyFunctionLiteralBody(CHECK_OK); | 1040 // Use the FUNCTION_BODY scope only if it's needed |
1029 } else { | 1041 // TODO(caitp): This is needed when ObjectBindingPatterns with |
1030 ParseStatementList(Token::RBRACE, CHECK_OK); | 1042 // computed property keys are used as well. |
| 1043 Scope* func_scope = has_initializers ? function_body : scope_; |
| 1044 if (func_scope != function_body) { |
| 1045 function_body->FinalizeBlockScope(); |
| 1046 } |
| 1047 BlockState function_body_state(&scope_, func_scope); |
| 1048 if (is_lazily_parsed) { |
| 1049 ParseLazyFunctionLiteralBody(CHECK_OK); |
| 1050 } else { |
| 1051 ParseStatementList(Token::RBRACE, CHECK_OK); |
| 1052 } |
1031 } | 1053 } |
1032 Expect(Token::RBRACE, CHECK_OK); | 1054 Expect(Token::RBRACE, CHECK_OK); |
| 1055 function_scope->set_end_position(scanner()->location().end_pos); |
| 1056 function_body->set_end_position(scanner()->location().end_pos); |
1033 | 1057 |
1034 // Validate name and parameter names. We can do this only after parsing the | 1058 // Validate name and parameter names. We can do this only after parsing the |
1035 // function, since the function can declare itself strict. | 1059 // function, since the function can declare itself strict. |
1036 CheckFunctionName(language_mode(), kind, function_name, | 1060 CheckFunctionName(language_mode(), kind, function_name, |
1037 name_is_strict_reserved, function_name_location, CHECK_OK); | 1061 name_is_strict_reserved, function_name_location, CHECK_OK); |
1038 const bool use_strict_params = is_rest || IsConciseMethod(kind); | 1062 const bool use_strict_params = is_rest || IsConciseMethod(kind); |
1039 CheckFunctionParameterNames(language_mode(), use_strict_params, error_locs, | 1063 CheckFunctionParameterNames(language_mode(), use_strict_params, error_locs, |
1040 CHECK_OK); | 1064 CHECK_OK); |
1041 | 1065 |
1042 if (is_strict(language_mode())) { | 1066 if (is_strict(language_mode())) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 | 1171 |
1148 DCHECK(!spread_pos.IsValid()); | 1172 DCHECK(!spread_pos.IsValid()); |
1149 | 1173 |
1150 return Expression::Default(); | 1174 return Expression::Default(); |
1151 } | 1175 } |
1152 | 1176 |
1153 #undef CHECK_OK | 1177 #undef CHECK_OK |
1154 | 1178 |
1155 | 1179 |
1156 } } // v8::internal | 1180 } } // v8::internal |
OLD | NEW |