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

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

Issue 1695393003: [es6] Implement for-of iterator finalization (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Epsilon Created 4 years, 10 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
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/rewriter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3318 matching lines...) Expand 10 before | Expand all | Expand 10 after
3329 result_proxy, value_literal, RelocInfo::kNoPosition); 3329 result_proxy, value_literal, RelocInfo::kNoPosition);
3330 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, 3330 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3331 RelocInfo::kNoPosition); 3331 RelocInfo::kNoPosition);
3332 if (is_destructuring) { 3332 if (is_destructuring) {
3333 assign_each = PatternRewriter::RewriteDestructuringAssignment( 3333 assign_each = PatternRewriter::RewriteDestructuringAssignment(
3334 this, assign_each->AsAssignment(), scope_); 3334 this, assign_each->AsAssignment(), scope_);
3335 } 3335 }
3336 } 3336 }
3337 3337
3338 for_of->Initialize(each, subject, body, 3338 for_of->Initialize(each, subject, body,
3339 iterator,
3339 assign_iterator, 3340 assign_iterator,
3340 next_result, 3341 next_result,
3341 result_done, 3342 result_done,
3342 assign_each); 3343 assign_each);
3343 } else { 3344 } else {
3344 if (is_destructuring) { 3345 if (is_destructuring) {
3345 Variable* temp = 3346 Variable* temp =
3346 scope_->NewTemporary(ast_value_factory()->empty_string()); 3347 scope_->NewTemporary(ast_value_factory()->empty_string());
3347 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 3348 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3348 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( 3349 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
3606 inner_block->set_scope(inner_scope); 3607 inner_block->set_scope(inner_scope);
3607 } 3608 }
3608 3609
3609 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3610 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3610 return outer_block; 3611 return outer_block;
3611 } 3612 }
3612 3613
3613 3614
3614 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3615 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3615 bool* ok) { 3616 bool* ok) {
3616 // ForStatement ::
3617 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
3618
3619 int stmt_pos = peek_position(); 3617 int stmt_pos = peek_position();
3620 Statement* init = NULL; 3618 Statement* init = NULL;
3621 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3619 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3622 3620
3623 // Create an in-between scope for let-bound iteration variables. 3621 // Create an in-between scope for let-bound iteration variables.
3624 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3622 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3625 3623
3626 BlockState block_state(&scope_, for_scope); 3624 BlockState block_state(&scope_, for_scope);
3627 Expect(Token::FOR, CHECK_OK); 3625 Expect(Token::FOR, CHECK_OK);
3628 Expect(Token::LPAREN, CHECK_OK); 3626 Expect(Token::LPAREN, CHECK_OK);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
3745 3743
3746 body_block->statements()->Add(each_initialization_block, zone()); 3744 body_block->statements()->Add(each_initialization_block, zone());
3747 body_block->statements()->Add(body, zone()); 3745 body_block->statements()->Add(body, zone());
3748 VariableProxy* temp_proxy = 3746 VariableProxy* temp_proxy =
3749 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3747 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3750 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, 3748 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3751 false); 3749 false);
3752 } 3750 }
3753 body_scope->set_end_position(scanner()->location().end_pos); 3751 body_scope->set_end_position(scanner()->location().end_pos);
3754 body_scope = body_scope->FinalizeBlockScope(); 3752 body_scope = body_scope->FinalizeBlockScope();
3755 body_block->set_scope(body_scope); 3753 body_block->set_scope(body_scope);
3756 3754
3757 // Create a TDZ for any lexically-bound names. 3755 // Create a TDZ for any lexically-bound names.
3758 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { 3756 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3759 DCHECK_NULL(init_block); 3757 DCHECK_NULL(init_block);
3760 3758
3761 init_block = 3759 init_block =
3762 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); 3760 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition);
3763 3761
3764 for (int i = 0; i < lexical_bindings.length(); ++i) { 3762 for (int i = 0; i < lexical_bindings.length(); ++i) {
3765 // TODO(adamk): This needs to be some sort of special 3763 // TODO(adamk): This needs to be some sort of special
3766 // INTERNAL variable that's invisible to the debugger 3764 // INTERNAL variable that's invisible to the debugger
3767 // but visible to everything else. 3765 // but visible to everything else.
3768 VariableProxy* tdz_proxy = 3766 VariableProxy* tdz_proxy =
3769 NewUnresolved(lexical_bindings[i], LET); 3767 NewUnresolved(lexical_bindings[i], LET);
3770 Declaration* tdz_decl = factory()->NewVariableDeclaration( 3768 Declaration* tdz_decl = factory()->NewVariableDeclaration(
3771 tdz_proxy, LET, scope_, RelocInfo::kNoPosition); 3769 tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
3772 Variable* tdz_var = Declare( 3770 Variable* tdz_var = Declare(
3773 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); 3771 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK);
3774 tdz_var->set_initializer_position(position()); 3772 tdz_var->set_initializer_position(position());
3775 }
3776 } 3773 }
3774 }
3775
3776 Statement* final_loop = loop->IsForOfStatement()
3777 ? FinalizeForOfStatement(
3778 loop->AsForOfStatement(), RelocInfo::kNoPosition)
3779 : loop;
3777 3780
3778 for_scope->set_end_position(scanner()->location().end_pos); 3781 for_scope->set_end_position(scanner()->location().end_pos);
3779 for_scope = for_scope->FinalizeBlockScope(); 3782 for_scope = for_scope->FinalizeBlockScope();
3780 // Parsed for-in loop w/ variable declarations. 3783 // Parsed for-in loop w/ variable declarations.
3781 if (init_block != nullptr) { 3784 if (init_block != nullptr) {
3782 init_block->statements()->Add(loop, zone()); 3785 init_block->statements()->Add(final_loop, zone());
3783 init_block->set_scope(for_scope); 3786 init_block->set_scope(for_scope);
3784 return init_block; 3787 return init_block;
3785 } else { 3788 } else {
3786 DCHECK_NULL(for_scope); 3789 DCHECK_NULL(for_scope);
3787 return loop; 3790 return final_loop;
3788 } 3791 }
3789 } else { 3792 } else {
3790 init = parsing_result.BuildInitializationBlock( 3793 init = parsing_result.BuildInitializationBlock(
3791 IsLexicalVariableMode(parsing_result.descriptor.mode) 3794 IsLexicalVariableMode(parsing_result.descriptor.mode)
3792 ? &lexical_bindings 3795 ? &lexical_bindings
3793 : nullptr, 3796 : nullptr,
3794 CHECK_OK); 3797 CHECK_OK);
3795 } 3798 }
3796 } else { 3799 } else {
3797 int lhs_beg_pos = peek_position(); 3800 int lhs_beg_pos = peek_position();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3840 3843
3841 Expect(Token::RPAREN, CHECK_OK); 3844 Expect(Token::RPAREN, CHECK_OK);
3842 3845
3843 // Make a block around the statement in case a lexical binding 3846 // Make a block around the statement in case a lexical binding
3844 // is introduced, e.g. by a FunctionDeclaration. 3847 // is introduced, e.g. by a FunctionDeclaration.
3845 // This block must not use for_scope as its scope because if a 3848 // This block must not use for_scope as its scope because if a
3846 // lexical binding is introduced which overlaps with the for-in/of, 3849 // lexical binding is introduced which overlaps with the for-in/of,
3847 // expressions in head of the loop should actually have variables 3850 // expressions in head of the loop should actually have variables
3848 // resolved in the outer scope. 3851 // resolved in the outer scope.
3849 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); 3852 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE);
3850 BlockState block_state(&scope_, body_scope); 3853 {
3851 Block* block = 3854 BlockState block_state(&scope_, body_scope);
3852 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3855 Block* block =
3853 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3856 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3854 block->statements()->Add(body, zone()); 3857 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3855 InitializeForEachStatement(loop, expression, enumerable, block, 3858 block->statements()->Add(body, zone());
3856 is_destructuring); 3859 InitializeForEachStatement(loop, expression, enumerable, block,
3857 body_scope->set_end_position(scanner()->location().end_pos); 3860 is_destructuring);
3858 body_scope = body_scope->FinalizeBlockScope(); 3861 body_scope->set_end_position(scanner()->location().end_pos);
3859 block->set_scope(body_scope); 3862 body_scope = body_scope->FinalizeBlockScope();
3863 block->set_scope(body_scope);
3864 }
3865
3866 Statement* final_loop = loop->IsForOfStatement()
3867 ? FinalizeForOfStatement(
3868 loop->AsForOfStatement(), RelocInfo::kNoPosition)
3869 : loop;
3870
3860 for_scope->set_end_position(scanner()->location().end_pos); 3871 for_scope->set_end_position(scanner()->location().end_pos);
3861 for_scope = for_scope->FinalizeBlockScope(); 3872 for_scope = for_scope->FinalizeBlockScope();
3862 DCHECK(for_scope == nullptr); 3873 DCHECK(for_scope == nullptr);
3863 // Parsed for-in loop. 3874 return final_loop;
3864 return loop;
3865 3875
3866 } else { 3876 } else {
3867 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); 3877 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3868 } 3878 }
3869 } 3879 }
3870 } 3880 }
3871 3881
3872 // Standard 'for' loop 3882 // Standard 'for' loop
3873 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); 3883 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3874 Target target(&this->target_stack_, loop); 3884 Target target(&this->target_stack_, loop);
(...skipping 1859 matching lines...) Expand 10 before | Expand all | Expand 10 after
5734 factory()->NewCallRuntime(Runtime::kAppendElement, 5744 factory()->NewCallRuntime(Runtime::kAppendElement,
5735 append_element_args, 5745 append_element_args,
5736 RelocInfo::kNoPosition), 5746 RelocInfo::kNoPosition),
5737 RelocInfo::kNoPosition); 5747 RelocInfo::kNoPosition);
5738 } 5748 }
5739 // for (each of spread) %AppendElement($R, each) 5749 // for (each of spread) %AppendElement($R, each)
5740 ForEachStatement* loop = factory()->NewForEachStatement( 5750 ForEachStatement* loop = factory()->NewForEachStatement(
5741 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition); 5751 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition);
5742 ForOfStatement* for_of = loop->AsForOfStatement(); 5752 ForOfStatement* for_of = loop->AsForOfStatement();
5743 for_of->Initialize(factory()->NewVariableProxy(each), subject, 5753 for_of->Initialize(factory()->NewVariableProxy(each), subject,
5744 append_body, assign_iterator, next_element, 5754 append_body, iterator, assign_iterator, next_element,
5745 element_done, assign_each); 5755 element_done, assign_each);
5746 do_block->statements()->Add(for_of, zone()); 5756 do_block->statements()->Add(for_of, zone());
5747 } 5757 }
5748 } 5758 }
5749 // Now, rewind the original array literal to truncate everything from the 5759 // Now, rewind the original array literal to truncate everything from the
5750 // first spread (included) until the end. This fixes $R's initialization. 5760 // first spread (included) until the end. This fixes $R's initialization.
5751 lit->RewindSpreads(); 5761 lit->RewindSpreads();
5752 return factory()->NewDoExpression(do_block, result, lit->position()); 5762 return factory()->NewDoExpression(do_block, result, lit->position());
5753 } 5763 }
5754 5764
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
5892 Expression* ParserTraits::RewriteYieldStar( 5902 Expression* ParserTraits::RewriteYieldStar(
5893 Expression* generator, Expression* iterable, int pos) { 5903 Expression* generator, Expression* iterable, int pos) {
5894 5904
5895 const int nopos = RelocInfo::kNoPosition; 5905 const int nopos = RelocInfo::kNoPosition;
5896 5906
5897 auto factory = parser_->factory(); 5907 auto factory = parser_->factory();
5898 auto avfactory = parser_->ast_value_factory(); 5908 auto avfactory = parser_->ast_value_factory();
5899 auto scope = parser_->scope_; 5909 auto scope = parser_->scope_;
5900 auto zone = parser_->zone(); 5910 auto zone = parser_->zone();
5901 5911
5902 Statement* skip = factory->NewEmptyStatement(nopos);
5903 5912
5904 // Forward definition for break/continue statements. 5913 // Forward definition for break/continue statements.
5905 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos); 5914 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos);
5906 5915
5907 5916
5908 // let input = undefined; 5917 // let input = undefined;
5909 Variable* var_input = scope->NewTemporary(avfactory->empty_string()); 5918 Variable* var_input = scope->NewTemporary(avfactory->empty_string());
5910 Statement* initialize_input; 5919 Statement* initialize_input;
5911 { 5920 {
5912 Expression* input_proxy = factory->NewVariableProxy(var_input); 5921 Expression* input_proxy = factory->NewVariableProxy(var_input);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
5964 } 5973 }
5965 5974
5966 Statement* throw_call; 5975 Statement* throw_call;
5967 { 5976 {
5968 Expression* call = NewThrowTypeError( 5977 Expression* call = NewThrowTypeError(
5969 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(), 5978 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(),
5970 nopos); 5979 nopos);
5971 throw_call = factory->NewExpressionStatement(call, nopos); 5980 throw_call = factory->NewExpressionStatement(call, nopos);
5972 } 5981 }
5973 5982
5974 validate_iterator = 5983 validate_iterator = factory->NewIfStatement(
5975 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 5984 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
5976 } 5985 }
5977 5986
5978 5987
5979 // output = iterator.next(input); 5988 // output = iterator.next(input);
5980 Statement* call_next; 5989 Statement* call_next;
5981 { 5990 {
5982 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); 5991 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
5983 Expression* literal = 5992 Expression* literal =
5984 factory->NewStringLiteral(avfactory->next_string(), nopos); 5993 factory->NewStringLiteral(avfactory->next_string(), nopos);
5985 Expression* next_property = 5994 Expression* next_property =
(...skipping 22 matching lines...) Expand all
6008 6017
6009 Statement* throw_call; 6018 Statement* throw_call;
6010 { 6019 {
6011 auto args = new (zone) ZoneList<Expression*>(1, zone); 6020 auto args = new (zone) ZoneList<Expression*>(1, zone);
6012 args->Add(factory->NewVariableProxy(var_output), zone); 6021 args->Add(factory->NewVariableProxy(var_output), zone);
6013 Expression* call = factory->NewCallRuntime( 6022 Expression* call = factory->NewCallRuntime(
6014 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6023 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6015 throw_call = factory->NewExpressionStatement(call, nopos); 6024 throw_call = factory->NewExpressionStatement(call, nopos);
6016 } 6025 }
6017 6026
6018 validate_next_output = 6027 validate_next_output = factory->NewIfStatement(
6019 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 6028 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6020 } 6029 }
6021 6030
6022 6031
6023 // let iteratorThrow = iterator.throw; 6032 // let iteratorThrow = iterator.throw;
6024 Variable* var_throw = scope->NewTemporary(avfactory->empty_string()); 6033 Variable* var_throw = scope->NewTemporary(avfactory->empty_string());
6025 Statement* get_throw; 6034 Statement* get_throw;
6026 { 6035 {
6027 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); 6036 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6028 Expression* literal = 6037 Expression* literal =
6029 factory->NewStringLiteral(avfactory->throw_string(), nopos); 6038 factory->NewStringLiteral(avfactory->throw_string(), nopos);
(...skipping 15 matching lines...) Expand all
6045 Expression* condition = factory->NewCompareOperation( 6054 Expression* condition = factory->NewCompareOperation(
6046 Token::EQ, factory->NewVariableProxy(var_throw), 6055 Token::EQ, factory->NewVariableProxy(var_throw),
6047 factory->NewNullLiteral(nopos), nopos); 6056 factory->NewNullLiteral(nopos), nopos);
6048 6057
6049 Expression* call = NewThrowTypeError( 6058 Expression* call = NewThrowTypeError(
6050 MessageTemplate::kThrowMethodMissing, 6059 MessageTemplate::kThrowMethodMissing,
6051 avfactory->empty_string(), nopos); 6060 avfactory->empty_string(), nopos);
6052 Statement* throw_call = factory->NewExpressionStatement(call, nopos); 6061 Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6053 6062
6054 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); 6063 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos);
6055 BuildIteratorClose(then->statements(), var_iterator, Nothing<Variable*>(), 6064 Variable* var_tmp = scope->NewTemporary(avfactory->empty_string());
6056 Nothing<Variable*>()); 6065 BuildIteratorClose(
6066 then->statements(), var_iterator, factory->NewUndefinedLiteral(nopos),
6067 var_tmp);
6057 then->statements()->Add(throw_call, zone); 6068 then->statements()->Add(throw_call, zone);
6058 check_throw = 6069 check_throw = factory->NewIfStatement(
6059 factory->NewIfStatement(condition, then, skip, nopos); 6070 condition, then, factory->NewEmptyStatement(nopos), nopos);
6060 } 6071 }
6061 6072
6062 6073
6063 // output = %_Call(iteratorThrow, iterator, input); 6074 // output = %_Call(iteratorThrow, iterator, input);
6064 Statement* call_throw; 6075 Statement* call_throw;
6065 { 6076 {
6066 auto args = new (zone) ZoneList<Expression*>(3, zone); 6077 auto args = new (zone) ZoneList<Expression*>(3, zone);
6067 args->Add(factory->NewVariableProxy(var_throw), zone); 6078 args->Add(factory->NewVariableProxy(var_throw), zone);
6068 args->Add(factory->NewVariableProxy(var_iterator), zone); 6079 args->Add(factory->NewVariableProxy(var_iterator), zone);
6069 args->Add(factory->NewVariableProxy(var_input), zone); 6080 args->Add(factory->NewVariableProxy(var_input), zone);
(...skipping 18 matching lines...) Expand all
6088 6099
6089 Statement* throw_call; 6100 Statement* throw_call;
6090 { 6101 {
6091 auto args = new (zone) ZoneList<Expression*>(1, zone); 6102 auto args = new (zone) ZoneList<Expression*>(1, zone);
6092 args->Add(factory->NewVariableProxy(var_output), zone); 6103 args->Add(factory->NewVariableProxy(var_output), zone);
6093 Expression* call = factory->NewCallRuntime( 6104 Expression* call = factory->NewCallRuntime(
6094 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6105 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6095 throw_call = factory->NewExpressionStatement(call, nopos); 6106 throw_call = factory->NewExpressionStatement(call, nopos);
6096 } 6107 }
6097 6108
6098 validate_throw_output = 6109 validate_throw_output = factory->NewIfStatement(
6099 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 6110 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6100 } 6111 }
6101 6112
6102 6113
6103 // if (output.done) break; 6114 // if (output.done) break;
6104 Statement* if_done; 6115 Statement* if_done;
6105 { 6116 {
6106 Expression* output_proxy = factory->NewVariableProxy(var_output); 6117 Expression* output_proxy = factory->NewVariableProxy(var_output);
6107 Expression* literal = 6118 Expression* literal =
6108 factory->NewStringLiteral(avfactory->done_string(), nopos); 6119 factory->NewStringLiteral(avfactory->done_string(), nopos);
6109 Expression* property = factory->NewProperty(output_proxy, literal, nopos); 6120 Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6110 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos); 6121 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos);
6111 if_done = factory->NewIfStatement(property, break_loop, skip, nopos); 6122 if_done = factory->NewIfStatement(
6123 property, break_loop, factory->NewEmptyStatement(nopos), nopos);
6112 } 6124 }
6113 6125
6114 6126
6115 // mode = kReturn; 6127 // mode = kReturn;
6116 Statement* set_mode_return; 6128 Statement* set_mode_return;
6117 { 6129 {
6118 Expression* mode_proxy = factory->NewVariableProxy(var_mode); 6130 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6119 Expression* kreturn = 6131 Expression* kreturn =
6120 factory->NewSmiLiteral(JSGeneratorObject::RETURN, nopos); 6132 factory->NewSmiLiteral(JSGeneratorObject::RETURN, nopos);
6121 Expression* assignment = 6133 Expression* assignment =
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
6220 6232
6221 // switch (mode) { ... } 6233 // switch (mode) { ... }
6222 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); 6234 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos);
6223 { 6235 {
6224 auto case_next = new (zone) ZoneList<Statement*>(3, zone); 6236 auto case_next = new (zone) ZoneList<Statement*>(3, zone);
6225 case_next->Add(call_next, zone); 6237 case_next->Add(call_next, zone);
6226 case_next->Add(validate_next_output, zone); 6238 case_next->Add(validate_next_output, zone);
6227 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6239 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6228 6240
6229 auto case_return = new (zone) ZoneList<Statement*>(5, zone); 6241 auto case_return = new (zone) ZoneList<Statement*>(5, zone);
6230 BuildIteratorClose( 6242 BuildIteratorClose(case_return, var_iterator,
6231 case_return, var_iterator, Just(var_input), Just(var_output)); 6243 factory->NewVariableProxy(var_input, nopos), var_output);
6232 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6244 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6233 6245
6234 auto case_throw = new (zone) ZoneList<Statement*>(5, zone); 6246 auto case_throw = new (zone) ZoneList<Statement*>(5, zone);
6235 case_throw->Add(get_throw, zone); 6247 case_throw->Add(get_throw, zone);
6236 case_throw->Add(check_throw, zone); 6248 case_throw->Add(check_throw, zone);
6237 case_throw->Add(call_throw, zone); 6249 case_throw->Add(call_throw, zone);
6238 case_throw->Add(validate_throw_output, zone); 6250 case_throw->Add(validate_throw_output, zone);
6239 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6251 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6240 6252
6241 auto cases = new (zone) ZoneList<CaseClause*>(3, zone); 6253 auto cases = new (zone) ZoneList<CaseClause*>(3, zone);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
6287 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); 6299 yield_star = factory->NewDoExpression(do_block, dot_result, nopos);
6288 Rewriter::Rewrite(parser_, yield_star, avfactory); 6300 Rewriter::Rewrite(parser_, yield_star, avfactory);
6289 } 6301 }
6290 6302
6291 return yield_star; 6303 return yield_star;
6292 } 6304 }
6293 6305
6294 6306
6295 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, 6307 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements,
6296 Variable* iterator, 6308 Variable* iterator,
6297 Maybe<Variable*> input, 6309 Expression* input,
6298 Maybe<Variable*> output) { 6310 Variable* var_output) {
6311 //
6312 // This function adds four statements to [statements], corresponding to the
6313 // following code:
6314 //
6315 // let iteratorReturn = iterator.return;
6316 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input;
6317 // output = %_Call(iteratorReturn, iterator);
6318 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6319 //
6320
6299 const int nopos = RelocInfo::kNoPosition; 6321 const int nopos = RelocInfo::kNoPosition;
6300 auto factory = parser_->factory(); 6322 auto factory = parser_->factory();
6301 auto avfactory = parser_->ast_value_factory(); 6323 auto avfactory = parser_->ast_value_factory();
6302 auto scope = parser_->scope_;
6303 auto zone = parser_->zone(); 6324 auto zone = parser_->zone();
6304 Statement* skip = factory->NewEmptyStatement(nopos); 6325
6305 6326
6306 // let iteratorReturn = iterator.return; 6327 // let iteratorReturn = iterator.return;
6307 Variable* var = scope->NewTemporary(avfactory->empty_string()); 6328 Variable* var_return = var_output; // Reusing the output variable.
6308 Statement* get_return; 6329 Statement* get_return;
6309 { 6330 {
6310 Expression* iterator_proxy = factory->NewVariableProxy(iterator); 6331 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6311 Expression* literal = 6332 Expression* literal =
6312 factory->NewStringLiteral(avfactory->return_string(), nopos); 6333 factory->NewStringLiteral(avfactory->return_string(), nopos);
6313 Expression* property = 6334 Expression* property =
6314 factory->NewProperty(iterator_proxy, literal, nopos); 6335 factory->NewProperty(iterator_proxy, literal, nopos);
6315 Expression* return_proxy = factory->NewVariableProxy(var); 6336 Expression* return_proxy = factory->NewVariableProxy(var_return);
6316 Expression* assignment = factory->NewAssignment( 6337 Expression* assignment = factory->NewAssignment(
6317 Token::ASSIGN, return_proxy, property, nopos); 6338 Token::ASSIGN, return_proxy, property, nopos);
6318 get_return = factory->NewExpressionStatement(assignment, nopos); 6339 get_return = factory->NewExpressionStatement(assignment, nopos);
6319 } 6340 }
6320 6341
6321 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return; OR 6342
Dan Ehrenberg 2016/02/17 15:42:00 Nit: no need for a blank line.
rossberg 2016/02/17 16:04:07 Removed various double empty lines, here and in ot
6322 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input; 6343 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input;
6323 Statement* check_return; 6344 Statement* check_return;
6324 { 6345 {
6325 Expression* condition = factory->NewCompareOperation( 6346 Expression* condition = factory->NewCompareOperation(
6326 Token::EQ, factory->NewVariableProxy(var), 6347 Token::EQ, factory->NewVariableProxy(var_return),
6327 factory->NewNullLiteral(nopos), nopos); 6348 factory->NewNullLiteral(nopos), nopos);
6328 6349
6329 Expression* value = input.IsJust() ? 6350 Statement* return_input = factory->NewReturnStatement(input, nopos);
6330 static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) :
6331 factory->NewUndefinedLiteral(nopos);
6332 6351
6333 Statement* return_undefined = factory->NewReturnStatement(value, nopos); 6352 check_return = factory->NewIfStatement(
6334 6353 condition, return_input, factory->NewEmptyStatement(nopos), nopos);
6335 check_return =
6336 factory->NewIfStatement(condition, return_undefined, skip, nopos);
6337 } 6354 }
6338 6355
6339 // let output = %_Call(iteratorReturn, iterator); OR 6356
Dan Ehrenberg 2016/02/17 15:42:00 Here too
6340 // output = %_Call(iteratorReturn, iterator, input); 6357 // output = %_Call(iteratorReturn, iterator);
6341 Statement* call_return; 6358 Statement* call_return;
6342 { 6359 {
6343 auto args = new (zone) ZoneList<Expression*>(3, zone); 6360 auto args = new (zone) ZoneList<Expression*>(3, zone);
6344 args->Add(factory->NewVariableProxy(var), zone); 6361 args->Add(factory->NewVariableProxy(var_return), zone);
6345 args->Add(factory->NewVariableProxy(iterator), zone); 6362 args->Add(factory->NewVariableProxy(iterator), zone);
6346 if (input.IsJust()) {
6347 args->Add(factory->NewVariableProxy(input.FromJust()), zone);
6348 }
6349 6363
6350 Expression* call = 6364 Expression* call =
6351 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); 6365 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6352 Expression* output_proxy = factory->NewVariableProxy( 6366 Expression* output_proxy = factory->NewVariableProxy(var_output);
6353 output.IsJust() ? output.FromJust() : var);
6354 Expression* assignment = factory->NewAssignment( 6367 Expression* assignment = factory->NewAssignment(
6355 Token::ASSIGN, output_proxy, call, nopos); 6368 Token::ASSIGN, output_proxy, call, nopos);
6356 call_return = factory->NewExpressionStatement(assignment, nopos); 6369 call_return = factory->NewExpressionStatement(assignment, nopos);
6357 } 6370 }
6358 6371
6359 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 6372
6373 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
6360 Statement* validate_output; 6374 Statement* validate_output;
6361 { 6375 {
6362 Expression* is_receiver_call; 6376 Expression* is_receiver_call;
6363 { 6377 {
6364 auto args = new (zone) ZoneList<Expression*>(1, zone); 6378 auto args = new (zone) ZoneList<Expression*>(1, zone);
6365 args->Add(factory->NewVariableProxy(var), zone); 6379 args->Add(factory->NewVariableProxy(var_output), zone);
6366 is_receiver_call = 6380 is_receiver_call =
6367 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 6381 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6368 } 6382 }
6369 6383
6370 Statement* throw_call; 6384 Statement* throw_call;
6371 { 6385 {
6372 auto args = new (zone) ZoneList<Expression*>(1, zone); 6386 auto args = new (zone) ZoneList<Expression*>(1, zone);
6373 args->Add(factory->NewVariableProxy(var), zone); 6387 args->Add(factory->NewVariableProxy(var_output), zone);
6374 Expression* call = factory->NewCallRuntime( 6388 Expression* call = factory->NewCallRuntime(
6375 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6389 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6376 throw_call = factory->NewExpressionStatement(call, nopos); 6390 throw_call = factory->NewExpressionStatement(call, nopos);
6377 } 6391 }
6378 6392
6379 validate_output = 6393 validate_output = factory->NewIfStatement(
6380 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 6394 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6381 } 6395 }
6382 6396
6397
6383 statements->Add(get_return, zone); 6398 statements->Add(get_return, zone);
6384 statements->Add(check_return, zone); 6399 statements->Add(check_return, zone);
6385 statements->Add(call_return, zone); 6400 statements->Add(call_return, zone);
6386 statements->Add(validate_output, zone); 6401 statements->Add(validate_output, zone);
6387 } 6402 }
6388 6403
6389 6404
6405 // Runtime encoding of different completion modes.
6406 enum ForOfLoopBodyCompletion { BODY_COMPLETED, BODY_ABORTED, BODY_THREW };
6407
6408 void ParserTraits::BuildIteratorCloseForCompletion(
6409 ZoneList<Statement*>* statements, Variable* iterator,
6410 Variable* completion) {
6411 //
6412 // This function adds two statements to [statements], corresponding to the
6413 // following code:
6414 //
6415 // let iteratorReturn = iterator.return;
6416 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
6417 // let output;
6418 // if (completion === BODY_THREW) {
6419 // if (!IS_CALLABLE(iteratorReturn)) {
6420 // throw MakeTypeError(kReturnMethodNotCallable);
6421 // }
6422 // try { output = %_Call(iteratorReturn, iterator) } catch (_) { }
6423 // } else {
6424 // output = %_Call(iteratorReturn, iterator);
6425 // }
6426 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6427 // }
6428 //
6429
6430 const int nopos = RelocInfo::kNoPosition;
6431 auto factory = parser_->factory();
6432 auto avfactory = parser_->ast_value_factory();
6433 auto scope = parser_->scope_;
6434 auto zone = parser_->zone();
6435
6436
6437 // let output;
6438 Variable* var_output = scope->NewTemporary(avfactory->empty_string());
6439
6440
6441 // let iteratorReturn = iterator.return;
6442 Variable* var_return = var_output; // Reusing the output variable.
6443 Statement* get_return;
6444 {
6445 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6446 Expression* literal =
6447 factory->NewStringLiteral(avfactory->return_string(), nopos);
6448 Expression* property =
6449 factory->NewProperty(iterator_proxy, literal, nopos);
6450 Expression* return_proxy = factory->NewVariableProxy(var_return);
6451 Expression* assignment = factory->NewAssignment(
6452 Token::ASSIGN, return_proxy, property, nopos);
6453 get_return = factory->NewExpressionStatement(assignment, nopos);
6454 }
6455
6456
6457 // if (!IS_CALLABLE(iteratorReturn)) {
6458 // throw MakeTypeError(kReturnMethodNotCallable);
6459 // }
6460 Statement* check_return_callable;
6461 {
6462 Expression* type_of = factory->NewUnaryOperation(
6463 Token::TYPEOF, factory->NewVariableProxy(var_return), nopos);
6464 Expression* function_literal = factory->NewStringLiteral(
6465 avfactory->function_string(), nopos);
6466 Expression* condition = factory->NewCompareOperation(
6467 Token::EQ_STRICT, type_of, function_literal, nopos);
6468
6469 Expression* call = NewThrowTypeError(
6470 MessageTemplate::kReturnMethodNotCallable,
6471 avfactory->empty_string(), nopos);
6472 Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6473
6474 check_return_callable = factory->NewIfStatement(
6475 condition, factory->NewEmptyStatement(nopos), throw_call, nopos);
6476 }
6477
6478
6479 // output = %_Call(iteratorReturn, iterator);
6480 Statement* call_return;
6481 {
6482 auto args = new (zone) ZoneList<Expression*>(2, zone);
6483 args->Add(factory->NewVariableProxy(var_return), zone);
6484 args->Add(factory->NewVariableProxy(iterator), zone);
6485 Expression* call =
6486 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6487
6488 Expression* output_proxy = factory->NewVariableProxy(var_output);
6489 Expression* assignment = factory->NewAssignment(
6490 Token::ASSIGN, output_proxy, call, nopos);
6491 call_return = factory->NewExpressionStatement(assignment, nopos);
6492 }
6493
6494
6495 // try { output = %_Call(iteratorReturn, iterator) } catch (_) { }
6496 Statement* try_call_return;
6497 {
6498 auto args = new (zone) ZoneList<Expression*>(2, zone);
6499 args->Add(factory->NewVariableProxy(var_return), zone);
6500 args->Add(factory->NewVariableProxy(iterator), zone);
6501
6502 Expression* call =
6503 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6504 Expression* assignment = factory->NewAssignment(
6505 Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos);
6506
6507 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6508 try_block->statements()->Add(
6509 factory->NewExpressionStatement(assignment, nopos), zone);
6510
6511 Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos);
6512
6513 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6514 Variable* catch_variable = catch_scope->DeclareLocal(
6515 avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6516 Variable::NORMAL);
6517
6518 try_call_return = factory->NewTryCatchStatement(
6519 try_block, catch_scope, catch_variable, catch_block, nopos);
6520 }
6521
6522
6523 // if (completion === ABRUPT_THROW) {
6524 // #check_return_callable;
6525 // #try_call_return;
6526 // } else {
6527 // #call_return;
6528 // }
6529 Statement* call_return_carefully;
6530 {
6531 Expression* condition = factory->NewCompareOperation(
6532 Token::EQ_STRICT, factory->NewVariableProxy(completion),
6533 factory->NewSmiLiteral(BODY_THREW, nopos), nopos);
6534
6535 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos);
6536 then_block->statements()->Add(check_return_callable, zone);
6537 then_block->statements()->Add(try_call_return, zone);
6538
6539 call_return_carefully =
6540 factory->NewIfStatement(condition, then_block, call_return, nopos);
6541 }
6542
6543
6544 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
6545 Statement* validate_output;
6546 {
6547 Expression* is_receiver_call;
6548 {
6549 auto args = new (zone) ZoneList<Expression*>(1, zone);
6550 args->Add(factory->NewVariableProxy(var_output), zone);
6551 is_receiver_call =
6552 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6553 }
6554
6555 Statement* throw_call;
6556 {
6557 auto args = new (zone) ZoneList<Expression*>(1, zone);
6558 args->Add(factory->NewVariableProxy(var_output), zone);
6559 Expression* call = factory->NewCallRuntime(
6560 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6561 throw_call = factory->NewExpressionStatement(call, nopos);
6562 }
6563
6564 validate_output = factory->NewIfStatement(
6565 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6566 }
6567
6568
6569 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
6570 Statement* maybe_call_return;
6571 {
6572 Expression* condition = factory->NewCompareOperation(
6573 Token::EQ, factory->NewVariableProxy(var_return),
6574 factory->NewNullLiteral(nopos), nopos);
6575
6576 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6577 block->statements()->Add(call_return_carefully, zone);
6578 block->statements()->Add(validate_output, zone);
6579
6580 maybe_call_return = factory->NewIfStatement(
6581 condition, factory->NewEmptyStatement(nopos), block, nopos);
6582 }
6583
6584
6585 statements->Add(get_return, zone);
6586 statements->Add(maybe_call_return, zone);
6587 }
6588
6589
6590 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
6591 if (!FLAG_harmony_iterator_close) return loop;
6592
6593 //
6594 // This function replaces the loop with the following wrapping:
6595 //
6596 // let completion = BODY_COMPLETED;
6597 // try {
6598 // #loop;
6599 // } catch(e) {
6600 // if (completion === BODY_ABORTED) completion = BODY_THREW;
6601 // throw e;
6602 // } finally {
6603 // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) {
6604 // #BuildIteratorClose(#iterator, completion) // See above.
6605 // }
6606 // }
6607 //
6608 // where the loop's body is wrapped as follows:
6609 //
6610 // {
6611 // {{completion = BODY_ABORTED;}}
6612 // #loop-body
6613 // {{completion = BODY_COMPLETED;}}
6614 // }
6615
6616 const int nopos = RelocInfo::kNoPosition;
6617 auto factory = parser_->factory();
6618 auto avfactory = parser_->ast_value_factory();
6619 auto scope = parser_->scope_;
6620 auto zone = parser_->zone();
6621
6622 // let completion = BODY_COMPLETED;
6623 Variable* var_completion = scope->NewTemporary(avfactory->empty_string());
6624 Statement* initialize_completion;
6625 {
6626 Expression* proxy = factory->NewVariableProxy(var_completion);
6627 Expression* assignment = factory->NewAssignment(
6628 Token::ASSIGN, proxy,
6629 factory->NewSmiLiteral(BODY_COMPLETED, nopos), nopos);
6630 initialize_completion =
6631 factory->NewExpressionStatement(assignment, nopos);
6632 }
6633
6634 // if (completion === BODY_ABORTED) completion = BODY_THREW;
6635 Statement* set_completion_throw;
6636 {
6637 Expression* condition = factory->NewCompareOperation(
6638 Token::EQ_STRICT, factory->NewVariableProxy(var_completion),
6639 factory->NewSmiLiteral(BODY_ABORTED, nopos), nopos);
6640
6641 Expression* proxy = factory->NewVariableProxy(var_completion);
6642 Expression* assignment = factory->NewAssignment(
6643 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_THREW, nopos),
6644 nopos);
6645 Statement* statement = factory->NewExpressionStatement(assignment, nopos);
6646 set_completion_throw = factory->NewIfStatement(
6647 condition, statement, factory->NewEmptyStatement(nopos), nopos);
6648 }
6649
6650 // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) {
6651 // #BuildIteratorClose(#iterator, completion)
6652 // }
6653 Block* maybe_close;
6654 {
6655 Expression* condition1 = factory->NewCompareOperation(
6656 Token::EQ_STRICT, factory->NewVariableProxy(var_completion),
6657 factory->NewSmiLiteral(BODY_COMPLETED, nopos), nopos);
6658 Expression* condition2 = factory->NewCompareOperation(
6659 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()),
6660 factory->NewUndefinedLiteral(nopos), nopos);
6661 Expression* condition = factory->NewBinaryOperation(
6662 Token::OR, condition1, condition2, nopos);
6663
6664 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6665 BuildIteratorCloseForCompletion(
6666 block->statements(), loop->iterator(), var_completion);
6667 DCHECK(block->statements()->length() == 2);
6668
6669 maybe_close = factory->NewBlock(nullptr, 1, false, nopos);
6670 maybe_close->statements()->Add(factory->NewIfStatement(
6671 condition, factory->NewEmptyStatement(nopos), block, nopos), zone);
6672 }
6673
6674 // try { #try_block }
6675 // catch(e) {
6676 // #set_completion_throw;
6677 // throw e;
6678 // }
6679 Statement* try_catch;
6680 {
6681 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6682 Variable* catch_variable = catch_scope->DeclareLocal(
6683 avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6684 Variable::NORMAL);
6685
6686 Statement* rethrow;
6687 {
6688 Expression* proxy = factory->NewVariableProxy(catch_variable);
6689 rethrow = factory->NewExpressionStatement(
6690 factory->NewThrow(proxy, nopos), nopos);
6691 }
6692
6693 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6694 try_block->statements()->Add(loop, zone);
6695
6696 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos);
6697 catch_block->statements()->Add(set_completion_throw, zone);
6698 catch_block->statements()->Add(rethrow, zone);
6699
6700 try_catch = factory->NewTryCatchStatement(
6701 try_block, catch_scope, catch_variable, catch_block, nopos);
6702 }
6703
6704 // try { #try_catch } finally { #maybe_close }
6705 Statement* try_finally;
6706 {
6707 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6708 try_block->statements()->Add(try_catch, zone);
6709
6710 try_finally =
6711 factory->NewTryFinallyStatement(try_block, maybe_close, nopos);
6712 }
6713
6714 // #initialize_completion;
6715 // #try_finally;
6716 Statement* final_loop;
6717 {
6718 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6719 block->statements()->Add(initialize_completion, zone);
6720 block->statements()->Add(try_finally, zone);
6721 final_loop = block;
6722 }
6723
6724 // {{completion = BODY_ABORTED;}}
6725 Statement* set_completion_break;
6726 {
6727 Expression* proxy = factory->NewVariableProxy(var_completion);
6728 Expression* assignment = factory->NewAssignment(
6729 Token::ASSIGN, proxy,
6730 factory->NewSmiLiteral(BODY_ABORTED, nopos), nopos);
6731
6732 Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6733 block->statements()->Add(
6734 factory->NewExpressionStatement(assignment, nopos), zone);
6735 set_completion_break = block;
6736 }
6737
6738 // {{completion = BODY_COMPLETED;}}
6739 Statement* set_completion_normal;
6740 {
6741 Expression* proxy = factory->NewVariableProxy(var_completion);
6742 Expression* assignment = factory->NewAssignment(
6743 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_COMPLETED, nopos),
6744 nopos);
6745
6746 Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6747 block->statements()->Add(
6748 factory->NewExpressionStatement(assignment, nopos), zone);
6749 set_completion_normal = block;
6750 }
6751
6752 // { #set_completion_break; #loop-body; #set_completion_normal }
6753 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos);
6754 new_body->statements()->Add(set_completion_break, zone);
6755 new_body->statements()->Add(loop->body(), zone);
6756 new_body->statements()->Add(set_completion_normal, zone);
6757
6758 loop->set_body(new_body);
6759 return final_loop;
6760 }
6761
6762
6390 } // namespace internal 6763 } // namespace internal
6391 } // namespace v8 6764 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698