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