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 6260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6271 do_block->statements()->Add(get_value, zone); | 6271 do_block->statements()->Add(get_value, zone); |
6272 | 6272 |
6273 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); | 6273 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); |
6274 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 6274 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); |
6275 Rewriter::Rewrite(parser_, yield_star, avfactory); | 6275 Rewriter::Rewrite(parser_, yield_star, avfactory); |
6276 } | 6276 } |
6277 | 6277 |
6278 return yield_star; | 6278 return yield_star; |
6279 } | 6279 } |
6280 | 6280 |
6281 | |
6281 // Desugaring of (lhs) instanceof (rhs) | 6282 // Desugaring of (lhs) instanceof (rhs) |
6282 // ==================================== | 6283 // ==================================== |
6283 // | 6284 // |
6284 // We desugar instanceof into a load of property @@hasInstance on the rhs. | 6285 // We desugar instanceof into a load of property @@hasInstance on the rhs. |
6285 // We end up with roughly the following code (O, C): | 6286 // We end up with roughly the following code: |
6286 // | 6287 // |
6287 // do { | 6288 // do { |
6288 // let O = lhs; | 6289 // let O = lhs; |
6289 // let C = rhs; | 6290 // let C = rhs; |
6290 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); | 6291 // if (!IS_RECEIVER(C)) throw MakeTypeError(kNonObjectInInstanceOfCheck); |
6291 // let handler_result = C[Symbol.hasInstance]; | 6292 // let handler_result = C[Symbol.hasInstance]; |
6292 // if (handler_result === undefined) { | 6293 // if (handler_result === undefined) { |
6293 // if (!IS_CALLABLE(C)) { | 6294 // if (!IS_CALLABLE(C)) { |
6294 // throw MakeTypeError(kCalledNonCallableInstanceOf); | 6295 // throw MakeTypeError(kCalledNonCallableInstanceOf); |
6295 // } | 6296 // } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6359 Expression* handler_proxy = factory->NewVariableProxy(var_handler_result); | 6360 Expression* handler_proxy = factory->NewVariableProxy(var_handler_result); |
6360 Expression* assignment = | 6361 Expression* assignment = |
6361 factory->NewAssignment(Token::ASSIGN, handler_proxy, prop, nopos); | 6362 factory->NewAssignment(Token::ASSIGN, handler_proxy, prop, nopos); |
6362 initialize_handler = factory->NewExpressionStatement(assignment, nopos); | 6363 initialize_handler = factory->NewExpressionStatement(assignment, nopos); |
6363 } | 6364 } |
6364 | 6365 |
6365 // if (handler_result === undefined) { | 6366 // if (handler_result === undefined) { |
6366 // if (!IS_CALLABLE(C)) { | 6367 // if (!IS_CALLABLE(C)) { |
6367 // throw MakeTypeError(kCalledNonCallableInstanceOf); | 6368 // throw MakeTypeError(kCalledNonCallableInstanceOf); |
6368 // } | 6369 // } |
6369 // result = %ordinary_has_instance(C, O); | 6370 // handler_result = %ordinary_has_instance(C, O); |
6370 // } else { | 6371 // } else { |
6371 // handler_result = !!%_Call(handler_result, C, O); | 6372 // handler_result = !!%_Call(handler_result, C, O); |
6372 // } | 6373 // } |
6373 Statement* call_handler; | 6374 Statement* call_handler; |
6374 { | 6375 { |
6375 Expression* condition = factory->NewCompareOperation( | 6376 Expression* condition = factory->NewCompareOperation( |
6376 Token::EQ_STRICT, factory->NewVariableProxy(var_handler_result), | 6377 Token::EQ_STRICT, factory->NewVariableProxy(var_handler_result), |
6377 factory->NewUndefinedLiteral(nopos), nopos); | 6378 factory->NewUndefinedLiteral(nopos), nopos); |
6378 | 6379 |
6379 Block* then_side = factory->NewBlock(nullptr, 2, false, nopos); | 6380 Block* then_side = factory->NewBlock(nullptr, 2, false, nopos); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6430 block->statements()->Add(call_handler, zone); | 6431 block->statements()->Add(call_handler, zone); |
6431 | 6432 |
6432 // Here is the desugared instanceof. | 6433 // Here is the desugared instanceof. |
6433 instanceof = factory->NewDoExpression(block, var_handler_result, nopos); | 6434 instanceof = factory->NewDoExpression(block, var_handler_result, nopos); |
6434 Rewriter::Rewrite(parser_, instanceof, avfactory); | 6435 Rewriter::Rewrite(parser_, instanceof, avfactory); |
6435 } | 6436 } |
6436 | 6437 |
6437 return instanceof; | 6438 return instanceof; |
6438 } | 6439 } |
6439 | 6440 |
6441 | |
6440 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error) { | 6442 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error) { |
6441 auto factory = parser_->factory(); | 6443 auto factory = parser_->factory(); |
6442 auto avfactory = parser_->ast_value_factory(); | 6444 auto avfactory = parser_->ast_value_factory(); |
6443 const int nopos = RelocInfo::kNoPosition; | 6445 const int nopos = RelocInfo::kNoPosition; |
6444 Statement* validate_var; | 6446 Statement* validate_var; |
6445 { | 6447 { |
6446 Expression* type_of = factory->NewUnaryOperation( | 6448 Expression* type_of = factory->NewUnaryOperation( |
6447 Token::TYPEOF, factory->NewVariableProxy(var), nopos); | 6449 Token::TYPEOF, factory->NewVariableProxy(var), nopos); |
6448 Expression* function_literal = | 6450 Expression* function_literal = |
6449 factory->NewStringLiteral(avfactory->function_string(), nopos); | 6451 factory->NewStringLiteral(avfactory->function_string(), nopos); |
6450 Expression* condition = factory->NewCompareOperation( | 6452 Expression* condition = factory->NewCompareOperation( |
6451 Token::EQ_STRICT, type_of, function_literal, nopos); | 6453 Token::EQ_STRICT, type_of, function_literal, nopos); |
6452 | 6454 |
6453 Statement* throw_call = factory->NewExpressionStatement(error, nopos); | 6455 Statement* throw_call = factory->NewExpressionStatement(error, nopos); |
6454 | 6456 |
6455 validate_var = factory->NewIfStatement( | 6457 validate_var = factory->NewIfStatement( |
6456 condition, factory->NewEmptyStatement(nopos), throw_call, nopos); | 6458 condition, factory->NewEmptyStatement(nopos), throw_call, nopos); |
6457 } | 6459 } |
6458 return validate_var; | 6460 return validate_var; |
6459 } | 6461 } |
6460 | 6462 |
6463 | |
6461 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 6464 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, |
6462 Variable* iterator, | 6465 Variable* iterator, |
6463 Maybe<Variable*> input, | 6466 Maybe<Variable*> input, |
6464 Variable* var_output) { | 6467 Variable* var_output) { |
6465 // | 6468 // |
6466 // This function adds four statements to [statements], corresponding to the | 6469 // This function adds four statements to [statements], corresponding to the |
6467 // following code: | 6470 // following code: |
6468 // | 6471 // |
6469 // let iteratorReturn = iterator.return; | 6472 // let iteratorReturn = iterator.return; |
6470 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return |input|; | 6473 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return |input|; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6556 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); | 6559 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |
6557 } | 6560 } |
6558 | 6561 |
6559 statements->Add(get_return, zone); | 6562 statements->Add(get_return, zone); |
6560 statements->Add(check_return, zone); | 6563 statements->Add(check_return, zone); |
6561 statements->Add(call_return, zone); | 6564 statements->Add(call_return, zone); |
6562 statements->Add(validate_output, zone); | 6565 statements->Add(validate_output, zone); |
6563 } | 6566 } |
6564 | 6567 |
6565 | 6568 |
6566 // Runtime encoding of different completion modes. | 6569 void ParserTraits::FinalizeIteratorUse( |
6567 enum ForOfLoopBodyCompletion { BODY_COMPLETED, BODY_ABORTED, BODY_THREW }; | 6570 Variable* completion, Expression* condition, Variable* iter, |
6571 Block* iterator_use, Block* target) { | |
6572 if (!FLAG_harmony_iterator_close) return; | |
6573 | |
6574 // | |
6575 // This function adds two statements to [target], corresponding to the | |
6576 // following code: | |
adamk
2016/03/08 01:57:07
It's somewhat confusing that this code contains a
neis
2016/03/08 13:40:10
Done.
| |
6577 // | |
6578 // completion = NORMAL; | |
6579 // try { | |
6580 // iterator_use | |
6581 // } catch(e) { | |
6582 // if (completion === ABRUPT) completion = THROW; | |
6583 // throw e; | |
6584 // } finally { | |
6585 // if (condition) { | |
6586 // #BuildIteratorCloseForCompletion(iter, completion) | |
6587 // } | |
6588 // } | |
6589 // | |
6590 | |
6591 const int nopos = RelocInfo::kNoPosition; | |
6592 auto factory = parser_->factory(); | |
adamk
2016/03/08 01:57:07
If you put this function in Parser instead of Pars
| |
6593 auto avfactory = parser_->ast_value_factory(); | |
6594 auto scope = parser_->scope_; | |
6595 auto zone = parser_->zone(); | |
6596 | |
6597 // completion = NORMAL; | |
6598 Statement* initialize_completion; | |
6599 { | |
6600 Expression* proxy = factory->NewVariableProxy(completion); | |
6601 Expression* assignment = factory->NewAssignment( | |
6602 Token::ASSIGN, proxy, | |
6603 factory->NewSmiLiteral(Parser::NORMAL, nopos), nopos); | |
6604 initialize_completion = | |
6605 factory->NewExpressionStatement(assignment, nopos); | |
6606 } | |
6607 | |
6608 // if (completion === ABRUPT) completion = THROW; | |
6609 Statement* set_completion_throw; | |
6610 { | |
6611 Expression* condition = factory->NewCompareOperation( | |
6612 Token::EQ_STRICT, factory->NewVariableProxy(completion), | |
6613 factory->NewSmiLiteral(Parser::ABRUPT, nopos), nopos); | |
6614 | |
6615 Expression* proxy = factory->NewVariableProxy(completion); | |
6616 Expression* assignment = factory->NewAssignment( | |
6617 Token::ASSIGN, proxy, factory->NewSmiLiteral(Parser::THROW, nopos), | |
6618 nopos); | |
6619 Statement* statement = factory->NewExpressionStatement(assignment, nopos); | |
6620 set_completion_throw = factory->NewIfStatement( | |
6621 condition, statement, factory->NewEmptyStatement(nopos), nopos); | |
6622 } | |
6623 | |
6624 // if (condition) { | |
6625 // #BuildIteratorCloseForCompletion(iter, completion) | |
6626 // } | |
6627 Block* maybe_close; | |
6628 { | |
6629 Block* block = factory->NewBlock(nullptr, 2, true, nopos); | |
6630 parser_->BuildIteratorCloseForCompletion( | |
6631 block->statements(), iter, completion); | |
6632 DCHECK(block->statements()->length() == 2); | |
6633 | |
6634 maybe_close = factory->NewBlock(nullptr, 1, true, nopos); | |
6635 maybe_close->statements()->Add(factory->NewIfStatement( | |
6636 condition, block, factory->NewEmptyStatement(nopos), nopos), zone); | |
6637 } | |
6638 | |
6639 // try { #try_block } | |
6640 // catch(e) { | |
6641 // #set_completion_throw; | |
6642 // throw e; | |
6643 // } | |
6644 Statement* try_catch; | |
6645 { | |
6646 Scope* catch_scope = parser_->NewScope(scope, CATCH_SCOPE); | |
6647 Variable* catch_variable = catch_scope->DeclareLocal( | |
6648 avfactory->dot_catch_string(), VAR, kCreatedInitialized, | |
6649 Variable::NORMAL); | |
6650 | |
6651 Statement* rethrow; | |
6652 { | |
6653 Expression* proxy = factory->NewVariableProxy(catch_variable); | |
6654 rethrow = factory->NewExpressionStatement( | |
6655 factory->NewThrow(proxy, nopos), nopos); | |
6656 } | |
6657 | |
6658 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos); | |
6659 catch_block->statements()->Add(set_completion_throw, zone); | |
6660 catch_block->statements()->Add(rethrow, zone); | |
6661 | |
6662 try_catch = factory->NewTryCatchStatement( | |
6663 iterator_use, catch_scope, catch_variable, catch_block, nopos); | |
6664 } | |
6665 | |
6666 // try { #try_catch } finally { #maybe_close } | |
6667 Statement* try_finally; | |
6668 { | |
6669 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | |
6670 try_block->statements()->Add(try_catch, zone); | |
6671 | |
6672 try_finally = | |
6673 factory->NewTryFinallyStatement(try_block, maybe_close, nopos); | |
6674 } | |
6675 | |
6676 target->statements()->Add(initialize_completion, zone); | |
6677 target->statements()->Add(try_finally, zone); | |
6678 } | |
6679 | |
6568 | 6680 |
6569 void ParserTraits::BuildIteratorCloseForCompletion( | 6681 void ParserTraits::BuildIteratorCloseForCompletion( |
6570 ZoneList<Statement*>* statements, Variable* iterator, | 6682 ZoneList<Statement*>* statements, Variable* iterator, |
6571 Variable* completion) { | 6683 Variable* completion) { |
6572 // | 6684 // |
6573 // This function adds two statements to [statements], corresponding to the | 6685 // This function adds two statements to [statements], corresponding to the |
6574 // following code: | 6686 // following code: |
6575 // | 6687 // |
6576 // let iteratorReturn = iterator.return; | 6688 // let iteratorReturn = iterator.return; |
6577 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 6689 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
6578 // if (completion === BODY_THREW) { | 6690 // if (completion === THROW) { |
6579 // if (!IS_CALLABLE(iteratorReturn)) { | 6691 // if (!IS_CALLABLE(iteratorReturn)) { |
6580 // throw MakeTypeError(kReturnMethodNotCallable); | 6692 // throw MakeTypeError(kReturnMethodNotCallable); |
6581 // } | 6693 // } |
6582 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 6694 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
6583 // } else { | 6695 // } else { |
6584 // let output = %_Call(iteratorReturn, iterator); | 6696 // let output = %_Call(iteratorReturn, iterator); |
6585 // if (!IS_RECEIVER(output)) { | 6697 // if (!IS_RECEIVER(output)) { |
6586 // %ThrowIterResultNotAnObject(output); | 6698 // %ThrowIterResultNotAnObject(output); |
6587 // } | 6699 // } |
6588 // } | 6700 // } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6686 } | 6798 } |
6687 | 6799 |
6688 Statement* check_return = factory->NewIfStatement( | 6800 Statement* check_return = factory->NewIfStatement( |
6689 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); | 6801 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |
6690 | 6802 |
6691 validate_return = factory->NewBlock(nullptr, 2, false, nopos); | 6803 validate_return = factory->NewBlock(nullptr, 2, false, nopos); |
6692 validate_return->statements()->Add(call_return, zone); | 6804 validate_return->statements()->Add(call_return, zone); |
6693 validate_return->statements()->Add(check_return, zone); | 6805 validate_return->statements()->Add(check_return, zone); |
6694 } | 6806 } |
6695 | 6807 |
6696 // if (completion === BODY_THREW) { | 6808 // if (completion === THROW) { |
6697 // #check_return_callable; | 6809 // #check_return_callable; |
6698 // #try_call_return; | 6810 // #try_call_return; |
6699 // } else { | 6811 // } else { |
6700 // #validate_return; | 6812 // #validate_return; |
6701 // } | 6813 // } |
6702 Statement* call_return_carefully; | 6814 Statement* call_return_carefully; |
6703 { | 6815 { |
6704 Expression* condition = factory->NewCompareOperation( | 6816 Expression* condition = factory->NewCompareOperation( |
6705 Token::EQ_STRICT, factory->NewVariableProxy(completion), | 6817 Token::EQ_STRICT, factory->NewVariableProxy(completion), |
6706 factory->NewSmiLiteral(BODY_THREW, nopos), nopos); | 6818 factory->NewSmiLiteral(Parser::THROW, nopos), nopos); |
6707 | 6819 |
6708 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); | 6820 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); |
6709 then_block->statements()->Add(check_return_callable, zone); | 6821 then_block->statements()->Add(check_return_callable, zone); |
6710 then_block->statements()->Add(try_call_return, zone); | 6822 then_block->statements()->Add(try_call_return, zone); |
6711 | 6823 |
6712 call_return_carefully = | 6824 call_return_carefully = |
6713 factory->NewIfStatement(condition, then_block, validate_return, nopos); | 6825 factory->NewIfStatement(condition, then_block, validate_return, nopos); |
6714 } | 6826 } |
6715 | 6827 |
6716 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } | 6828 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } |
(...skipping 13 matching lines...) Expand all Loading... | |
6730 statements->Add(maybe_call_return, zone); | 6842 statements->Add(maybe_call_return, zone); |
6731 } | 6843 } |
6732 | 6844 |
6733 | 6845 |
6734 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { | 6846 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { |
6735 if (!FLAG_harmony_iterator_close) return loop; | 6847 if (!FLAG_harmony_iterator_close) return loop; |
6736 | 6848 |
6737 // | 6849 // |
6738 // This function replaces the loop with the following wrapping: | 6850 // This function replaces the loop with the following wrapping: |
6739 // | 6851 // |
6740 // let completion = BODY_COMPLETED; | |
6741 // let each; | 6852 // let each; |
6853 // let completion = NORMAL; | |
6742 // try { | 6854 // try { |
6743 // #loop; | 6855 // #loop; |
6744 // } catch(e) { | 6856 // } catch(e) { |
6745 // if (completion === BODY_ABORTED) completion = BODY_THREW; | 6857 // if (completion === ABRUPT) completion = THROW; |
6746 // throw e; | 6858 // throw e; |
6747 // } finally { | 6859 // } finally { |
6748 // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) { | 6860 // if (!(completion === NORMAL || IS_UNDEFINED(#iterator))) { |
6749 // #BuildIteratorCloseForCompletion(#iterator, completion) | 6861 // #BuildIteratorCloseForCompletion(#iterator, completion) |
6750 // } | 6862 // } |
6751 // } | 6863 // } |
6752 // | 6864 // |
6753 // where the loop's body is wrapped as follows: | 6865 // where the loop's body is wrapped as follows: |
6754 // | 6866 // |
6755 // { | 6867 // { |
6756 // #loop-body | 6868 // #loop-body |
6757 // {{completion = BODY_COMPLETED;}} | 6869 // {{completion = NORMAL;}} |
6758 // } | 6870 // } |
6759 // | 6871 // |
6760 // and assign_each is wrapped as follows | 6872 // and the loop's assign_each is wrapped as follows |
6761 // | 6873 // |
6762 // do { | 6874 // do { |
6763 // {{completion = BODY_ABORTED;}} | 6875 // {{completion = ABRUPT;}} |
6764 // #assign-each | 6876 // #assign-each |
6765 // } into each | 6877 // } |
6878 // | |
6766 | 6879 |
6767 const int nopos = RelocInfo::kNoPosition; | 6880 const int nopos = RelocInfo::kNoPosition; |
6768 auto factory = parser_->factory(); | 6881 auto factory = parser_->factory(); |
6769 auto avfactory = parser_->ast_value_factory(); | 6882 auto avfactory = parser_->ast_value_factory(); |
6770 auto scope = parser_->scope_; | 6883 auto scope = parser_->scope_; |
6771 auto zone = parser_->zone(); | 6884 auto zone = parser_->zone(); |
6772 | 6885 |
6773 // let completion = BODY_COMPLETED; | |
6774 Variable* var_completion = scope->NewTemporary(avfactory->empty_string()); | 6886 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 | 6887 |
6785 // let each; | 6888 // let each; |
6786 Variable* var_each = scope->NewTemporary(avfactory->empty_string()); | 6889 Variable* var_each = scope->NewTemporary(avfactory->empty_string()); |
6787 Statement* initialize_each; | 6890 Statement* initialize_each; |
6788 { | 6891 { |
6789 Expression* proxy = factory->NewVariableProxy(var_each); | 6892 Expression* proxy = factory->NewVariableProxy(var_each); |
6790 Expression* assignment = factory->NewAssignment( | 6893 Expression* assignment = factory->NewAssignment( |
6791 Token::ASSIGN, proxy, | 6894 Token::ASSIGN, proxy, |
6792 factory->NewUndefinedLiteral(nopos), nopos); | 6895 factory->NewUndefinedLiteral(nopos), nopos); |
6793 initialize_each = | 6896 initialize_each = |
6794 factory->NewExpressionStatement(assignment, nopos); | 6897 factory->NewExpressionStatement(assignment, nopos); |
6795 } | 6898 } |
6796 | 6899 |
6797 // if (completion === BODY_ABORTED) completion = BODY_THREW; | 6900 // !(completion === NORMAL || IS_UNDEFINED(#iterator)) |
6798 Statement* set_completion_throw; | 6901 Expression* condition; |
adamk
2016/03/07 20:28:05
Can you give this a better name? Maybe "iterator_c
neis
2016/03/08 13:40:10
Done.
| |
6799 { | 6902 { |
6800 Expression* condition = factory->NewCompareOperation( | 6903 Expression* lhs = factory->NewCompareOperation( |
6801 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), | 6904 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), |
6802 factory->NewSmiLiteral(BODY_ABORTED, nopos), nopos); | 6905 factory->NewSmiLiteral(Parser::NORMAL, nopos), nopos); |
6803 | 6906 Expression* rhs = factory->NewCompareOperation( |
6804 Expression* proxy = factory->NewVariableProxy(var_completion); | 6907 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()), |
6805 Expression* assignment = factory->NewAssignment( | 6908 factory->NewUndefinedLiteral(nopos), nopos); |
6806 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_THREW, nopos), | 6909 condition = factory->NewUnaryOperation( |
6910 Token::NOT, | |
6911 factory->NewBinaryOperation(Token::OR, lhs, rhs, nopos), | |
6807 nopos); | 6912 nopos); |
6808 Statement* statement = factory->NewExpressionStatement(assignment, nopos); | |
6809 set_completion_throw = factory->NewIfStatement( | |
6810 condition, statement, factory->NewEmptyStatement(nopos), nopos); | |
6811 } | 6913 } |
6812 | 6914 |
6813 // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) { | 6915 // {{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; | 6916 Statement* set_completion_normal; |
6891 { | 6917 { |
6892 Expression* proxy = factory->NewVariableProxy(var_completion); | 6918 Expression* proxy = factory->NewVariableProxy(var_completion); |
6893 Expression* assignment = factory->NewAssignment( | 6919 Expression* assignment = factory->NewAssignment( |
6894 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_COMPLETED, nopos), | 6920 Token::ASSIGN, proxy, factory->NewSmiLiteral(Parser::NORMAL, nopos), |
6895 nopos); | 6921 nopos); |
6896 | 6922 |
6897 Block* block = factory->NewBlock(nullptr, 1, true, nopos); | 6923 Block* block = factory->NewBlock(nullptr, 1, true, nopos); |
6898 block->statements()->Add( | 6924 block->statements()->Add( |
6899 factory->NewExpressionStatement(assignment, nopos), zone); | 6925 factory->NewExpressionStatement(assignment, nopos), zone); |
6900 set_completion_normal = block; | 6926 set_completion_normal = block; |
6901 } | 6927 } |
6902 | 6928 |
6903 // { #loop-body; #set_completion_normal } | 6929 // {{completion = ABRUPT;}} |
6904 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); | 6930 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 { | 6931 { |
6913 Expression* proxy = factory->NewVariableProxy(var_completion); | 6932 Expression* proxy = factory->NewVariableProxy(var_completion); |
6914 Expression* assignment = factory->NewAssignment( | 6933 Expression* assignment = factory->NewAssignment( |
6915 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_ABORTED, nopos), | 6934 Token::ASSIGN, proxy, factory->NewSmiLiteral(Parser::ABRUPT, nopos), |
6916 nopos); | 6935 nopos); |
6917 | 6936 |
6918 Block* block = factory->NewBlock(nullptr, 1, true, nopos); | 6937 Block* block = factory->NewBlock(nullptr, 1, true, nopos); |
6919 block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), | 6938 block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), |
6920 zone); | 6939 zone); |
6921 set_completion_break = block; | 6940 set_completion_abrupt = block; |
6922 } | 6941 } |
6923 | 6942 |
6924 // { #set_completion_break; #assign-each } | 6943 // { #loop-body; #set_completion_normal } |
6944 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); | |
6945 { | |
6946 new_body->statements()->Add(loop->body(), zone); | |
6947 new_body->statements()->Add(set_completion_normal, zone); | |
6948 } | |
6949 | |
6950 // { #set_completion_abrupt; #assign-each } | |
6925 Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); | 6951 Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); |
6926 new_assign_each->statements()->Add(set_completion_break, zone); | 6952 { |
6927 new_assign_each->statements()->Add( | 6953 new_assign_each->statements()->Add(set_completion_abrupt, zone); |
6928 factory->NewExpressionStatement(loop->assign_each(), nopos), zone); | 6954 new_assign_each->statements()->Add( |
6955 factory->NewExpressionStatement(loop->assign_each(), nopos), zone); | |
6956 } | |
6929 | 6957 |
6930 Expression* do_each = | 6958 // Now put things together. |
6931 factory->NewDoExpression(new_assign_each, var_each, nopos); | 6959 |
6932 loop->set_assign_each(do_each); | 6960 loop->set_body(new_body); |
6961 loop->set_assign_each( | |
6962 factory->NewDoExpression(new_assign_each, var_each, nopos)); | |
6963 | |
6964 Statement* final_loop; | |
6965 { | |
6966 Block* target = factory->NewBlock(nullptr, 3, false, nopos); | |
6967 target->statements()->Add(initialize_each, zone); | |
6968 | |
6969 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | |
6970 try_block->statements()->Add(loop, zone); | |
6971 | |
6972 FinalizeIteratorUse( | |
6973 var_completion, condition, loop->iterator(), try_block, target); | |
6974 final_loop = target; | |
6975 } | |
6933 | 6976 |
6934 return final_loop; | 6977 return final_loop; |
6935 } | 6978 } |
6936 | 6979 |
6937 | 6980 |
6938 } // namespace internal | 6981 } // namespace internal |
6939 } // namespace v8 | 6982 } // namespace v8 |
OLD | NEW |