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 |