Chromium Code Reviews| 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 |