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 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1295 bool* ok); | 1295 bool* ok); |
1296 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, | 1296 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, |
1297 bool* ok); | 1297 bool* ok); |
1298 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, | 1298 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, |
1299 bool* ok); | 1299 bool* ok); |
1300 StatementT ParseThrowStatement(bool* ok); | 1300 StatementT ParseThrowStatement(bool* ok); |
1301 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, | 1301 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, |
1302 bool* ok); | 1302 bool* ok); |
1303 StatementT ParseTryStatement(bool* ok); | 1303 StatementT ParseTryStatement(bool* ok); |
1304 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); | 1304 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); |
| 1305 StatementT ParseForEachStatementWithDeclarations( |
| 1306 int stmt_pos, ForInfo* for_info, BlockState* for_state, |
| 1307 ZoneList<const AstRawString*>* labels, bool* ok); |
| 1308 StatementT ParseForEachStatementWithoutDeclarations( |
| 1309 int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos, |
| 1310 ForInfo* for_info, BlockState* for_state, |
| 1311 ZoneList<const AstRawString*>* labels, bool* ok); |
| 1312 |
| 1313 // Parse a C-style for loop: 'for (<init>; <cond>; <step>) { ... }' |
| 1314 StatementT ParseStandardForLoop(int stmt_pos, StatementT init, |
| 1315 bool bound_names_are_lexical, |
| 1316 ForInfo* for_info, BlockState* for_state, |
| 1317 ZoneList<const AstRawString*>* labels, |
| 1318 bool* ok); |
1305 | 1319 |
1306 bool IsNextLetKeyword(); | 1320 bool IsNextLetKeyword(); |
1307 bool IsTrivialExpression(); | 1321 bool IsTrivialExpression(); |
1308 | 1322 |
1309 // Checks if the expression is a valid reference expression (e.g., on the | 1323 // Checks if the expression is a valid reference expression (e.g., on the |
1310 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1324 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1311 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1325 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1312 ExpressionT CheckAndRewriteReferenceExpression( | 1326 ExpressionT CheckAndRewriteReferenceExpression( |
1313 ExpressionT expression, int beg_pos, int end_pos, | 1327 ExpressionT expression, int beg_pos, int end_pos, |
1314 MessageTemplate::Template message, bool* ok); | 1328 MessageTemplate::Template message, bool* ok); |
(...skipping 4058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5373 bool bound_names_are_lexical = false; | 5387 bool bound_names_are_lexical = false; |
5374 | 5388 |
5375 // Create an in-between scope for let-bound iteration variables. | 5389 // Create an in-between scope for let-bound iteration variables. |
5376 BlockState for_state(zone(), &scope_state_); | 5390 BlockState for_state(zone(), &scope_state_); |
5377 Expect(Token::FOR, CHECK_OK); | 5391 Expect(Token::FOR, CHECK_OK); |
5378 Expect(Token::LPAREN, CHECK_OK); | 5392 Expect(Token::LPAREN, CHECK_OK); |
5379 for_state.set_start_position(scanner()->location().beg_pos); | 5393 for_state.set_start_position(scanner()->location().beg_pos); |
5380 for_state.set_is_hidden(); | 5394 for_state.set_is_hidden(); |
5381 | 5395 |
5382 StatementT init = impl()->NullStatement(); | 5396 StatementT init = impl()->NullStatement(); |
5383 if (peek() != Token::SEMICOLON) { | |
5384 // An initializer is present. | |
5385 if (peek() == Token::VAR || peek() == Token::CONST || | |
5386 (peek() == Token::LET && IsNextLetKeyword())) { | |
5387 // The initializer contains declarations. | |
5388 ParseVariableDeclarations(kForStatement, &for_info.parsing_result, | |
5389 nullptr, CHECK_OK); | |
5390 bound_names_are_lexical = | |
5391 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode); | |
5392 for_info.position = scanner()->location().beg_pos; | |
5393 | 5397 |
5394 if (CheckInOrOf(&for_info.mode)) { | 5398 if (peek() == Token::VAR || peek() == Token::CONST || |
5395 // Just one declaration followed by in/of. | 5399 (peek() == Token::LET && IsNextLetKeyword())) { |
5396 if (for_info.parsing_result.declarations.length() != 1) { | 5400 // The initializer contains declarations. |
5397 impl()->ReportMessageAt( | 5401 ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr, |
5398 for_info.parsing_result.bindings_loc, | 5402 CHECK_OK); |
5399 MessageTemplate::kForInOfLoopMultiBindings, | 5403 bound_names_are_lexical = |
5400 ForEachStatement::VisitModeString(for_info.mode)); | 5404 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode); |
5401 *ok = false; | 5405 for_info.position = scanner()->location().beg_pos; |
5402 return impl()->NullStatement(); | |
5403 } | |
5404 if (for_info.parsing_result.first_initializer_loc.IsValid() && | |
5405 (is_strict(language_mode()) || | |
5406 for_info.mode == ForEachStatement::ITERATE || | |
5407 bound_names_are_lexical || | |
5408 !impl()->IsIdentifier( | |
5409 for_info.parsing_result.declarations[0].pattern))) { | |
5410 impl()->ReportMessageAt( | |
5411 for_info.parsing_result.first_initializer_loc, | |
5412 MessageTemplate::kForInOfLoopInitializer, | |
5413 ForEachStatement::VisitModeString(for_info.mode)); | |
5414 *ok = false; | |
5415 return impl()->NullStatement(); | |
5416 } | |
5417 | 5406 |
5418 BlockT init_block = impl()->RewriteForVarInLegacy(for_info); | 5407 if (CheckInOrOf(&for_info.mode)) { |
| 5408 return ParseForEachStatementWithDeclarations(stmt_pos, &for_info, |
| 5409 &for_state, labels, ok); |
| 5410 } |
5419 | 5411 |
5420 auto loop = | 5412 // One or more declaration not followed by in/of. |
5421 factory()->NewForEachStatement(for_info.mode, labels, stmt_pos); | 5413 init = impl()->BuildInitializationBlock( |
5422 typename Types::Target target(this, loop); | 5414 &for_info.parsing_result, |
| 5415 bound_names_are_lexical ? &for_info.bound_names : nullptr, CHECK_OK); |
| 5416 } else if (peek() != Token::SEMICOLON) { |
| 5417 // The initializer does not contain declarations. |
| 5418 int lhs_beg_pos = peek_position(); |
| 5419 ExpressionClassifier classifier(this); |
| 5420 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK); |
| 5421 int lhs_end_pos = scanner()->location().end_pos; |
5423 | 5422 |
5424 int each_keyword_pos = scanner()->location().beg_pos; | 5423 bool is_for_each = CheckInOrOf(&for_info.mode); |
| 5424 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || |
| 5425 expression->IsObjectLiteral()); |
5425 | 5426 |
5426 ExpressionT enumerable = impl()->EmptyExpression(); | 5427 if (is_destructuring) { |
5427 if (for_info.mode == ForEachStatement::ITERATE) { | 5428 ValidateAssignmentPattern(CHECK_OK); |
5428 ExpressionClassifier classifier(this); | 5429 } else { |
5429 enumerable = ParseAssignmentExpression(true, CHECK_OK); | 5430 impl()->RewriteNonPattern(CHECK_OK); |
5430 impl()->RewriteNonPattern(CHECK_OK); | 5431 } |
5431 } else { | |
5432 enumerable = ParseExpression(true, CHECK_OK); | |
5433 } | |
5434 | 5432 |
5435 Expect(Token::RPAREN, CHECK_OK); | 5433 if (is_for_each) { |
5436 | 5434 return ParseForEachStatementWithoutDeclarations( |
5437 StatementT final_loop = impl()->NullStatement(); | 5435 stmt_pos, expression, lhs_beg_pos, lhs_end_pos, &for_info, &for_state, |
5438 { | 5436 labels, ok); |
5439 ReturnExprScope no_tail_calls(function_state_, | |
5440 ReturnExprContext::kInsideForInOfBody); | |
5441 BlockState block_state(zone(), &scope_state_); | |
5442 block_state.set_start_position(scanner()->location().beg_pos); | |
5443 | |
5444 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); | |
5445 | |
5446 BlockT body_block = impl()->NullBlock(); | |
5447 ExpressionT each_variable = impl()->EmptyExpression(); | |
5448 impl()->DesugarBindingInForEachStatement(&for_info, &body_block, | |
5449 &each_variable, CHECK_OK); | |
5450 body_block->statements()->Add(body, zone()); | |
5451 final_loop = impl()->InitializeForEachStatement( | |
5452 loop, each_variable, enumerable, body_block, each_keyword_pos); | |
5453 | |
5454 block_state.set_end_position(scanner()->location().end_pos); | |
5455 body_block->set_scope(block_state.FinalizedBlockScope()); | |
5456 } | |
5457 | |
5458 init_block = | |
5459 impl()->CreateForEachStatementTDZ(init_block, for_info, ok); | |
5460 | |
5461 for_state.set_end_position(scanner()->location().end_pos); | |
5462 Scope* for_scope = for_state.FinalizedBlockScope(); | |
5463 // Parsed for-in loop w/ variable declarations. | |
5464 if (!impl()->IsNullStatement(init_block)) { | |
5465 init_block->statements()->Add(final_loop, zone()); | |
5466 init_block->set_scope(for_scope); | |
5467 return init_block; | |
5468 } else { | |
5469 DCHECK_NULL(for_scope); | |
5470 return final_loop; | |
5471 } | |
5472 } else { | |
5473 // One or more declaration not followed by in/of. | |
5474 init = impl()->BuildInitializationBlock( | |
5475 &for_info.parsing_result, | |
5476 bound_names_are_lexical ? &for_info.bound_names : nullptr, | |
5477 CHECK_OK); | |
5478 } | |
5479 } else { | |
5480 // The initializer does not contain declarations. | |
5481 int lhs_beg_pos = peek_position(); | |
5482 ExpressionClassifier classifier(this); | |
5483 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK); | |
5484 int lhs_end_pos = scanner()->location().end_pos; | |
5485 | |
5486 bool is_for_each = CheckInOrOf(&for_info.mode); | |
5487 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || | |
5488 expression->IsObjectLiteral()); | |
5489 | |
5490 if (is_destructuring) { | |
5491 ValidateAssignmentPattern(CHECK_OK); | |
5492 } else { | |
5493 impl()->RewriteNonPattern(CHECK_OK); | |
5494 } | |
5495 | |
5496 if (is_for_each) { | |
5497 // Initializer is reference followed by in/of. | |
5498 if (!is_destructuring) { | |
5499 expression = impl()->CheckAndRewriteReferenceExpression( | |
5500 expression, lhs_beg_pos, lhs_end_pos, | |
5501 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); | |
5502 } | |
5503 | |
5504 auto loop = | |
5505 factory()->NewForEachStatement(for_info.mode, labels, stmt_pos); | |
5506 typename Types::Target target(this, loop); | |
5507 | |
5508 int each_keyword_pos = scanner()->location().beg_pos; | |
5509 | |
5510 ExpressionT enumerable = impl()->EmptyExpression(); | |
5511 if (for_info.mode == ForEachStatement::ITERATE) { | |
5512 ExpressionClassifier classifier(this); | |
5513 enumerable = ParseAssignmentExpression(true, CHECK_OK); | |
5514 impl()->RewriteNonPattern(CHECK_OK); | |
5515 } else { | |
5516 enumerable = ParseExpression(true, CHECK_OK); | |
5517 } | |
5518 | |
5519 Expect(Token::RPAREN, CHECK_OK); | |
5520 | |
5521 { | |
5522 ReturnExprScope no_tail_calls(function_state_, | |
5523 ReturnExprContext::kInsideForInOfBody); | |
5524 BlockState block_state(zone(), &scope_state_); | |
5525 block_state.set_start_position(scanner()->location().beg_pos); | |
5526 | |
5527 // For legacy compat reasons, give for loops similar treatment to | |
5528 // if statements in allowing a function declaration for a body | |
5529 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); | |
5530 block_state.set_end_position(scanner()->location().end_pos); | |
5531 StatementT final_loop = impl()->InitializeForEachStatement( | |
5532 loop, expression, enumerable, body, each_keyword_pos); | |
5533 | |
5534 Scope* for_scope = for_state.FinalizedBlockScope(); | |
5535 DCHECK_NULL(for_scope); | |
5536 USE(for_scope); | |
5537 Scope* block_scope = block_state.FinalizedBlockScope(); | |
5538 DCHECK_NULL(block_scope); | |
5539 USE(block_scope); | |
5540 return final_loop; | |
5541 } | |
5542 } else { | |
5543 // Initializer is just an expression. | |
5544 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); | |
5545 } | |
5546 } | 5437 } |
| 5438 // Initializer is just an expression. |
| 5439 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); |
5547 } | 5440 } |
5548 | 5441 |
5549 // Standard 'for' loop, we have parsed the initializer at this point. | 5442 // Standard 'for' loop, we have parsed the initializer at this point. |
| 5443 return ParseStandardForLoop(stmt_pos, init, bound_names_are_lexical, |
| 5444 &for_info, &for_state, labels, ok); |
| 5445 } |
| 5446 |
| 5447 template <typename Impl> |
| 5448 typename ParserBase<Impl>::StatementT |
| 5449 ParserBase<Impl>::ParseForEachStatementWithDeclarations( |
| 5450 int stmt_pos, ForInfo* for_info, BlockState* for_state, |
| 5451 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 5452 // Just one declaration followed by in/of. |
| 5453 if (for_info->parsing_result.declarations.length() != 1) { |
| 5454 impl()->ReportMessageAt(for_info->parsing_result.bindings_loc, |
| 5455 MessageTemplate::kForInOfLoopMultiBindings, |
| 5456 ForEachStatement::VisitModeString(for_info->mode)); |
| 5457 *ok = false; |
| 5458 return impl()->NullStatement(); |
| 5459 } |
| 5460 if (for_info->parsing_result.first_initializer_loc.IsValid() && |
| 5461 (is_strict(language_mode()) || |
| 5462 for_info->mode == ForEachStatement::ITERATE || |
| 5463 IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) || |
| 5464 !impl()->IsIdentifier( |
| 5465 for_info->parsing_result.declarations[0].pattern))) { |
| 5466 impl()->ReportMessageAt(for_info->parsing_result.first_initializer_loc, |
| 5467 MessageTemplate::kForInOfLoopInitializer, |
| 5468 ForEachStatement::VisitModeString(for_info->mode)); |
| 5469 *ok = false; |
| 5470 return impl()->NullStatement(); |
| 5471 } |
| 5472 |
| 5473 BlockT init_block = impl()->RewriteForVarInLegacy(*for_info); |
| 5474 |
| 5475 auto loop = factory()->NewForEachStatement(for_info->mode, labels, stmt_pos); |
| 5476 typename Types::Target target(this, loop); |
| 5477 |
| 5478 int each_keyword_pos = scanner()->location().beg_pos; |
| 5479 |
| 5480 ExpressionT enumerable = impl()->EmptyExpression(); |
| 5481 if (for_info->mode == ForEachStatement::ITERATE) { |
| 5482 ExpressionClassifier classifier(this); |
| 5483 enumerable = ParseAssignmentExpression(true, CHECK_OK); |
| 5484 impl()->RewriteNonPattern(CHECK_OK); |
| 5485 } else { |
| 5486 enumerable = ParseExpression(true, CHECK_OK); |
| 5487 } |
| 5488 |
| 5489 Expect(Token::RPAREN, CHECK_OK); |
| 5490 |
| 5491 StatementT final_loop = impl()->NullStatement(); |
| 5492 { |
| 5493 ReturnExprScope no_tail_calls(function_state_, |
| 5494 ReturnExprContext::kInsideForInOfBody); |
| 5495 BlockState block_state(zone(), &scope_state_); |
| 5496 block_state.set_start_position(scanner()->location().beg_pos); |
| 5497 |
| 5498 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 5499 |
| 5500 BlockT body_block = impl()->NullBlock(); |
| 5501 ExpressionT each_variable = impl()->EmptyExpression(); |
| 5502 impl()->DesugarBindingInForEachStatement(for_info, &body_block, |
| 5503 &each_variable, CHECK_OK); |
| 5504 body_block->statements()->Add(body, zone()); |
| 5505 final_loop = impl()->InitializeForEachStatement( |
| 5506 loop, each_variable, enumerable, body_block, each_keyword_pos); |
| 5507 |
| 5508 block_state.set_end_position(scanner()->location().end_pos); |
| 5509 body_block->set_scope(block_state.FinalizedBlockScope()); |
| 5510 } |
| 5511 |
| 5512 init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info, ok); |
| 5513 |
| 5514 for_state->set_end_position(scanner()->location().end_pos); |
| 5515 Scope* for_scope = for_state->FinalizedBlockScope(); |
| 5516 // Parsed for-in loop w/ variable declarations. |
| 5517 if (!impl()->IsNullStatement(init_block)) { |
| 5518 init_block->statements()->Add(final_loop, zone()); |
| 5519 init_block->set_scope(for_scope); |
| 5520 return init_block; |
| 5521 } |
| 5522 |
| 5523 DCHECK_NULL(for_scope); |
| 5524 return final_loop; |
| 5525 } |
| 5526 |
| 5527 template <typename Impl> |
| 5528 typename ParserBase<Impl>::StatementT |
| 5529 ParserBase<Impl>::ParseForEachStatementWithoutDeclarations( |
| 5530 int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos, |
| 5531 ForInfo* for_info, BlockState* for_state, |
| 5532 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 5533 // Initializer is reference followed by in/of. |
| 5534 if (!expression->IsArrayLiteral() && !expression->IsObjectLiteral()) { |
| 5535 expression = impl()->CheckAndRewriteReferenceExpression( |
| 5536 expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, |
| 5537 kSyntaxError, CHECK_OK); |
| 5538 } |
| 5539 |
| 5540 auto loop = factory()->NewForEachStatement(for_info->mode, labels, stmt_pos); |
| 5541 typename Types::Target target(this, loop); |
| 5542 |
| 5543 int each_keyword_pos = scanner()->location().beg_pos; |
| 5544 |
| 5545 ExpressionT enumerable = impl()->EmptyExpression(); |
| 5546 if (for_info->mode == ForEachStatement::ITERATE) { |
| 5547 ExpressionClassifier classifier(this); |
| 5548 enumerable = ParseAssignmentExpression(true, CHECK_OK); |
| 5549 impl()->RewriteNonPattern(CHECK_OK); |
| 5550 } else { |
| 5551 enumerable = ParseExpression(true, CHECK_OK); |
| 5552 } |
| 5553 |
| 5554 Expect(Token::RPAREN, CHECK_OK); |
| 5555 |
| 5556 { |
| 5557 ReturnExprScope no_tail_calls(function_state_, |
| 5558 ReturnExprContext::kInsideForInOfBody); |
| 5559 BlockState block_state(zone(), &scope_state_); |
| 5560 block_state.set_start_position(scanner()->location().beg_pos); |
| 5561 |
| 5562 // For legacy compat reasons, give for loops similar treatment to |
| 5563 // if statements in allowing a function declaration for a body |
| 5564 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 5565 block_state.set_end_position(scanner()->location().end_pos); |
| 5566 StatementT final_loop = impl()->InitializeForEachStatement( |
| 5567 loop, expression, enumerable, body, each_keyword_pos); |
| 5568 |
| 5569 Scope* for_scope = for_state->FinalizedBlockScope(); |
| 5570 DCHECK_NULL(for_scope); |
| 5571 USE(for_scope); |
| 5572 Scope* block_scope = block_state.FinalizedBlockScope(); |
| 5573 DCHECK_NULL(block_scope); |
| 5574 USE(block_scope); |
| 5575 return final_loop; |
| 5576 } |
| 5577 } |
| 5578 |
| 5579 template <typename Impl> |
| 5580 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStandardForLoop( |
| 5581 int stmt_pos, StatementT init, bool bound_names_are_lexical, |
| 5582 ForInfo* for_info, BlockState* for_state, |
| 5583 ZoneList<const AstRawString*>* labels, bool* ok) { |
5550 auto loop = factory()->NewForStatement(labels, stmt_pos); | 5584 auto loop = factory()->NewForStatement(labels, stmt_pos); |
5551 typename Types::Target target(this, loop); | 5585 typename Types::Target target(this, loop); |
5552 | 5586 |
5553 Expect(Token::SEMICOLON, CHECK_OK); | 5587 Expect(Token::SEMICOLON, CHECK_OK); |
5554 | 5588 |
5555 ExpressionT cond = impl()->EmptyExpression(); | 5589 ExpressionT cond = impl()->EmptyExpression(); |
5556 StatementT next = impl()->NullStatement(); | 5590 StatementT next = impl()->NullStatement(); |
5557 StatementT body = impl()->NullStatement(); | 5591 StatementT body = impl()->NullStatement(); |
5558 | 5592 |
5559 // If there are let bindings, then condition and the next statement of the | 5593 // If there are let bindings, then condition and the next statement of the |
5560 // for loop must be parsed in a new scope. | 5594 // for loop must be parsed in a new scope. |
5561 Scope* inner_scope = scope(); | 5595 Scope* inner_scope = scope(); |
5562 // TODO(verwaest): Allocate this through a ScopeState as well. | 5596 // TODO(verwaest): Allocate this through a ScopeState as well. |
5563 if (bound_names_are_lexical && for_info.bound_names.length() > 0) { | 5597 if (bound_names_are_lexical && for_info->bound_names.length() > 0) { |
5564 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE); | 5598 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE); |
5565 inner_scope->set_start_position(scanner()->location().beg_pos); | 5599 inner_scope->set_start_position(scanner()->location().beg_pos); |
5566 } | 5600 } |
5567 { | 5601 { |
5568 BlockState block_state(&scope_state_, inner_scope); | 5602 BlockState block_state(&scope_state_, inner_scope); |
5569 | 5603 |
5570 if (peek() != Token::SEMICOLON) { | 5604 if (peek() != Token::SEMICOLON) { |
5571 cond = ParseExpression(true, CHECK_OK); | 5605 cond = ParseExpression(true, CHECK_OK); |
5572 } | 5606 } |
5573 Expect(Token::SEMICOLON, CHECK_OK); | 5607 Expect(Token::SEMICOLON, CHECK_OK); |
5574 | 5608 |
5575 if (peek() != Token::RPAREN) { | 5609 if (peek() != Token::RPAREN) { |
5576 ExpressionT exp = ParseExpression(true, CHECK_OK); | 5610 ExpressionT exp = ParseExpression(true, CHECK_OK); |
5577 next = factory()->NewExpressionStatement(exp, exp->position()); | 5611 next = factory()->NewExpressionStatement(exp, exp->position()); |
5578 } | 5612 } |
5579 Expect(Token::RPAREN, CHECK_OK); | 5613 Expect(Token::RPAREN, CHECK_OK); |
5580 | 5614 |
5581 body = ParseScopedStatement(nullptr, true, CHECK_OK); | 5615 body = ParseScopedStatement(nullptr, true, CHECK_OK); |
5582 } | 5616 } |
5583 | 5617 |
5584 if (bound_names_are_lexical && for_info.bound_names.length() > 0) { | 5618 if (bound_names_are_lexical && for_info->bound_names.length() > 0) { |
5585 auto result = impl()->DesugarLexicalBindingsInForStatement( | 5619 auto result = impl()->DesugarLexicalBindingsInForStatement( |
5586 loop, init, cond, next, body, inner_scope, for_info, CHECK_OK); | 5620 loop, init, cond, next, body, inner_scope, *for_info, CHECK_OK); |
5587 for_state.set_end_position(scanner()->location().end_pos); | 5621 for_state->set_end_position(scanner()->location().end_pos); |
5588 return result; | 5622 return result; |
5589 } else { | 5623 } |
5590 for_state.set_end_position(scanner()->location().end_pos); | 5624 |
5591 Scope* for_scope = for_state.FinalizedBlockScope(); | 5625 for_state->set_end_position(scanner()->location().end_pos); |
5592 if (for_scope != nullptr) { | 5626 Scope* for_scope = for_state->FinalizedBlockScope(); |
5593 // Rewrite a for statement of the form | 5627 if (for_scope != nullptr) { |
5594 // for (const x = i; c; n) b | 5628 // Rewrite a for statement of the form |
5595 // | 5629 // for (const x = i; c; n) b |
5596 // into | 5630 // |
5597 // | 5631 // into |
5598 // { | 5632 // |
5599 // const x = i; | 5633 // { |
5600 // for (; c; n) b | 5634 // const x = i; |
5601 // } | 5635 // for (; c; n) b |
5602 // | 5636 // } |
5603 // or, desugar | 5637 // |
5604 // for (; c; n) b | 5638 // or, desugar |
5605 // into | 5639 // for (; c; n) b |
5606 // { | 5640 // into |
5607 // for (; c; n) b | 5641 // { |
5608 // } | 5642 // for (; c; n) b |
5609 // just in case b introduces a lexical binding some other way, e.g., if b | 5643 // } |
5610 // is a FunctionDeclaration. | 5644 // just in case b introduces a lexical binding some other way, e.g., if b |
5611 BlockT block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); | 5645 // is a FunctionDeclaration. |
5612 if (!impl()->IsNullStatement(init)) { | 5646 BlockT block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); |
5613 block->statements()->Add(init, zone()); | 5647 if (!impl()->IsNullStatement(init)) { |
5614 } | 5648 block->statements()->Add(init, zone()); |
5615 block->statements()->Add(loop, zone()); | |
5616 block->set_scope(for_scope); | |
5617 loop->Initialize(init, cond, next, body); | |
5618 return block; | |
5619 } else { | |
5620 loop->Initialize(init, cond, next, body); | |
5621 return loop; | |
5622 } | 5649 } |
| 5650 block->statements()->Add(loop, zone()); |
| 5651 block->set_scope(for_scope); |
| 5652 loop->Initialize(init, cond, next, body); |
| 5653 return block; |
5623 } | 5654 } |
| 5655 |
| 5656 loop->Initialize(init, cond, next, body); |
| 5657 return loop; |
5624 } | 5658 } |
5625 | 5659 |
5626 #undef CHECK_OK | 5660 #undef CHECK_OK |
5627 #undef CHECK_OK_CUSTOM | 5661 #undef CHECK_OK_CUSTOM |
5628 | 5662 |
5629 template <typename Impl> | 5663 template <typename Impl> |
5630 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( | 5664 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
5631 Token::Value property) { | 5665 Token::Value property) { |
5632 if (property == Token::SMI || property == Token::NUMBER) return; | 5666 if (property == Token::SMI || property == Token::NUMBER) return; |
5633 | 5667 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5675 return; | 5709 return; |
5676 } | 5710 } |
5677 } | 5711 } |
5678 | 5712 |
5679 #undef CHECK_OK_VOID | 5713 #undef CHECK_OK_VOID |
5680 | 5714 |
5681 } // namespace internal | 5715 } // namespace internal |
5682 } // namespace v8 | 5716 } // namespace v8 |
5683 | 5717 |
5684 #endif // V8_PARSING_PARSER_BASE_H | 5718 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |