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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 PreParserIdentifier symbol = GetSymbolHelper(scanner()); | 77 PreParserIdentifier symbol = GetSymbolHelper(scanner()); |
78 if (track_unresolved_variables_) { | 78 if (track_unresolved_variables_) { |
79 const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory()); | 79 const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory()); |
80 DCHECK_NOT_NULL(result); | 80 DCHECK_NOT_NULL(result); |
81 symbol.string_ = result; | 81 symbol.string_ = result; |
82 } | 82 } |
83 return symbol; | 83 return symbol; |
84 } | 84 } |
85 | 85 |
86 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 86 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
87 DeclarationScope* function_scope, bool parsing_module, ParserRecorder* log, | 87 DeclarationScope* function_scope, bool parsing_module, SingletonLogger* log, |
88 bool is_inner_function, bool may_abort, int* use_counts) { | 88 bool is_inner_function, bool may_abort, int* use_counts) { |
89 DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type()); | 89 DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type()); |
90 parsing_module_ = parsing_module; | 90 parsing_module_ = parsing_module; |
91 log_ = log; | 91 log_ = log; |
92 use_counts_ = use_counts; | 92 use_counts_ = use_counts; |
93 DCHECK(!track_unresolved_variables_); | 93 DCHECK(!track_unresolved_variables_); |
94 track_unresolved_variables_ = is_inner_function; | 94 track_unresolved_variables_ = is_inner_function; |
95 | 95 |
96 // The caller passes the function_scope which is not yet inserted into the | 96 // The caller passes the function_scope which is not yet inserted into the |
97 // scope_state_. All scopes above the function_scope are ignored by the | 97 // scope_state_. All scopes above the function_scope are ignored by the |
98 // PreParser. | 98 // PreParser. |
99 DCHECK_NULL(scope_state_); | 99 DCHECK_NULL(scope_state_); |
100 FunctionState function_state(&function_state_, &scope_state_, function_scope); | 100 FunctionState function_state(&function_state_, &scope_state_, function_scope); |
101 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 101 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
102 bool ok = true; | 102 bool ok = true; |
103 int start_position = peek_position(); | 103 int start_position = peek_position(); |
104 LazyParsingResult result = ParseLazyFunctionLiteralBody(may_abort, &ok); | 104 LazyParsingResult result = ParseStatementListAndLogFunction(may_abort, &ok); |
105 use_counts_ = nullptr; | 105 use_counts_ = nullptr; |
106 track_unresolved_variables_ = false; | 106 track_unresolved_variables_ = false; |
107 if (result == kLazyParsingAborted) { | 107 if (result == kLazyParsingAborted) { |
108 return kPreParseAbort; | 108 return kPreParseAbort; |
109 } else if (stack_overflow()) { | 109 } else if (stack_overflow()) { |
110 return kPreParseStackOverflow; | 110 return kPreParseStackOverflow; |
111 } else if (!ok) { | 111 } else if (!ok) { |
112 ReportUnexpectedToken(scanner()->current_token()); | 112 DCHECK(log->has_error()); |
113 } else { | 113 } else { |
114 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 114 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
115 if (is_strict(function_scope->language_mode())) { | 115 if (is_strict(function_scope->language_mode())) { |
116 int end_pos = scanner()->location().end_pos; | 116 int end_pos = scanner()->location().end_pos; |
117 CheckStrictOctalLiteral(start_position, end_pos, &ok); | 117 CheckStrictOctalLiteral(start_position, end_pos, &ok); |
118 CheckDecimalLiteralWithLeadingZero(start_position, end_pos); | 118 CheckDecimalLiteralWithLeadingZero(start_position, end_pos); |
119 } | 119 } |
120 } | 120 } |
121 return kPreParseSuccess; | 121 return kPreParseSuccess; |
122 } | 122 } |
(...skipping 15 matching lines...) Expand all Loading... |
138 PreParser::Expression PreParser::ParseFunctionLiteral( | 138 PreParser::Expression PreParser::ParseFunctionLiteral( |
139 Identifier function_name, Scanner::Location function_name_location, | 139 Identifier function_name, Scanner::Location function_name_location, |
140 FunctionNameValidity function_name_validity, FunctionKind kind, | 140 FunctionNameValidity function_name_validity, FunctionKind kind, |
141 int function_token_pos, FunctionLiteral::FunctionType function_type, | 141 int function_token_pos, FunctionLiteral::FunctionType function_type, |
142 LanguageMode language_mode, bool* ok) { | 142 LanguageMode language_mode, bool* ok) { |
143 // Function :: | 143 // Function :: |
144 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 144 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
145 | 145 |
146 // Parse function body. | 146 // Parse function body. |
147 PreParserStatementList body; | 147 PreParserStatementList body; |
148 bool outer_is_script_scope = scope()->is_script_scope(); | |
149 DeclarationScope* function_scope = NewFunctionScope(kind); | 148 DeclarationScope* function_scope = NewFunctionScope(kind); |
150 function_scope->SetLanguageMode(language_mode); | 149 function_scope->SetLanguageMode(language_mode); |
151 FunctionState function_state(&function_state_, &scope_state_, function_scope); | 150 FunctionState function_state(&function_state_, &scope_state_, function_scope); |
152 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 151 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
153 ExpressionClassifier formals_classifier(this, &duplicate_finder); | 152 ExpressionClassifier formals_classifier(this, &duplicate_finder); |
154 | 153 |
155 Expect(Token::LPAREN, CHECK_OK); | 154 Expect(Token::LPAREN, CHECK_OK); |
156 int start_position = scanner()->location().beg_pos; | 155 int start_position = scanner()->location().beg_pos; |
157 function_scope->set_start_position(start_position); | 156 function_scope->set_start_position(start_position); |
158 PreParserFormalParameters formals(function_scope); | 157 PreParserFormalParameters formals(function_scope); |
159 ParseFormalParameterList(&formals, CHECK_OK); | 158 ParseFormalParameterList(&formals, CHECK_OK); |
160 Expect(Token::RPAREN, CHECK_OK); | 159 Expect(Token::RPAREN, CHECK_OK); |
161 int formals_end_position = scanner()->location().end_pos; | 160 int formals_end_position = scanner()->location().end_pos; |
162 | 161 |
163 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, | 162 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, |
164 formals_end_position, CHECK_OK); | 163 formals_end_position, CHECK_OK); |
165 | 164 |
166 // See Parser::ParseFunctionLiteral for more information about lazy parsing | |
167 // and lazy compilation. | |
168 bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() && | |
169 !function_state_->this_function_is_parenthesized()); | |
170 | |
171 Expect(Token::LBRACE, CHECK_OK); | 165 Expect(Token::LBRACE, CHECK_OK); |
172 if (is_lazily_parsed) { | 166 ParseStatementList(body, Token::RBRACE, CHECK_OK); |
173 ParseLazyFunctionLiteralBody(false, CHECK_OK); | |
174 } else { | |
175 ParseStatementList(body, Token::RBRACE, CHECK_OK); | |
176 } | |
177 Expect(Token::RBRACE, CHECK_OK); | 167 Expect(Token::RBRACE, CHECK_OK); |
178 | 168 |
179 // Parsing the body may change the language mode in our scope. | 169 // Parsing the body may change the language mode in our scope. |
180 language_mode = function_scope->language_mode(); | 170 language_mode = function_scope->language_mode(); |
181 | 171 |
182 // Validate name and parameter names. We can do this only after parsing the | 172 // Validate name and parameter names. We can do this only after parsing the |
183 // function, since the function can declare itself strict. | 173 // function, since the function can declare itself strict. |
184 CheckFunctionName(language_mode, function_name, function_name_validity, | 174 CheckFunctionName(language_mode, function_name, function_name_validity, |
185 function_name_location, CHECK_OK); | 175 function_name_location, CHECK_OK); |
186 const bool allow_duplicate_parameters = | 176 const bool allow_duplicate_parameters = |
187 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); | 177 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); |
188 ValidateFormalParameters(language_mode, allow_duplicate_parameters, CHECK_OK); | 178 ValidateFormalParameters(language_mode, allow_duplicate_parameters, CHECK_OK); |
189 | 179 |
190 if (is_strict(language_mode)) { | 180 if (is_strict(language_mode)) { |
191 int end_position = scanner()->location().end_pos; | 181 int end_position = scanner()->location().end_pos; |
192 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); | 182 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); |
193 CheckDecimalLiteralWithLeadingZero(start_position, end_position); | 183 CheckDecimalLiteralWithLeadingZero(start_position, end_position); |
194 } | 184 } |
195 | 185 |
196 return Expression::Default(); | 186 return Expression::Default(); |
197 } | 187 } |
198 | 188 |
199 PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody( | 189 PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction( |
200 bool may_abort, bool* ok) { | 190 bool may_abort, bool* ok) { |
201 int body_start = position(); | 191 int body_start = position(); |
202 PreParserStatementList body; | 192 PreParserStatementList body; |
203 LazyParsingResult result = ParseStatementList( | 193 LazyParsingResult result = ParseStatementList( |
204 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); | 194 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); |
205 if (result == kLazyParsingAborted) return result; | 195 if (result == kLazyParsingAborted) return result; |
206 | 196 |
207 // Position right after terminal '}'. | 197 // Position right after terminal '}'. |
208 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 198 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
209 int body_end = scanner()->peek_location().end_pos; | 199 int body_end = scanner()->peek_location().end_pos; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 } | 246 } |
257 } | 247 } |
258 } | 248 } |
259 | 249 |
260 #undef CHECK_OK | 250 #undef CHECK_OK |
261 #undef CHECK_OK_CUSTOM | 251 #undef CHECK_OK_CUSTOM |
262 | 252 |
263 | 253 |
264 } // namespace internal | 254 } // namespace internal |
265 } // namespace v8 | 255 } // namespace v8 |
OLD | NEW |