Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(483)

Side by Side Diff: src/parsing/parser.cc

Issue 1772793002: Implement iterator finalization in array destructuring. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698