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