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