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

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: Disable iterator test for Ignition 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);
6305 6325
6306 // let iteratorReturn = iterator.return; 6326 // let iteratorReturn = iterator.return;
6307 Variable* var = scope->NewTemporary(avfactory->empty_string()); 6327 Variable* var_return = var_output; // Reusing the output variable.
6308 Statement* get_return; 6328 Statement* get_return;
6309 { 6329 {
6310 Expression* iterator_proxy = factory->NewVariableProxy(iterator); 6330 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6311 Expression* literal = 6331 Expression* literal =
6312 factory->NewStringLiteral(avfactory->return_string(), nopos); 6332 factory->NewStringLiteral(avfactory->return_string(), nopos);
6313 Expression* property = 6333 Expression* property =
6314 factory->NewProperty(iterator_proxy, literal, nopos); 6334 factory->NewProperty(iterator_proxy, literal, nopos);
6315 Expression* return_proxy = factory->NewVariableProxy(var); 6335 Expression* return_proxy = factory->NewVariableProxy(var_return);
6316 Expression* assignment = factory->NewAssignment( 6336 Expression* assignment = factory->NewAssignment(
6317 Token::ASSIGN, return_proxy, property, nopos); 6337 Token::ASSIGN, return_proxy, property, nopos);
6318 get_return = factory->NewExpressionStatement(assignment, nopos); 6338 get_return = factory->NewExpressionStatement(assignment, nopos);
6319 } 6339 }
6320 6340
6321 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return; OR
6322 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input; 6341 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input;
6323 Statement* check_return; 6342 Statement* check_return;
6324 { 6343 {
6325 Expression* condition = factory->NewCompareOperation( 6344 Expression* condition = factory->NewCompareOperation(
6326 Token::EQ, factory->NewVariableProxy(var), 6345 Token::EQ, factory->NewVariableProxy(var_return),
6327 factory->NewNullLiteral(nopos), nopos); 6346 factory->NewNullLiteral(nopos), nopos);
6328 6347
6329 Expression* value = input.IsJust() ? 6348 Statement* return_input = factory->NewReturnStatement(input, nopos);
6330 static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) :
6331 factory->NewUndefinedLiteral(nopos);
6332 6349
6333 Statement* return_undefined = factory->NewReturnStatement(value, nopos); 6350 check_return = factory->NewIfStatement(
6334 6351 condition, return_input, factory->NewEmptyStatement(nopos), nopos);
6335 check_return =
6336 factory->NewIfStatement(condition, return_undefined, skip, nopos);
6337 } 6352 }
6338 6353
6339 // let output = %_Call(iteratorReturn, iterator); OR 6354 // output = %_Call(iteratorReturn, iterator);
6340 // output = %_Call(iteratorReturn, iterator, input);
6341 Statement* call_return; 6355 Statement* call_return;
6342 { 6356 {
6343 auto args = new (zone) ZoneList<Expression*>(3, zone); 6357 auto args = new (zone) ZoneList<Expression*>(3, zone);
6344 args->Add(factory->NewVariableProxy(var), zone); 6358 args->Add(factory->NewVariableProxy(var_return), zone);
6345 args->Add(factory->NewVariableProxy(iterator), zone); 6359 args->Add(factory->NewVariableProxy(iterator), zone);
6346 if (input.IsJust()) {
6347 args->Add(factory->NewVariableProxy(input.FromJust()), zone);
6348 }
6349 6360
6350 Expression* call = 6361 Expression* call =
6351 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); 6362 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6352 Expression* output_proxy = factory->NewVariableProxy( 6363 Expression* output_proxy = factory->NewVariableProxy(var_output);
6353 output.IsJust() ? output.FromJust() : var);
6354 Expression* assignment = factory->NewAssignment( 6364 Expression* assignment = factory->NewAssignment(
6355 Token::ASSIGN, output_proxy, call, nopos); 6365 Token::ASSIGN, output_proxy, call, nopos);
6356 call_return = factory->NewExpressionStatement(assignment, nopos); 6366 call_return = factory->NewExpressionStatement(assignment, nopos);
6357 } 6367 }
6358 6368
6359 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 6369 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
6360 Statement* validate_output; 6370 Statement* validate_output;
6361 { 6371 {
6362 Expression* is_receiver_call; 6372 Expression* is_receiver_call;
6363 { 6373 {
6364 auto args = new (zone) ZoneList<Expression*>(1, zone); 6374 auto args = new (zone) ZoneList<Expression*>(1, zone);
6365 args->Add(factory->NewVariableProxy(var), zone); 6375 args->Add(factory->NewVariableProxy(var_output), zone);
6366 is_receiver_call = 6376 is_receiver_call =
6367 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 6377 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6368 } 6378 }
6369 6379
6370 Statement* throw_call; 6380 Statement* throw_call;
6371 { 6381 {
6372 auto args = new (zone) ZoneList<Expression*>(1, zone); 6382 auto args = new (zone) ZoneList<Expression*>(1, zone);
6373 args->Add(factory->NewVariableProxy(var), zone); 6383 args->Add(factory->NewVariableProxy(var_output), zone);
6374 Expression* call = factory->NewCallRuntime( 6384 Expression* call = factory->NewCallRuntime(
6375 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6385 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6376 throw_call = factory->NewExpressionStatement(call, nopos); 6386 throw_call = factory->NewExpressionStatement(call, nopos);
6377 } 6387 }
6378 6388
6379 validate_output = 6389 validate_output = factory->NewIfStatement(
6380 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 6390 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6381 } 6391 }
6382 6392
6383 statements->Add(get_return, zone); 6393 statements->Add(get_return, zone);
6384 statements->Add(check_return, zone); 6394 statements->Add(check_return, zone);
6385 statements->Add(call_return, zone); 6395 statements->Add(call_return, zone);
6386 statements->Add(validate_output, zone); 6396 statements->Add(validate_output, zone);
6387 } 6397 }
6388 6398
6389 6399
6400 // Runtime encoding of different completion modes.
6401 enum ForOfLoopBodyCompletion { BODY_COMPLETED, BODY_ABORTED, BODY_THREW };
6402
6403 void ParserTraits::BuildIteratorCloseForCompletion(
6404 ZoneList<Statement*>* statements, Variable* iterator,
6405 Variable* completion) {
6406 //
6407 // This function adds two statements to [statements], corresponding to the
6408 // following code:
6409 //
6410 // let iteratorReturn = iterator.return;
6411 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
6412 // let output;
6413 // if (completion === BODY_THREW) {
6414 // if (!IS_CALLABLE(iteratorReturn)) {
6415 // throw MakeTypeError(kReturnMethodNotCallable);
6416 // }
6417 // try { output = %_Call(iteratorReturn, iterator) } catch (_) { }
6418 // } else {
6419 // output = %_Call(iteratorReturn, iterator);
6420 // }
6421 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6422 // }
6423 //
6424
6425 const int nopos = RelocInfo::kNoPosition;
6426 auto factory = parser_->factory();
6427 auto avfactory = parser_->ast_value_factory();
6428 auto scope = parser_->scope_;
6429 auto zone = parser_->zone();
6430
6431 // let output;
6432 Variable* var_output = scope->NewTemporary(avfactory->empty_string());
6433
6434 // let iteratorReturn = iterator.return;
6435 Variable* var_return = var_output; // Reusing the output variable.
6436 Statement* get_return;
6437 {
6438 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6439 Expression* literal =
6440 factory->NewStringLiteral(avfactory->return_string(), nopos);
6441 Expression* property =
6442 factory->NewProperty(iterator_proxy, literal, nopos);
6443 Expression* return_proxy = factory->NewVariableProxy(var_return);
6444 Expression* assignment = factory->NewAssignment(
6445 Token::ASSIGN, return_proxy, property, nopos);
6446 get_return = factory->NewExpressionStatement(assignment, nopos);
6447 }
6448
6449 // if (!IS_CALLABLE(iteratorReturn)) {
6450 // throw MakeTypeError(kReturnMethodNotCallable);
6451 // }
6452 Statement* check_return_callable;
6453 {
6454 Expression* type_of = factory->NewUnaryOperation(
6455 Token::TYPEOF, factory->NewVariableProxy(var_return), nopos);
6456 Expression* function_literal = factory->NewStringLiteral(
6457 avfactory->function_string(), nopos);
6458 Expression* condition = factory->NewCompareOperation(
6459 Token::EQ_STRICT, type_of, function_literal, nopos);
6460
6461 Expression* call = NewThrowTypeError(
6462 MessageTemplate::kReturnMethodNotCallable,
6463 avfactory->empty_string(), nopos);
6464 Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6465
6466 check_return_callable = factory->NewIfStatement(
6467 condition, factory->NewEmptyStatement(nopos), throw_call, nopos);
6468 }
6469
6470 // output = %_Call(iteratorReturn, iterator);
6471 Statement* call_return;
6472 {
6473 auto args = new (zone) ZoneList<Expression*>(2, zone);
6474 args->Add(factory->NewVariableProxy(var_return), zone);
6475 args->Add(factory->NewVariableProxy(iterator), zone);
6476 Expression* call =
6477 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6478
6479 Expression* output_proxy = factory->NewVariableProxy(var_output);
6480 Expression* assignment = factory->NewAssignment(
6481 Token::ASSIGN, output_proxy, call, nopos);
6482 call_return = factory->NewExpressionStatement(assignment, nopos);
6483 }
6484
6485 // try { output = %_Call(iteratorReturn, iterator) } catch (_) { }
6486 Statement* try_call_return;
6487 {
6488 auto args = new (zone) ZoneList<Expression*>(2, zone);
6489 args->Add(factory->NewVariableProxy(var_return), zone);
6490 args->Add(factory->NewVariableProxy(iterator), zone);
6491
6492 Expression* call =
6493 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6494 Expression* assignment = factory->NewAssignment(
6495 Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos);
6496
6497 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6498 try_block->statements()->Add(
6499 factory->NewExpressionStatement(assignment, nopos), zone);
6500
6501 Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos);
6502
6503 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6504 Variable* catch_variable = catch_scope->DeclareLocal(
6505 avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6506 Variable::NORMAL);
6507
6508 try_call_return = factory->NewTryCatchStatement(
6509 try_block, catch_scope, catch_variable, catch_block, nopos);
6510 }
6511
6512 // if (completion === ABRUPT_THROW) {
6513 // #check_return_callable;
6514 // #try_call_return;
6515 // } else {
6516 // #call_return;
6517 // }
6518 Statement* call_return_carefully;
6519 {
6520 Expression* condition = factory->NewCompareOperation(
6521 Token::EQ_STRICT, factory->NewVariableProxy(completion),
6522 factory->NewSmiLiteral(BODY_THREW, nopos), nopos);
6523
6524 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos);
6525 then_block->statements()->Add(check_return_callable, zone);
6526 then_block->statements()->Add(try_call_return, zone);
6527
6528 call_return_carefully =
6529 factory->NewIfStatement(condition, then_block, call_return, nopos);
6530 }
6531
6532 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
6533 Statement* validate_output;
6534 {
6535 Expression* is_receiver_call;
6536 {
6537 auto args = new (zone) ZoneList<Expression*>(1, zone);
6538 args->Add(factory->NewVariableProxy(var_output), zone);
6539 is_receiver_call =
6540 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6541 }
6542
6543 Statement* throw_call;
6544 {
6545 auto args = new (zone) ZoneList<Expression*>(1, zone);
6546 args->Add(factory->NewVariableProxy(var_output), zone);
6547 Expression* call = factory->NewCallRuntime(
6548 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6549 throw_call = factory->NewExpressionStatement(call, nopos);
6550 }
6551
6552 validate_output = factory->NewIfStatement(
6553 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6554 }
6555
6556 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
6557 Statement* maybe_call_return;
6558 {
6559 Expression* condition = factory->NewCompareOperation(
6560 Token::EQ, factory->NewVariableProxy(var_return),
6561 factory->NewNullLiteral(nopos), nopos);
6562
6563 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6564 block->statements()->Add(call_return_carefully, zone);
6565 block->statements()->Add(validate_output, zone);
6566
6567 maybe_call_return = factory->NewIfStatement(
6568 condition, factory->NewEmptyStatement(nopos), block, nopos);
6569 }
6570
6571
6572 statements->Add(get_return, zone);
6573 statements->Add(maybe_call_return, zone);
6574 }
6575
6576
6577 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
6578 if (!FLAG_harmony_iterator_close) return loop;
6579
6580 //
6581 // This function replaces the loop with the following wrapping:
6582 //
6583 // let completion = BODY_COMPLETED;
6584 // try {
6585 // #loop;
6586 // } catch(e) {
6587 // if (completion === BODY_ABORTED) completion = BODY_THREW;
6588 // throw e;
6589 // } finally {
6590 // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) {
6591 // #BuildIteratorClose(#iterator, completion) // See above.
6592 // }
6593 // }
6594 //
6595 // where the loop's body is wrapped as follows:
6596 //
6597 // {
6598 // {{completion = BODY_ABORTED;}}
6599 // #loop-body
6600 // {{completion = BODY_COMPLETED;}}
6601 // }
6602
6603 const int nopos = RelocInfo::kNoPosition;
6604 auto factory = parser_->factory();
6605 auto avfactory = parser_->ast_value_factory();
6606 auto scope = parser_->scope_;
6607 auto zone = parser_->zone();
6608
6609 // let completion = BODY_COMPLETED;
6610 Variable* var_completion = scope->NewTemporary(avfactory->empty_string());
6611 Statement* initialize_completion;
6612 {
6613 Expression* proxy = factory->NewVariableProxy(var_completion);
6614 Expression* assignment = factory->NewAssignment(
6615 Token::ASSIGN, proxy,
6616 factory->NewSmiLiteral(BODY_COMPLETED, nopos), nopos);
6617 initialize_completion =
6618 factory->NewExpressionStatement(assignment, nopos);
6619 }
6620
6621 // if (completion === BODY_ABORTED) completion = BODY_THREW;
6622 Statement* set_completion_throw;
6623 {
6624 Expression* condition = factory->NewCompareOperation(
6625 Token::EQ_STRICT, factory->NewVariableProxy(var_completion),
6626 factory->NewSmiLiteral(BODY_ABORTED, nopos), nopos);
6627
6628 Expression* proxy = factory->NewVariableProxy(var_completion);
6629 Expression* assignment = factory->NewAssignment(
6630 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_THREW, nopos),
6631 nopos);
6632 Statement* statement = factory->NewExpressionStatement(assignment, nopos);
6633 set_completion_throw = factory->NewIfStatement(
6634 condition, statement, factory->NewEmptyStatement(nopos), nopos);
6635 }
6636
6637 // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) {
6638 // #BuildIteratorClose(#iterator, completion)
6639 // }
6640 Block* maybe_close;
6641 {
6642 Expression* condition1 = factory->NewCompareOperation(
6643 Token::EQ_STRICT, factory->NewVariableProxy(var_completion),
6644 factory->NewSmiLiteral(BODY_COMPLETED, nopos), nopos);
6645 Expression* condition2 = factory->NewCompareOperation(
6646 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()),
6647 factory->NewUndefinedLiteral(nopos), nopos);
6648 Expression* condition = factory->NewBinaryOperation(
6649 Token::OR, condition1, condition2, nopos);
6650
6651 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6652 BuildIteratorCloseForCompletion(
6653 block->statements(), loop->iterator(), var_completion);
6654 DCHECK(block->statements()->length() == 2);
6655
6656 maybe_close = factory->NewBlock(nullptr, 1, false, nopos);
6657 maybe_close->statements()->Add(factory->NewIfStatement(
6658 condition, factory->NewEmptyStatement(nopos), block, nopos), zone);
6659 }
6660
6661 // try { #try_block }
6662 // catch(e) {
6663 // #set_completion_throw;
6664 // throw e;
6665 // }
6666 Statement* try_catch;
6667 {
6668 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6669 Variable* catch_variable = catch_scope->DeclareLocal(
6670 avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6671 Variable::NORMAL);
6672
6673 Statement* rethrow;
6674 {
6675 Expression* proxy = factory->NewVariableProxy(catch_variable);
6676 rethrow = factory->NewExpressionStatement(
6677 factory->NewThrow(proxy, nopos), nopos);
6678 }
6679
6680 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6681 try_block->statements()->Add(loop, zone);
6682
6683 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos);
6684 catch_block->statements()->Add(set_completion_throw, zone);
6685 catch_block->statements()->Add(rethrow, zone);
6686
6687 try_catch = factory->NewTryCatchStatement(
6688 try_block, catch_scope, catch_variable, catch_block, nopos);
6689 }
6690
6691 // try { #try_catch } finally { #maybe_close }
6692 Statement* try_finally;
6693 {
6694 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6695 try_block->statements()->Add(try_catch, zone);
6696
6697 try_finally =
6698 factory->NewTryFinallyStatement(try_block, maybe_close, nopos);
6699 }
6700
6701 // #initialize_completion;
6702 // #try_finally;
6703 Statement* final_loop;
6704 {
6705 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6706 block->statements()->Add(initialize_completion, zone);
6707 block->statements()->Add(try_finally, zone);
6708 final_loop = block;
6709 }
6710
6711 // {{completion = BODY_ABORTED;}}
6712 Statement* set_completion_break;
6713 {
6714 Expression* proxy = factory->NewVariableProxy(var_completion);
6715 Expression* assignment = factory->NewAssignment(
6716 Token::ASSIGN, proxy,
6717 factory->NewSmiLiteral(BODY_ABORTED, nopos), nopos);
6718
6719 Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6720 block->statements()->Add(
6721 factory->NewExpressionStatement(assignment, nopos), zone);
6722 set_completion_break = block;
6723 }
6724
6725 // {{completion = BODY_COMPLETED;}}
6726 Statement* set_completion_normal;
6727 {
6728 Expression* proxy = factory->NewVariableProxy(var_completion);
6729 Expression* assignment = factory->NewAssignment(
6730 Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_COMPLETED, nopos),
6731 nopos);
6732
6733 Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6734 block->statements()->Add(
6735 factory->NewExpressionStatement(assignment, nopos), zone);
6736 set_completion_normal = block;
6737 }
6738
6739 // { #set_completion_break; #loop-body; #set_completion_normal }
6740 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos);
6741 new_body->statements()->Add(set_completion_break, zone);
6742 new_body->statements()->Add(loop->body(), zone);
6743 new_body->statements()->Add(set_completion_normal, zone);
6744
6745 loop->set_body(new_body);
6746 return final_loop;
6747 }
6748
6749
6390 } // namespace internal 6750 } // namespace internal
6391 } // namespace v8 6751 } // 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