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): DCHECK(block_->ignore_completion_value()); | |
| 411 | |
| 410 auto temp = *temp_var = CreateTempVar(current_value_); | 412 auto temp = *temp_var = CreateTempVar(current_value_); |
| 411 | |
| 412 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone()); | |
| 413 | |
| 414 auto iterator = CreateTempVar(parser_->GetIterator( | 413 auto iterator = CreateTempVar(parser_->GetIterator( |
| 415 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition)); | 414 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition)); |
| 416 auto done = CreateTempVar( | 415 auto done = CreateTempVar( |
| 417 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); | 416 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); |
| 418 auto result = CreateTempVar(); | 417 auto result = CreateTempVar(); |
| 419 auto v = CreateTempVar(); | 418 auto v = CreateTempVar(); |
| 419 auto completion = CreateTempVar(); | |
| 420 auto nopos = RelocInfo::kNoPosition; | |
| 421 | |
| 422 // For the purpose of iterator finalization, we temporarily set block_ to a | |
| 423 // new block. In the main body of this function, we write to block_ (both | |
| 424 // explicitly and implicitly via recursion). At the end of the function, we | |
| 425 // wrap this new block in a try-finally statement, restore block_ to its | |
| 426 // original value, and add the try-finally statement to block_. | |
| 427 auto target = block_; | |
| 428 if (FLAG_harmony_iterator_close) { | |
| 429 block_ = factory()->NewBlock(nullptr, 8, true, nopos); | |
| 430 } | |
| 420 | 431 |
| 421 Spread* spread = nullptr; | 432 Spread* spread = nullptr; |
| 422 for (Expression* value : *node->values()) { | 433 for (Expression* value : *node->values()) { |
| 423 if (value->IsSpread()) { | 434 if (value->IsSpread()) { |
| 424 spread = value->AsSpread(); | 435 spread = value->AsSpread(); |
| 425 break; | 436 break; |
| 426 } | 437 } |
| 427 | 438 |
| 428 PatternContext context = SetInitializerContextIfNeeded(value); | 439 PatternContext context = SetInitializerContextIfNeeded(value); |
| 440 | |
| 429 // if (!done) { | 441 // if (!done) { |
| 430 // result = IteratorNext(iterator); | 442 // result = IteratorNext(iterator); |
| 431 // v = (done = result.done) ? undefined : result.value; | 443 // v = (done = result.done) ? undefined : result.value; |
| 432 // } | 444 // } |
| 433 auto next_block = | 445 Statement* if_statement; |
| 434 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); | 446 { |
| 435 next_block->statements()->Add(factory()->NewExpressionStatement( | 447 auto next_block = |
| 436 parser_->BuildIteratorNextResult( | 448 factory()->NewBlock(nullptr, 2, true, nopos); |
|
adamk
2016/03/07 20:28:05
Can you leave stylistic changes out of this patch?
neis
2016/03/08 13:40:10
Ok, I removed them.
| |
| 437 factory()->NewVariableProxy(iterator), | 449 next_block->statements()->Add( |
| 438 result, RelocInfo::kNoPosition), | 450 factory()->NewExpressionStatement( |
| 439 RelocInfo::kNoPosition), | 451 parser_->BuildIteratorNextResult( |
| 440 zone()); | 452 factory()->NewVariableProxy(iterator), result, nopos), |
| 453 nopos), | |
| 454 zone()); | |
| 441 | 455 |
| 442 auto assign_to_done = factory()->NewAssignment( | 456 auto assign_to_done = factory()->NewAssignment( |
| 443 Token::ASSIGN, factory()->NewVariableProxy(done), | 457 Token::ASSIGN, factory()->NewVariableProxy(done), |
| 444 factory()->NewProperty( | 458 factory()->NewProperty( |
| 445 factory()->NewVariableProxy(result), | 459 factory()->NewVariableProxy(result), |
| 446 factory()->NewStringLiteral(ast_value_factory()->done_string(), | 460 factory()->NewStringLiteral(ast_value_factory()->done_string(), |
| 447 RelocInfo::kNoPosition), | 461 nopos), |
| 448 RelocInfo::kNoPosition), | 462 nopos), |
| 449 RelocInfo::kNoPosition); | 463 nopos); |
| 450 auto next_value = factory()->NewConditional( | 464 auto next_value = factory()->NewConditional( |
| 451 assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | 465 assign_to_done, factory()->NewUndefinedLiteral(nopos), |
| 452 factory()->NewProperty( | 466 factory()->NewProperty( |
| 453 factory()->NewVariableProxy(result), | 467 factory()->NewVariableProxy(result), |
| 454 factory()->NewStringLiteral(ast_value_factory()->value_string(), | 468 factory()->NewStringLiteral(ast_value_factory()->value_string(), |
| 455 RelocInfo::kNoPosition), | 469 nopos), |
| 456 RelocInfo::kNoPosition), | 470 nopos), |
| 457 RelocInfo::kNoPosition); | 471 nopos); |
| 458 next_block->statements()->Add( | 472 next_block->statements()->Add( |
| 459 factory()->NewExpressionStatement( | 473 factory()->NewExpressionStatement( |
| 460 factory()->NewAssignment(Token::ASSIGN, | 474 factory()->NewAssignment( |
| 461 factory()->NewVariableProxy(v), next_value, | 475 Token::ASSIGN, factory()->NewVariableProxy(v), next_value, |
| 462 RelocInfo::kNoPosition), | 476 nopos), |
| 463 RelocInfo::kNoPosition), | 477 nopos), |
| 464 zone()); | 478 zone()); |
| 465 | 479 |
| 466 auto if_statement = factory()->NewIfStatement( | 480 if_statement = factory()->NewIfStatement( |
| 467 factory()->NewUnaryOperation(Token::NOT, | 481 factory()->NewUnaryOperation(Token::NOT, |
| 468 factory()->NewVariableProxy(done), | 482 factory()->NewVariableProxy(done), |
| 469 RelocInfo::kNoPosition), | 483 nopos), |
| 470 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 484 next_block, factory()->NewEmptyStatement(nopos), |
| 471 RelocInfo::kNoPosition); | 485 nopos); |
| 486 } | |
| 472 block_->statements()->Add(if_statement, zone()); | 487 block_->statements()->Add(if_statement, zone()); |
| 473 | 488 |
| 474 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { | 489 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { |
| 490 if (FLAG_harmony_iterator_close) { | |
| 491 // completion = ABRUPT; | |
| 492 Expression* proxy = factory()->NewVariableProxy(completion); | |
| 493 Expression* assignment = factory()->NewAssignment( | |
| 494 Token::ASSIGN, proxy, | |
| 495 factory()->NewSmiLiteral(ABRUPT, nopos), | |
| 496 nopos); | |
| 497 block_->statements()->Add( | |
| 498 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
| 499 } | |
| 500 | |
| 475 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); | 501 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); |
| 502 | |
| 503 if (FLAG_harmony_iterator_close) { | |
| 504 // completion = NORMAL; | |
| 505 Expression* proxy = factory()->NewVariableProxy(completion); | |
| 506 Expression* assignment = factory()->NewAssignment( | |
| 507 Token::ASSIGN, proxy, factory()->NewSmiLiteral(NORMAL, nopos), | |
| 508 nopos); | |
| 509 block_->statements()->Add( | |
| 510 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
| 511 } | |
| 476 } | 512 } |
| 477 set_context(context); | 513 set_context(context); |
| 478 } | 514 } |
| 479 | 515 |
| 480 if (spread != nullptr) { | 516 if (spread != nullptr) { |
| 481 // array = []; | 517 // A spread can only occur as the last component. It is not handled by |
| 482 // if (!done) %concat_iterable_to_array(array, iterator); | 518 // RecurseIntoSubpattern above. |
| 519 // | |
| 520 // let array = []; | |
| 521 // while (!done) { | |
|
adamk
2016/03/07 20:28:05
This change is already giant (and thus tricky to r
neis
2016/03/08 13:40:10
Except that 'done' must be set to true at the end.
| |
| 522 // result = IteratorNext(iterator); | |
| 523 // if (!(done = result.done)) %AppendElement(array, result.value); | |
| 524 // } | |
| 525 // <.completion = ABRUPT> | |
|
adamk
2016/03/07 20:28:05
This doesn't seem right to me. The recursion is ov
neis
2016/03/08 13:40:10
Oops, these two assignments were wrong here indeed
| |
| 526 // #recurse | |
| 527 // <.completion = NORMAL> | |
| 528 | |
| 483 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); | 529 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); |
| 484 auto array = CreateTempVar(factory()->NewArrayLiteral( | 530 auto array = CreateTempVar(factory()->NewArrayLiteral( |
| 485 empty_exprs, | 531 empty_exprs, |
| 486 // Reuse pattern's literal index - it is unused since there is no | 532 // Reuse pattern's literal index - it is unused since there is no |
| 487 // actual literal allocated. | 533 // actual literal allocated. |
| 488 node->literal_index(), RelocInfo::kNoPosition)); | 534 node->literal_index(), nopos)); |
| 489 | 535 |
| 490 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); | 536 // result = IteratorNext(iterator); |
| 491 arguments->Add(factory()->NewVariableProxy(array), zone()); | 537 Statement* get_next = factory()->NewExpressionStatement( |
| 492 arguments->Add(factory()->NewVariableProxy(iterator), zone()); | 538 parser_->BuildIteratorNextResult( |
| 493 auto spread_into_array_call = | 539 factory()->NewVariableProxy(iterator), result, nopos), |
| 494 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, | 540 nopos); |
| 495 arguments, RelocInfo::kNoPosition); | |
| 496 | 541 |
| 497 auto if_statement = factory()->NewIfStatement( | 542 // done = result.done |
| 498 factory()->NewUnaryOperation(Token::NOT, | 543 auto set_done = factory()->NewAssignment( |
| 499 factory()->NewVariableProxy(done), | 544 Token::ASSIGN, factory()->NewVariableProxy(done), |
| 500 RelocInfo::kNoPosition), | 545 factory()->NewProperty( |
| 501 factory()->NewExpressionStatement(spread_into_array_call, | 546 factory()->NewVariableProxy(result), |
| 502 RelocInfo::kNoPosition), | 547 factory()->NewStringLiteral(ast_value_factory()->done_string(), |
| 503 factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 548 nopos), |
| 504 RelocInfo::kNoPosition); | 549 nopos), nopos); |
| 505 block_->statements()->Add(if_statement, zone()); | |
| 506 | 550 |
| 551 // result.value | |
| 552 Expression* result_value = factory()->NewProperty( | |
| 553 factory()->NewVariableProxy(result), | |
| 554 factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos), | |
| 555 nopos); | |
| 556 | |
| 557 // %AppendElement(array, result.value); | |
| 558 Statement* append_element; | |
| 559 { | |
| 560 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | |
| 561 args->Add(factory()->NewVariableProxy(array), zone()); | |
| 562 args->Add(result_value, zone()); | |
| 563 | |
| 564 append_element = factory()->NewExpressionStatement( | |
| 565 factory()->NewCallRuntime(Runtime::kAppendElement, args, nopos), | |
| 566 nopos); | |
| 567 } | |
| 568 | |
| 569 // if (!#set_done) #append_element; | |
| 570 auto maybe_append = factory()->NewIfStatement( | |
| 571 factory()->NewUnaryOperation(Token::NOT, set_done, nopos), | |
| 572 append_element, factory()->NewEmptyStatement(nopos), nopos); | |
| 573 | |
| 574 // while (#not_done) { | |
| 575 // #get_next; | |
| 576 // #maybe_append; | |
| 577 // } | |
| 578 WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos); | |
| 579 { | |
| 580 Expression* condition = factory()->NewUnaryOperation( | |
| 581 Token::NOT, factory()->NewVariableProxy(done), nopos); | |
| 582 Block* body = factory()->NewBlock(nullptr, 2, true, nopos); | |
| 583 body->statements()->Add(get_next, zone()); | |
| 584 body->statements()->Add(maybe_append, zone()); | |
| 585 loop->Initialize(condition, body); | |
| 586 } | |
| 587 | |
| 588 // completion = ABRUPT; | |
| 589 Statement* set_aborted; | |
| 590 if (FLAG_harmony_iterator_close) { | |
| 591 Expression* proxy = factory()->NewVariableProxy(completion); | |
| 592 Expression* assignment = factory()->NewAssignment( | |
| 593 Token::ASSIGN, proxy, | |
| 594 factory()->NewSmiLiteral(ABRUPT, nopos), nopos); | |
| 595 set_aborted = | |
| 596 factory()->NewExpressionStatement(assignment, nopos); | |
| 597 } | |
| 598 | |
| 599 // completion = NORMAL; | |
| 600 Statement* set_completed; | |
| 601 if (FLAG_harmony_iterator_close) { | |
| 602 Expression* proxy = factory()->NewVariableProxy(completion); | |
| 603 Expression* assignment = factory()->NewAssignment( | |
| 604 Token::ASSIGN, proxy, | |
| 605 factory()->NewSmiLiteral(NORMAL, nopos), nopos); | |
| 606 set_completed = | |
| 607 factory()->NewExpressionStatement(assignment, nopos); | |
| 608 } | |
| 609 | |
| 610 block_->statements()->Add(loop, zone()); | |
| 611 if (FLAG_harmony_iterator_close) { | |
| 612 block_->statements()->Add(set_aborted, zone()); | |
| 613 } | |
| 507 RecurseIntoSubpattern(spread->expression(), | 614 RecurseIntoSubpattern(spread->expression(), |
| 508 factory()->NewVariableProxy(array)); | 615 factory()->NewVariableProxy(array)); |
| 616 if (FLAG_harmony_iterator_close) { | |
| 617 block_->statements()->Add(set_completed, zone()); | |
| 618 } | |
| 619 } | |
| 620 | |
| 621 if (FLAG_harmony_iterator_close) { | |
| 622 Expression* condition = factory()->NewUnaryOperation( | |
| 623 Token::NOT, factory()->NewVariableProxy(done), nopos); | |
| 624 parser_->FinalizeIteratorUse( | |
| 625 completion, condition, iterator, block_, target); | |
| 626 block_ = target; | |
| 509 } | 627 } |
| 510 } | 628 } |
| 511 | 629 |
| 512 | 630 |
| 513 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { | 631 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { |
| 514 Variable* temp_var = nullptr; | 632 Variable* temp_var = nullptr; |
| 515 VisitArrayLiteral(node, &temp_var); | 633 VisitArrayLiteral(node, &temp_var); |
| 516 } | 634 } |
| 517 | 635 |
| 518 | 636 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 615 NOT_A_PATTERN(TryFinallyStatement) | 733 NOT_A_PATTERN(TryFinallyStatement) |
| 616 NOT_A_PATTERN(UnaryOperation) | 734 NOT_A_PATTERN(UnaryOperation) |
| 617 NOT_A_PATTERN(VariableDeclaration) | 735 NOT_A_PATTERN(VariableDeclaration) |
| 618 NOT_A_PATTERN(WhileStatement) | 736 NOT_A_PATTERN(WhileStatement) |
| 619 NOT_A_PATTERN(WithStatement) | 737 NOT_A_PATTERN(WithStatement) |
| 620 NOT_A_PATTERN(Yield) | 738 NOT_A_PATTERN(Yield) |
| 621 | 739 |
| 622 #undef NOT_A_PATTERN | 740 #undef NOT_A_PATTERN |
| 623 } // namespace internal | 741 } // namespace internal |
| 624 } // namespace v8 | 742 } // namespace v8 |
| OLD | NEW |