Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 "src/ast/ast.h" | 5 #include "src/ast/ast.h" |
| 6 #include "src/messages.h" | 6 #include "src/messages.h" |
| 7 #include "src/parsing/parameter-initializer-rewriter.h" | 7 #include "src/parsing/parameter-initializer-rewriter.h" |
| 8 #include "src/parsing/parser.h" | 8 #include "src/parsing/parser.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 400 | 400 |
| 401 | 401 |
| 402 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { | 402 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { |
| 403 Variable* temp_var = nullptr; | 403 Variable* temp_var = nullptr; |
| 404 VisitObjectLiteral(node, &temp_var); | 404 VisitObjectLiteral(node, &temp_var); |
| 405 } | 405 } |
| 406 | 406 |
| 407 | 407 |
| 408 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, | 408 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, |
| 409 Variable** temp_var) { | 409 Variable** temp_var) { |
| 410 // TODO(neis): Enable after rebase: | |
| 411 // DCHECK(block_->ignore_completion_value()); | |
| 412 | |
| 410 auto temp = *temp_var = CreateTempVar(current_value_); | 413 auto temp = *temp_var = CreateTempVar(current_value_); |
| 411 | |
| 412 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone()); | |
| 413 | |
| 414 auto iterator = CreateTempVar(parser_->GetIterator( | 414 auto iterator = CreateTempVar(parser_->GetIterator( |
| 415 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition)); | 415 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition)); |
| 416 auto done = CreateTempVar( | 416 auto done = CreateTempVar( |
| 417 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); | 417 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); |
| 418 auto result = CreateTempVar(); | 418 auto result = CreateTempVar(); |
| 419 auto v = CreateTempVar(); | 419 auto v = CreateTempVar(); |
| 420 auto completion = CreateTempVar(); | |
| 421 auto nopos = RelocInfo::kNoPosition; | |
| 422 | |
| 423 // For the purpose of iterator finalization, we temporarily set block_ to a | |
| 424 // new block. In the main body of this function, we write to block_ (both | |
| 425 // explicitly and implicitly via recursion). At the end of the function, we | |
| 426 // wrap this new block in a try-finally statement, restore block_ to its | |
| 427 // original value, and add the try-finally statement to block_. | |
| 428 auto target = block_; | |
| 429 if (FLAG_harmony_iterator_close) { | |
| 430 block_ = factory()->NewBlock(nullptr, 8, true, nopos); | |
| 431 } | |
| 420 | 432 |
| 421 Spread* spread = nullptr; | 433 Spread* spread = nullptr; |
| 422 for (Expression* value : *node->values()) { | 434 for (Expression* value : *node->values()) { |
| 423 if (value->IsSpread()) { | 435 if (value->IsSpread()) { |
| 424 spread = value->AsSpread(); | 436 spread = value->AsSpread(); |
| 425 break; | 437 break; |
| 426 } | 438 } |
| 427 | 439 |
| 428 PatternContext context = SetInitializerContextIfNeeded(value); | 440 PatternContext context = SetInitializerContextIfNeeded(value); |
| 441 | |
| 429 // if (!done) { | 442 // if (!done) { |
| 443 // done = true; // If .next, .done or .value throws, don't close. | |
| 430 // result = IteratorNext(iterator); | 444 // result = IteratorNext(iterator); |
| 431 // v = (done = result.done) ? undefined : result.value; | 445 // v = (done = result.done) ? undefined : result.value; |
| 432 // } | 446 // } |
| 433 auto next_block = | 447 Statement* if_statement; |
| 434 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); | 448 { |
| 435 next_block->statements()->Add(factory()->NewExpressionStatement( | 449 auto next_block = |
| 436 parser_->BuildIteratorNextResult( | 450 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); |
|
adamk
2016/03/08 18:41:13
This block now contains 3 statements.
| |
| 437 factory()->NewVariableProxy(iterator), | |
| 438 result, RelocInfo::kNoPosition), | |
| 439 RelocInfo::kNoPosition), | |
| 440 zone()); | |
| 441 | 451 |
| 442 auto assign_to_done = factory()->NewAssignment( | 452 next_block->statements()->Add( |
| 443 Token::ASSIGN, factory()->NewVariableProxy(done), | 453 factory()->NewExpressionStatement( |
| 444 factory()->NewProperty( | 454 factory()->NewAssignment( |
| 445 factory()->NewVariableProxy(result), | 455 Token::ASSIGN, factory()->NewVariableProxy(done), |
| 446 factory()->NewStringLiteral(ast_value_factory()->done_string(), | 456 factory()->NewBooleanLiteral(true, nopos), nopos), |
| 447 RelocInfo::kNoPosition), | 457 nopos), |
| 448 RelocInfo::kNoPosition), | 458 zone()); |
| 449 RelocInfo::kNoPosition); | |
| 450 auto next_value = factory()->NewConditional( | |
| 451 assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | |
| 452 factory()->NewProperty( | |
| 453 factory()->NewVariableProxy(result), | |
| 454 factory()->NewStringLiteral(ast_value_factory()->value_string(), | |
| 455 RelocInfo::kNoPosition), | |
| 456 RelocInfo::kNoPosition), | |
| 457 RelocInfo::kNoPosition); | |
| 458 next_block->statements()->Add( | |
| 459 factory()->NewExpressionStatement( | |
| 460 factory()->NewAssignment(Token::ASSIGN, | |
| 461 factory()->NewVariableProxy(v), next_value, | |
| 462 RelocInfo::kNoPosition), | |
| 463 RelocInfo::kNoPosition), | |
| 464 zone()); | |
| 465 | 459 |
| 466 auto if_statement = factory()->NewIfStatement( | 460 next_block->statements()->Add( |
| 467 factory()->NewUnaryOperation(Token::NOT, | 461 factory()->NewExpressionStatement( |
| 468 factory()->NewVariableProxy(done), | 462 parser_->BuildIteratorNextResult( |
| 469 RelocInfo::kNoPosition), | 463 factory()->NewVariableProxy(iterator), result, |
| 470 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 464 RelocInfo::kNoPosition), |
| 471 RelocInfo::kNoPosition); | 465 RelocInfo::kNoPosition), |
| 466 zone()); | |
| 467 | |
| 468 auto assign_to_done = factory()->NewAssignment( | |
| 469 Token::ASSIGN, factory()->NewVariableProxy(done), | |
| 470 factory()->NewProperty( | |
| 471 factory()->NewVariableProxy(result), | |
| 472 factory()->NewStringLiteral(ast_value_factory()->done_string(), | |
| 473 RelocInfo::kNoPosition), | |
| 474 RelocInfo::kNoPosition), | |
| 475 RelocInfo::kNoPosition); | |
| 476 auto next_value = factory()->NewConditional( | |
| 477 assign_to_done, | |
| 478 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | |
| 479 factory()->NewProperty( | |
| 480 factory()->NewVariableProxy(result), | |
| 481 factory()->NewStringLiteral(ast_value_factory()->value_string(), | |
| 482 RelocInfo::kNoPosition), | |
| 483 RelocInfo::kNoPosition), | |
| 484 RelocInfo::kNoPosition); | |
| 485 next_block->statements()->Add( | |
| 486 factory()->NewExpressionStatement( | |
| 487 factory()->NewAssignment( | |
| 488 Token::ASSIGN, factory()->NewVariableProxy(v), next_value, | |
| 489 RelocInfo::kNoPosition), | |
| 490 RelocInfo::kNoPosition), | |
| 491 zone()); | |
| 492 | |
| 493 if_statement = factory()->NewIfStatement( | |
| 494 factory()->NewUnaryOperation(Token::NOT, | |
| 495 factory()->NewVariableProxy(done), | |
| 496 RelocInfo::kNoPosition), | |
| 497 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), | |
| 498 RelocInfo::kNoPosition); | |
| 499 } | |
| 472 block_->statements()->Add(if_statement, zone()); | 500 block_->statements()->Add(if_statement, zone()); |
| 473 | 501 |
| 474 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { | 502 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { |
| 503 if (FLAG_harmony_iterator_close) { | |
| 504 // completion = ABRUPT; | |
| 505 Expression* proxy = factory()->NewVariableProxy(completion); | |
| 506 Expression* assignment = factory()->NewAssignment( | |
| 507 Token::ASSIGN, proxy, | |
| 508 factory()->NewSmiLiteral(ABRUPT, nopos), | |
| 509 nopos); | |
| 510 block_->statements()->Add( | |
| 511 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
| 512 } | |
| 513 | |
| 475 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); | 514 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); |
| 515 | |
| 516 if (FLAG_harmony_iterator_close) { | |
| 517 // completion = NORMAL; | |
| 518 Expression* proxy = factory()->NewVariableProxy(completion); | |
| 519 Expression* assignment = factory()->NewAssignment( | |
| 520 Token::ASSIGN, proxy, factory()->NewSmiLiteral(NORMAL, nopos), | |
| 521 nopos); | |
| 522 block_->statements()->Add( | |
| 523 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
| 524 } | |
| 476 } | 525 } |
| 477 set_context(context); | 526 set_context(context); |
| 478 } | 527 } |
| 479 | 528 |
| 480 if (spread != nullptr) { | 529 if (spread != nullptr) { |
| 481 // array = []; | 530 // A spread can only occur as the last component. It is not handled by |
| 531 // RecurseIntoSubpattern above. | |
| 532 | |
| 533 // let array = []; | |
| 482 // if (!done) %concat_iterable_to_array(array, iterator); | 534 // if (!done) %concat_iterable_to_array(array, iterator); |
| 535 // done = true; | |
| 536 | |
| 483 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); | 537 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); |
| 484 auto array = CreateTempVar(factory()->NewArrayLiteral( | 538 auto array = CreateTempVar(factory()->NewArrayLiteral( |
| 485 empty_exprs, | 539 empty_exprs, |
| 486 // Reuse pattern's literal index - it is unused since there is no | 540 // Reuse pattern's literal index - it is unused since there is no |
| 487 // actual literal allocated. | 541 // actual literal allocated. |
| 488 node->literal_index(), RelocInfo::kNoPosition)); | 542 node->literal_index(), RelocInfo::kNoPosition)); |
| 489 | 543 |
| 490 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); | 544 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); |
| 491 arguments->Add(factory()->NewVariableProxy(array), zone()); | 545 arguments->Add(factory()->NewVariableProxy(array), zone()); |
| 492 arguments->Add(factory()->NewVariableProxy(iterator), zone()); | 546 arguments->Add(factory()->NewVariableProxy(iterator), zone()); |
| 493 auto spread_into_array_call = | 547 auto spread_into_array_call = |
| 494 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, | 548 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, |
| 495 arguments, RelocInfo::kNoPosition); | 549 arguments, RelocInfo::kNoPosition); |
| 496 | 550 |
| 497 auto if_statement = factory()->NewIfStatement( | 551 auto if_statement = factory()->NewIfStatement( |
| 498 factory()->NewUnaryOperation(Token::NOT, | 552 factory()->NewUnaryOperation(Token::NOT, |
| 499 factory()->NewVariableProxy(done), | 553 factory()->NewVariableProxy(done), |
| 500 RelocInfo::kNoPosition), | 554 RelocInfo::kNoPosition), |
| 501 factory()->NewExpressionStatement(spread_into_array_call, | 555 factory()->NewExpressionStatement(spread_into_array_call, |
| 502 RelocInfo::kNoPosition), | 556 RelocInfo::kNoPosition), |
| 503 factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 557 factory()->NewEmptyStatement(RelocInfo::kNoPosition), |
| 504 RelocInfo::kNoPosition); | 558 RelocInfo::kNoPosition); |
| 505 block_->statements()->Add(if_statement, zone()); | 559 block_->statements()->Add(if_statement, zone()); |
| 506 | 560 |
| 561 auto set_done = factory()->NewAssignment( | |
| 562 Token::ASSIGN, factory()->NewVariableProxy(done), | |
| 563 factory()->NewBooleanLiteral(true, nopos), nopos); | |
| 564 block_->statements()->Add( | |
| 565 factory()->NewExpressionStatement(set_done, nopos), zone()); | |
| 566 | |
| 507 RecurseIntoSubpattern(spread->expression(), | 567 RecurseIntoSubpattern(spread->expression(), |
| 508 factory()->NewVariableProxy(array)); | 568 factory()->NewVariableProxy(array)); |
| 509 } | 569 } |
| 570 | |
| 571 if (FLAG_harmony_iterator_close) { | |
| 572 Expression* closing_condition = factory()->NewUnaryOperation( | |
| 573 Token::NOT, factory()->NewVariableProxy(done), nopos); | |
| 574 parser_->FinalizeIteratorUse( | |
| 575 completion, closing_condition, iterator, block_, target); | |
| 576 block_ = target; | |
| 577 } | |
| 510 } | 578 } |
| 511 | 579 |
| 512 | 580 |
| 513 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { | 581 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { |
| 514 Variable* temp_var = nullptr; | 582 Variable* temp_var = nullptr; |
| 515 VisitArrayLiteral(node, &temp_var); | 583 VisitArrayLiteral(node, &temp_var); |
| 516 } | 584 } |
| 517 | 585 |
| 518 | 586 |
| 519 void Parser::PatternRewriter::VisitAssignment(Assignment* node) { | 587 void Parser::PatternRewriter::VisitAssignment(Assignment* node) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 615 NOT_A_PATTERN(TryFinallyStatement) | 683 NOT_A_PATTERN(TryFinallyStatement) |
| 616 NOT_A_PATTERN(UnaryOperation) | 684 NOT_A_PATTERN(UnaryOperation) |
| 617 NOT_A_PATTERN(VariableDeclaration) | 685 NOT_A_PATTERN(VariableDeclaration) |
| 618 NOT_A_PATTERN(WhileStatement) | 686 NOT_A_PATTERN(WhileStatement) |
| 619 NOT_A_PATTERN(WithStatement) | 687 NOT_A_PATTERN(WithStatement) |
| 620 NOT_A_PATTERN(Yield) | 688 NOT_A_PATTERN(Yield) |
| 621 | 689 |
| 622 #undef NOT_A_PATTERN | 690 #undef NOT_A_PATTERN |
| 623 } // namespace internal | 691 } // namespace internal |
| 624 } // namespace v8 | 692 } // namespace v8 |
| OLD | NEW |