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 176 matching lines...) Loading... |
187 } | 187 } |
188 break; | 188 break; |
189 case Token::LET: | 189 case Token::LET: |
190 if (IsNextLetKeyword()) { | 190 if (IsNextLetKeyword()) { |
191 return ParseVariableStatement(kStatementListItem, ok); | 191 return ParseVariableStatement(kStatementListItem, ok); |
192 } | 192 } |
193 break; | 193 break; |
194 default: | 194 default: |
195 break; | 195 break; |
196 } | 196 } |
197 return ParseStatement(ok); | 197 return ParseStatement(kAllowLabelledFunctionStatement, ok); |
198 } | 198 } |
199 | 199 |
200 | 200 |
201 void PreParser::ParseStatementList(int end_token, bool* ok, | 201 void PreParser::ParseStatementList(int end_token, bool* ok, |
202 Scanner::BookmarkScope* bookmark) { | 202 Scanner::BookmarkScope* bookmark) { |
203 // SourceElements :: | 203 // SourceElements :: |
204 // (Statement)* <end_token> | 204 // (Statement)* <end_token> |
205 | 205 |
206 // Bookkeeping for trial parse if bookmark is set: | 206 // Bookkeeping for trial parse if bookmark is set: |
207 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); | 207 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); |
(...skipping 48 matching lines...) Loading... |
256 } | 256 } |
257 } | 257 } |
258 | 258 |
259 | 259 |
260 #define CHECK_OK ok); \ | 260 #define CHECK_OK ok); \ |
261 if (!*ok) return Statement::Default(); \ | 261 if (!*ok) return Statement::Default(); \ |
262 ((void)0 | 262 ((void)0 |
263 #define DUMMY ) // to make indentation work | 263 #define DUMMY ) // to make indentation work |
264 #undef DUMMY | 264 #undef DUMMY |
265 | 265 |
266 | 266 PreParser::Statement PreParser::ParseStatement( |
267 PreParser::Statement PreParser::ParseStatement(bool* ok) { | 267 AllowLabelledFunctionStatement allow_labelled_function_statement, |
| 268 bool* ok) { |
268 // Statement :: | 269 // Statement :: |
269 // EmptyStatement | 270 // EmptyStatement |
270 // ... | 271 // ... |
271 | 272 |
272 if (peek() == Token::SEMICOLON) { | 273 if (peek() == Token::SEMICOLON) { |
273 Next(); | 274 Next(); |
274 return Statement::Default(); | 275 return Statement::Default(); |
275 } | 276 } |
276 return ParseSubStatement(ok); | 277 return ParseSubStatement(allow_labelled_function_statement, ok); |
277 } | 278 } |
278 | 279 |
279 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { | 280 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { |
280 if (is_strict(language_mode()) || peek() != Token::FUNCTION || | 281 if (is_strict(language_mode()) || peek() != Token::FUNCTION || |
281 (legacy && allow_harmony_restrictive_declarations())) { | 282 (legacy && allow_harmony_restrictive_declarations())) { |
282 return ParseSubStatement(ok); | 283 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok); |
283 } else { | 284 } else { |
284 return ParseFunctionDeclaration(CHECK_OK); | 285 return ParseFunctionDeclaration(CHECK_OK); |
285 } | 286 } |
286 } | 287 } |
287 | 288 |
288 PreParser::Statement PreParser::ParseSubStatement(bool* ok) { | 289 PreParser::Statement PreParser::ParseSubStatement( |
| 290 AllowLabelledFunctionStatement allow_labelled_function_statement, |
| 291 bool* ok) { |
289 // Statement :: | 292 // Statement :: |
290 // Block | 293 // Block |
291 // VariableStatement | 294 // VariableStatement |
292 // EmptyStatement | 295 // EmptyStatement |
293 // ExpressionStatement | 296 // ExpressionStatement |
294 // IfStatement | 297 // IfStatement |
295 // IterationStatement | 298 // IterationStatement |
296 // ContinueStatement | 299 // ContinueStatement |
297 // BreakStatement | 300 // BreakStatement |
298 // ReturnStatement | 301 // ReturnStatement |
(...skipping 75 matching lines...) Loading... |
374 case Token::CONST: | 377 case Token::CONST: |
375 // In ES6 CONST is not allowed as a Statement, only as a | 378 // In ES6 CONST is not allowed as a Statement, only as a |
376 // LexicalDeclaration, however we continue to allow it in sloppy mode for | 379 // LexicalDeclaration, however we continue to allow it in sloppy mode for |
377 // backwards compatibility. | 380 // backwards compatibility. |
378 if (is_sloppy(language_mode()) && allow_legacy_const()) { | 381 if (is_sloppy(language_mode()) && allow_legacy_const()) { |
379 return ParseVariableStatement(kStatement, ok); | 382 return ParseVariableStatement(kStatement, ok); |
380 } | 383 } |
381 | 384 |
382 // Fall through. | 385 // Fall through. |
383 default: | 386 default: |
384 return ParseExpressionOrLabelledStatement(ok); | 387 return ParseExpressionOrLabelledStatement( |
| 388 allow_labelled_function_statement, ok); |
385 } | 389 } |
386 } | 390 } |
387 | 391 |
388 | 392 |
389 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 393 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
390 // FunctionDeclaration :: | 394 // FunctionDeclaration :: |
391 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 395 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
392 // GeneratorDeclaration :: | 396 // GeneratorDeclaration :: |
393 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 397 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
394 // '{' FunctionBody '}' | 398 // '{' FunctionBody '}' |
(...skipping 163 matching lines...) Loading... |
558 *bindings_loc = | 562 *bindings_loc = |
559 Scanner::Location(bindings_start, scanner()->location().end_pos); | 563 Scanner::Location(bindings_start, scanner()->location().end_pos); |
560 } | 564 } |
561 | 565 |
562 if (num_decl != nullptr) *num_decl = nvars; | 566 if (num_decl != nullptr) *num_decl = nvars; |
563 if (is_lexical != nullptr) *is_lexical = lexical; | 567 if (is_lexical != nullptr) *is_lexical = lexical; |
564 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern; | 568 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern; |
565 return Statement::Default(); | 569 return Statement::Default(); |
566 } | 570 } |
567 | 571 |
568 | 572 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( |
569 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { | 573 AllowLabelledFunctionStatement allow_labelled_function_statement, |
| 574 bool* ok) { |
570 // ExpressionStatement | LabelledStatement :: | 575 // ExpressionStatement | LabelledStatement :: |
571 // Expression ';' | 576 // Expression ';' |
572 // Identifier ':' Statement | 577 // Identifier ':' Statement |
573 | 578 |
574 switch (peek()) { | 579 switch (peek()) { |
575 case Token::FUNCTION: | 580 case Token::FUNCTION: |
576 case Token::LBRACE: | 581 case Token::LBRACE: |
577 UNREACHABLE(); // Always handled by the callers. | 582 UNREACHABLE(); // Always handled by the callers. |
578 case Token::CLASS: | 583 case Token::CLASS: |
579 ReportUnexpectedToken(Next()); | 584 ReportUnexpectedToken(Next()); |
(...skipping 14 matching lines...) Loading... |
594 // an identifier. | 599 // an identifier. |
595 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { | 600 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { |
596 // Expression is a single identifier, and not, e.g., a parenthesized | 601 // Expression is a single identifier, and not, e.g., a parenthesized |
597 // identifier. | 602 // identifier. |
598 DCHECK(!expr.AsIdentifier().IsFutureReserved()); | 603 DCHECK(!expr.AsIdentifier().IsFutureReserved()); |
599 DCHECK(is_sloppy(language_mode()) || | 604 DCHECK(is_sloppy(language_mode()) || |
600 !IsFutureStrictReserved(expr.AsIdentifier())); | 605 !IsFutureStrictReserved(expr.AsIdentifier())); |
601 Consume(Token::COLON); | 606 Consume(Token::COLON); |
602 // ES#sec-labelled-function-declarations Labelled Function Declarations | 607 // ES#sec-labelled-function-declarations Labelled Function Declarations |
603 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { | 608 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { |
604 return ParseFunctionDeclaration(ok); | 609 if (allow_labelled_function_statement == |
| 610 kAllowLabelledFunctionStatement) { |
| 611 return ParseFunctionDeclaration(ok); |
| 612 } else { |
| 613 return ParseScopedStatement(true, ok); |
| 614 } |
605 } | 615 } |
606 Statement statement = ParseStatement(ok); | 616 Statement statement = |
| 617 ParseStatement(kDisallowLabelledFunctionStatement, ok); |
607 return statement.IsJumpStatement() ? Statement::Default() : statement; | 618 return statement.IsJumpStatement() ? Statement::Default() : statement; |
608 // Preparsing is disabled for extensions (because the extension details | 619 // Preparsing is disabled for extensions (because the extension details |
609 // aren't passed to lazily compiled functions), so we don't | 620 // aren't passed to lazily compiled functions), so we don't |
610 // accept "native function" in the preparser. | 621 // accept "native function" in the preparser. |
611 } | 622 } |
612 // Parsed expression statement. | 623 // Parsed expression statement. |
613 // Detect attempts at 'let' declarations in sloppy mode. | 624 // Detect attempts at 'let' declarations in sloppy mode. |
614 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER && | 625 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER && |
615 is_sloppy(language_mode()) && expr.IsIdentifier() && | 626 is_sloppy(language_mode()) && expr.IsIdentifier() && |
616 expr.AsIdentifier().IsLet()) { | 627 expr.AsIdentifier().IsLet()) { |
(...skipping 539 matching lines...) Loading... |
1156 Expect(Token::RBRACE, CHECK_OK); | 1167 Expect(Token::RBRACE, CHECK_OK); |
1157 return PreParserExpression::Default(); | 1168 return PreParserExpression::Default(); |
1158 } | 1169 } |
1159 } | 1170 } |
1160 | 1171 |
1161 #undef CHECK_OK | 1172 #undef CHECK_OK |
1162 | 1173 |
1163 | 1174 |
1164 } // namespace internal | 1175 } // namespace internal |
1165 } // namespace v8 | 1176 } // namespace v8 |
OLD | NEW |