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 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 6510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6521 validate_output = factory->NewIfStatement( | 6521 validate_output = factory->NewIfStatement( |
6522 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); | 6522 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |
6523 } | 6523 } |
6524 | 6524 |
6525 statements->Add(get_return, zone); | 6525 statements->Add(get_return, zone); |
6526 statements->Add(check_return, zone); | 6526 statements->Add(check_return, zone); |
6527 statements->Add(call_return, zone); | 6527 statements->Add(call_return, zone); |
6528 statements->Add(validate_output, zone); | 6528 statements->Add(validate_output, zone); |
6529 } | 6529 } |
6530 | 6530 |
| 6531 void ParserTraits::FinalizeIteratorUse(Variable* completion, |
| 6532 Expression* condition, Variable* iter, |
| 6533 Block* iterator_use, Block* target) { |
| 6534 if (!FLAG_harmony_iterator_close) return; |
6531 | 6535 |
6532 // Runtime encoding of different completion modes. | 6536 // |
6533 enum ForOfLoopBodyCompletion { BODY_COMPLETED, BODY_ABORTED, BODY_THREW }; | 6537 // This function adds two statements to [target], corresponding to the |
| 6538 // following code: |
| 6539 // |
| 6540 // completion = kNormalCompletion; |
| 6541 // try { |
| 6542 // try { |
| 6543 // iterator_use |
| 6544 // } catch(e) { |
| 6545 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
| 6546 // throw e; |
| 6547 // } |
| 6548 // } finally { |
| 6549 // if (condition) { |
| 6550 // #BuildIteratorCloseForCompletion(iter, completion) |
| 6551 // } |
| 6552 // } |
| 6553 // |
| 6554 |
| 6555 const int nopos = RelocInfo::kNoPosition; |
| 6556 auto factory = parser_->factory(); |
| 6557 auto avfactory = parser_->ast_value_factory(); |
| 6558 auto scope = parser_->scope_; |
| 6559 auto zone = parser_->zone(); |
| 6560 |
| 6561 // completion = kNormalCompletion; |
| 6562 Statement* initialize_completion; |
| 6563 { |
| 6564 Expression* proxy = factory->NewVariableProxy(completion); |
| 6565 Expression* assignment = factory->NewAssignment( |
| 6566 Token::ASSIGN, proxy, |
| 6567 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
| 6568 initialize_completion = factory->NewExpressionStatement(assignment, nopos); |
| 6569 } |
| 6570 |
| 6571 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
| 6572 Statement* set_completion_throw; |
| 6573 { |
| 6574 Expression* condition = factory->NewCompareOperation( |
| 6575 Token::EQ_STRICT, factory->NewVariableProxy(completion), |
| 6576 factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); |
| 6577 |
| 6578 Expression* proxy = factory->NewVariableProxy(completion); |
| 6579 Expression* assignment = factory->NewAssignment( |
| 6580 Token::ASSIGN, proxy, |
| 6581 factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); |
| 6582 Statement* statement = factory->NewExpressionStatement(assignment, nopos); |
| 6583 set_completion_throw = factory->NewIfStatement( |
| 6584 condition, statement, factory->NewEmptyStatement(nopos), nopos); |
| 6585 } |
| 6586 |
| 6587 // if (condition) { |
| 6588 // #BuildIteratorCloseForCompletion(iter, completion) |
| 6589 // } |
| 6590 Block* maybe_close; |
| 6591 { |
| 6592 Block* block = factory->NewBlock(nullptr, 2, true, nopos); |
| 6593 parser_->BuildIteratorCloseForCompletion(block->statements(), iter, |
| 6594 completion); |
| 6595 DCHECK(block->statements()->length() == 2); |
| 6596 |
| 6597 maybe_close = factory->NewBlock(nullptr, 1, true, nopos); |
| 6598 maybe_close->statements()->Add( |
| 6599 factory->NewIfStatement(condition, block, |
| 6600 factory->NewEmptyStatement(nopos), nopos), |
| 6601 zone); |
| 6602 } |
| 6603 |
| 6604 // try { #try_block } |
| 6605 // catch(e) { |
| 6606 // #set_completion_throw; |
| 6607 // throw e; |
| 6608 // } |
| 6609 Statement* try_catch; |
| 6610 { |
| 6611 Scope* catch_scope = parser_->NewScope(scope, CATCH_SCOPE); |
| 6612 Variable* catch_variable = |
| 6613 catch_scope->DeclareLocal(avfactory->dot_catch_string(), VAR, |
| 6614 kCreatedInitialized, Variable::NORMAL); |
| 6615 |
| 6616 Statement* rethrow; |
| 6617 { |
| 6618 Expression* proxy = factory->NewVariableProxy(catch_variable); |
| 6619 rethrow = factory->NewExpressionStatement(factory->NewThrow(proxy, nopos), |
| 6620 nopos); |
| 6621 } |
| 6622 |
| 6623 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos); |
| 6624 catch_block->statements()->Add(set_completion_throw, zone); |
| 6625 catch_block->statements()->Add(rethrow, zone); |
| 6626 |
| 6627 try_catch = factory->NewTryCatchStatement( |
| 6628 iterator_use, catch_scope, catch_variable, catch_block, nopos); |
| 6629 } |
| 6630 |
| 6631 // try { #try_catch } finally { #maybe_close } |
| 6632 Statement* try_finally; |
| 6633 { |
| 6634 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); |
| 6635 try_block->statements()->Add(try_catch, zone); |
| 6636 |
| 6637 try_finally = |
| 6638 factory->NewTryFinallyStatement(try_block, maybe_close, nopos); |
| 6639 } |
| 6640 |
| 6641 target->statements()->Add(initialize_completion, zone); |
| 6642 target->statements()->Add(try_finally, zone); |
| 6643 } |
6534 | 6644 |
6535 void ParserTraits::BuildIteratorCloseForCompletion( | 6645 void ParserTraits::BuildIteratorCloseForCompletion( |
6536 ZoneList<Statement*>* statements, Variable* iterator, | 6646 ZoneList<Statement*>* statements, Variable* iterator, |
6537 Variable* completion) { | 6647 Variable* completion) { |
6538 // | 6648 // |
6539 // This function adds two statements to [statements], corresponding to the | 6649 // This function adds two statements to [statements], corresponding to the |
6540 // following code: | 6650 // following code: |
6541 // | 6651 // |
6542 // let iteratorReturn = iterator.return; | 6652 // let iteratorReturn = iterator.return; |
6543 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 6653 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
6544 // if (completion === BODY_THREW) { | 6654 // if (completion === kThrowCompletion) { |
6545 // if (!IS_CALLABLE(iteratorReturn)) { | 6655 // if (!IS_CALLABLE(iteratorReturn)) { |
6546 // throw MakeTypeError(kReturnMethodNotCallable); | 6656 // throw MakeTypeError(kReturnMethodNotCallable); |
6547 // } | 6657 // } |
6548 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 6658 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
6549 // } else { | 6659 // } else { |
6550 // let output = %_Call(iteratorReturn, iterator); | 6660 // let output = %_Call(iteratorReturn, iterator); |
6551 // if (!IS_RECEIVER(output)) { | 6661 // if (!IS_RECEIVER(output)) { |
6552 // %ThrowIterResultNotAnObject(output); | 6662 // %ThrowIterResultNotAnObject(output); |
6553 // } | 6663 // } |
6554 // } | 6664 // } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6652 } | 6762 } |
6653 | 6763 |
6654 Statement* check_return = factory->NewIfStatement( | 6764 Statement* check_return = factory->NewIfStatement( |
6655 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); | 6765 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |
6656 | 6766 |
6657 validate_return = factory->NewBlock(nullptr, 2, false, nopos); | 6767 validate_return = factory->NewBlock(nullptr, 2, false, nopos); |
6658 validate_return->statements()->Add(call_return, zone); | 6768 validate_return->statements()->Add(call_return, zone); |
6659 validate_return->statements()->Add(check_return, zone); | 6769 validate_return->statements()->Add(check_return, zone); |
6660 } | 6770 } |
6661 | 6771 |
6662 // if (completion === BODY_THREW) { | 6772 // if (completion === kThrowCompletion) { |
6663 // #check_return_callable; | 6773 // #check_return_callable; |
6664 // #try_call_return; | 6774 // #try_call_return; |
6665 // } else { | 6775 // } else { |
6666 // #validate_return; | 6776 // #validate_return; |
6667 // } | 6777 // } |
6668 Statement* call_return_carefully; | 6778 Statement* call_return_carefully; |
6669 { | 6779 { |
6670 Expression* condition = factory->NewCompareOperation( | 6780 Expression* condition = factory->NewCompareOperation( |
6671 Token::EQ_STRICT, factory->NewVariableProxy(completion), | 6781 Token::EQ_STRICT, factory->NewVariableProxy(completion), |
6672 factory->NewSmiLiteral(BODY_THREW, nopos), nopos); | 6782 factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); |
6673 | 6783 |
6674 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); | 6784 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); |
6675 then_block->statements()->Add(check_return_callable, zone); | 6785 then_block->statements()->Add(check_return_callable, zone); |
6676 then_block->statements()->Add(try_call_return, zone); | 6786 then_block->statements()->Add(try_call_return, zone); |
6677 | 6787 |
6678 call_return_carefully = | 6788 call_return_carefully = |
6679 factory->NewIfStatement(condition, then_block, validate_return, nopos); | 6789 factory->NewIfStatement(condition, then_block, validate_return, nopos); |
6680 } | 6790 } |
6681 | 6791 |
6682 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } | 6792 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } |
(...skipping 13 matching lines...) Expand all Loading... |
6696 statements->Add(maybe_call_return, zone); | 6806 statements->Add(maybe_call_return, zone); |
6697 } | 6807 } |
6698 | 6808 |
6699 | 6809 |
6700 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { | 6810 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { |
6701 if (!FLAG_harmony_iterator_close) return loop; | 6811 if (!FLAG_harmony_iterator_close) return loop; |
6702 | 6812 |
6703 // | 6813 // |
6704 // This function replaces the loop with the following wrapping: | 6814 // This function replaces the loop with the following wrapping: |
6705 // | 6815 // |
6706 // let completion = BODY_COMPLETED; | |
6707 // let each; | 6816 // let each; |
| 6817 // let completion = kNormalCompletion; |
6708 // try { | 6818 // try { |
6709 // #loop; | 6819 // try { |
6710 // } catch(e) { | 6820 // #loop; |
6711 // if (completion === BODY_ABORTED) completion = BODY_THREW; | 6821 // } catch(e) { |
6712 // throw e; | 6822 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
| 6823 // throw e; |
| 6824 // } |
6713 // } finally { | 6825 // } finally { |
6714 // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) { | 6826 // if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) { |
6715 // #BuildIteratorCloseForCompletion(#iterator, completion) | 6827 // #BuildIteratorCloseForCompletion(#iterator, completion) |
6716 // } | 6828 // } |
6717 // } | 6829 // } |
6718 // | 6830 // |
6719 // where the loop's body is wrapped as follows: | 6831 // where the loop's body is wrapped as follows: |
6720 // | 6832 // |
6721 // { | 6833 // { |
6722 // #loop-body | 6834 // #loop-body |
6723 // {{completion = BODY_COMPLETED;}} | 6835 // {{completion = kNormalCompletion;}} |
6724 // } | 6836 // } |
6725 // | 6837 // |
6726 // and assign_each is wrapped as follows | 6838 // and the loop's assign_each is wrapped as follows |
6727 // | 6839 // |
6728 // do { | 6840 // do { |
6729 // {{completion = BODY_ABORTED;}} | 6841 // {{completion = kAbruptCompletion;}} |
6730 // #assign-each | 6842 // #assign-each |
6731 // } into each | 6843 // } |
| 6844 // |
6732 | 6845 |
6733 const int nopos = RelocInfo::kNoPosition; | 6846 const int nopos = RelocInfo::kNoPosition; |
6734 auto factory = parser_->factory(); | 6847 auto factory = parser_->factory(); |
6735 auto avfactory = parser_->ast_value_factory(); | 6848 auto avfactory = parser_->ast_value_factory(); |
6736 auto scope = parser_->scope_; | 6849 auto scope = parser_->scope_; |
6737 auto zone = parser_->zone(); | 6850 auto zone = parser_->zone(); |
6738 | 6851 |
6739 // let completion = BODY_COMPLETED; | |
6740 Variable* var_completion = scope->NewTemporary(avfactory->empty_string()); | 6852 Variable* var_completion = scope->NewTemporary(avfactory->empty_string()); |
6741 Statement* initialize_completion; | |
6742 { | |
6743 Expression* proxy = factory->NewVariableProxy(var_completion); | |
6744 Expression* assignment = factory->NewAssignment( | |
6745 Token::ASSIGN, proxy, | |
6746 factory->NewSmiLiteral(BODY_COMPLETED, nopos), nopos); | |
6747 initialize_completion = | |
6748 factory->NewExpressionStatement(assignment, nopos); | |
6749 } | |
6750 | 6853 |
6751 // let each; | 6854 // let each; |
6752 Variable* var_each = scope->NewTemporary(avfactory->empty_string()); | 6855 Variable* var_each = scope->NewTemporary(avfactory->empty_string()); |
6753 Statement* initialize_each; | 6856 Statement* initialize_each; |
6754 { | 6857 { |
6755 Expression* proxy = factory->NewVariableProxy(var_each); | 6858 Expression* proxy = factory->NewVariableProxy(var_each); |
6756 Expression* assignment = factory->NewAssignment( | 6859 Expression* assignment = factory->NewAssignment( |
6757 Token::ASSIGN, proxy, | 6860 Token::ASSIGN, proxy, |
6758 factory->NewUndefinedLiteral(nopos), nopos); | 6861 factory->NewUndefinedLiteral(nopos), nopos); |
6759 initialize_each = | 6862 initialize_each = |
6760 factory->NewExpressionStatement(assignment, nopos); | 6863 factory->NewExpressionStatement(assignment, nopos); |
6761 } | 6864 } |
6762 | 6865 |
6763 // if (completion === BODY_ABORTED) completion = BODY_THREW; | 6866 // !(completion === kNormalCompletion || IS_UNDEFINED(#iterator)) |
6764 Statement* set_completion_throw; | 6867 Expression* closing_condition; |
6765 { | 6868 { |
6766 Expression* condition = factory->NewCompareOperation( | 6869 Expression* lhs = factory->NewCompareOperation( |
6767 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), | 6870 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), |
6768 factory->NewSmiLiteral(BODY_ABORTED, nopos), nopos); | 6871 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
6769 | 6872 Expression* rhs = factory->NewCompareOperation( |
6770 Expression* proxy = factory->NewVariableProxy(var_completion); | 6873 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()), |
6771 Expression* assignment = factory->NewAssignment( | 6874 factory->NewUndefinedLiteral(nopos), nopos); |
6772 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_THREW, nopos), | 6875 closing_condition = factory->NewUnaryOperation( |
| 6876 Token::NOT, factory->NewBinaryOperation(Token::OR, lhs, rhs, nopos), |
6773 nopos); | 6877 nopos); |
6774 Statement* statement = factory->NewExpressionStatement(assignment, nopos); | |
6775 set_completion_throw = factory->NewIfStatement( | |
6776 condition, statement, factory->NewEmptyStatement(nopos), nopos); | |
6777 } | 6878 } |
6778 | 6879 |
6779 // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) { | 6880 // {{completion = kNormalCompletion;}} |
6780 // #BuildIteratorCloseForCompletion(#iterator, completion) | |
6781 // } | |
6782 Block* maybe_close; | |
6783 { | |
6784 Expression* condition1 = factory->NewCompareOperation( | |
6785 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), | |
6786 factory->NewSmiLiteral(BODY_COMPLETED, nopos), nopos); | |
6787 Expression* condition2 = factory->NewCompareOperation( | |
6788 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()), | |
6789 factory->NewUndefinedLiteral(nopos), nopos); | |
6790 Expression* condition = factory->NewBinaryOperation( | |
6791 Token::OR, condition1, condition2, nopos); | |
6792 | |
6793 Block* block = factory->NewBlock(nullptr, 2, false, nopos); | |
6794 BuildIteratorCloseForCompletion( | |
6795 block->statements(), loop->iterator(), var_completion); | |
6796 DCHECK(block->statements()->length() == 2); | |
6797 | |
6798 maybe_close = factory->NewBlock(nullptr, 1, false, nopos); | |
6799 maybe_close->statements()->Add(factory->NewIfStatement( | |
6800 condition, factory->NewEmptyStatement(nopos), block, nopos), zone); | |
6801 } | |
6802 | |
6803 // try { #try_block } | |
6804 // catch(e) { | |
6805 // #set_completion_throw; | |
6806 // throw e; | |
6807 // } | |
6808 Statement* try_catch; | |
6809 { | |
6810 Scope* catch_scope = NewScope(scope, CATCH_SCOPE); | |
6811 Variable* catch_variable = catch_scope->DeclareLocal( | |
6812 avfactory->dot_catch_string(), VAR, kCreatedInitialized, | |
6813 Variable::NORMAL); | |
6814 | |
6815 Statement* rethrow; | |
6816 { | |
6817 Expression* proxy = factory->NewVariableProxy(catch_variable); | |
6818 rethrow = factory->NewExpressionStatement( | |
6819 factory->NewThrow(proxy, nopos), nopos); | |
6820 } | |
6821 | |
6822 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | |
6823 try_block->statements()->Add(loop, zone); | |
6824 | |
6825 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos); | |
6826 catch_block->statements()->Add(set_completion_throw, zone); | |
6827 catch_block->statements()->Add(rethrow, zone); | |
6828 | |
6829 try_catch = factory->NewTryCatchStatement( | |
6830 try_block, catch_scope, catch_variable, catch_block, nopos); | |
6831 } | |
6832 | |
6833 // try { #try_catch } finally { #maybe_close } | |
6834 Statement* try_finally; | |
6835 { | |
6836 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | |
6837 try_block->statements()->Add(try_catch, zone); | |
6838 | |
6839 try_finally = | |
6840 factory->NewTryFinallyStatement(try_block, maybe_close, nopos); | |
6841 } | |
6842 | |
6843 // #initialize_completion; | |
6844 // #initialize_each; | |
6845 // #try_finally; | |
6846 Statement* final_loop; | |
6847 { | |
6848 Block* block = factory->NewBlock(nullptr, 2, false, nopos); | |
6849 block->statements()->Add(initialize_completion, zone); | |
6850 block->statements()->Add(initialize_each, zone); | |
6851 block->statements()->Add(try_finally, zone); | |
6852 final_loop = block; | |
6853 } | |
6854 | |
6855 // {{completion = BODY_COMPLETED;}} | |
6856 Statement* set_completion_normal; | 6881 Statement* set_completion_normal; |
6857 { | 6882 { |
6858 Expression* proxy = factory->NewVariableProxy(var_completion); | 6883 Expression* proxy = factory->NewVariableProxy(var_completion); |
6859 Expression* assignment = factory->NewAssignment( | 6884 Expression* assignment = factory->NewAssignment( |
6860 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_COMPLETED, nopos), | 6885 Token::ASSIGN, proxy, |
6861 nopos); | 6886 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
6862 | 6887 |
6863 Block* block = factory->NewBlock(nullptr, 1, true, nopos); | 6888 Block* block = factory->NewBlock(nullptr, 1, true, nopos); |
6864 block->statements()->Add( | 6889 block->statements()->Add( |
6865 factory->NewExpressionStatement(assignment, nopos), zone); | 6890 factory->NewExpressionStatement(assignment, nopos), zone); |
6866 set_completion_normal = block; | 6891 set_completion_normal = block; |
6867 } | 6892 } |
6868 | 6893 |
| 6894 // {{completion = kAbruptCompletion;}} |
| 6895 Statement* set_completion_abrupt; |
| 6896 { |
| 6897 Expression* proxy = factory->NewVariableProxy(var_completion); |
| 6898 Expression* assignment = factory->NewAssignment( |
| 6899 Token::ASSIGN, proxy, |
| 6900 factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); |
| 6901 |
| 6902 Block* block = factory->NewBlock(nullptr, 1, true, nopos); |
| 6903 block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), |
| 6904 zone); |
| 6905 set_completion_abrupt = block; |
| 6906 } |
| 6907 |
6869 // { #loop-body; #set_completion_normal } | 6908 // { #loop-body; #set_completion_normal } |
6870 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); | 6909 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); |
6871 new_body->statements()->Add(loop->body(), zone); | 6910 { |
6872 new_body->statements()->Add(set_completion_normal, zone); | 6911 new_body->statements()->Add(loop->body(), zone); |
| 6912 new_body->statements()->Add(set_completion_normal, zone); |
| 6913 } |
| 6914 |
| 6915 // { #set_completion_abrupt; #assign-each } |
| 6916 Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); |
| 6917 { |
| 6918 new_assign_each->statements()->Add(set_completion_abrupt, zone); |
| 6919 new_assign_each->statements()->Add( |
| 6920 factory->NewExpressionStatement(loop->assign_each(), nopos), zone); |
| 6921 } |
| 6922 |
| 6923 // Now put things together. |
6873 | 6924 |
6874 loop->set_body(new_body); | 6925 loop->set_body(new_body); |
| 6926 loop->set_assign_each( |
| 6927 factory->NewDoExpression(new_assign_each, var_each, nopos)); |
6875 | 6928 |
6876 // {{completion = BODY_ABORTED;}} | 6929 Statement* final_loop; |
6877 Statement* set_completion_break; | |
6878 { | 6930 { |
6879 Expression* proxy = factory->NewVariableProxy(var_completion); | 6931 Block* target = factory->NewBlock(nullptr, 3, false, nopos); |
6880 Expression* assignment = factory->NewAssignment( | 6932 target->statements()->Add(initialize_each, zone); |
6881 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_ABORTED, nopos), | |
6882 nopos); | |
6883 | 6933 |
6884 Block* block = factory->NewBlock(nullptr, 1, true, nopos); | 6934 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); |
6885 block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), | 6935 try_block->statements()->Add(loop, zone); |
6886 zone); | 6936 |
6887 set_completion_break = block; | 6937 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(), |
| 6938 try_block, target); |
| 6939 final_loop = target; |
6888 } | 6940 } |
6889 | 6941 |
6890 // { #set_completion_break; #assign-each } | |
6891 Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); | |
6892 new_assign_each->statements()->Add(set_completion_break, zone); | |
6893 new_assign_each->statements()->Add( | |
6894 factory->NewExpressionStatement(loop->assign_each(), nopos), zone); | |
6895 | |
6896 Expression* do_each = | |
6897 factory->NewDoExpression(new_assign_each, var_each, nopos); | |
6898 loop->set_assign_each(do_each); | |
6899 | |
6900 return final_loop; | 6942 return final_loop; |
6901 } | 6943 } |
6902 | 6944 |
6903 | 6945 |
6904 } // namespace internal | 6946 } // namespace internal |
6905 } // namespace v8 | 6947 } // namespace v8 |
OLD | NEW |