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

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

Issue 1695583003: [WIP] for-of iterator finalization (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 } 3773 }
3776 } 3774 }
3777 3775
3776 if (loop->IsForOfStatement()) {
3777 FinalizeForOfStatement(
3778 loop->AsForOfStatement(), RelocInfo::kNoPosition);
3779 }
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(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 loop;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3854 block->statements()->Add(body, zone()); 3857 block->statements()->Add(body, zone());
3855 InitializeForEachStatement(loop, expression, enumerable, block, 3858 InitializeForEachStatement(loop, expression, enumerable, block,
3856 is_destructuring); 3859 is_destructuring);
3857 body_scope->set_end_position(scanner()->location().end_pos); 3860 body_scope->set_end_position(scanner()->location().end_pos);
3858 body_scope = body_scope->FinalizeBlockScope(); 3861 body_scope = body_scope->FinalizeBlockScope();
3859 block->set_scope(body_scope); 3862 block->set_scope(body_scope);
3860 for_scope->set_end_position(scanner()->location().end_pos); 3863 for_scope->set_end_position(scanner()->location().end_pos);
3861 for_scope = for_scope->FinalizeBlockScope(); 3864 for_scope = for_scope->FinalizeBlockScope();
3862 DCHECK(for_scope == nullptr); 3865 DCHECK(for_scope == nullptr);
3863 // Parsed for-in loop. 3866 // Parsed for-in loop.
3867 if (loop->IsForOfStatement()) {
3868 FinalizeForOfStatement(
3869 loop->AsForOfStatement(), RelocInfo::kNoPosition);
3870 }
3864 return loop; 3871 return loop;
3865 3872
3866 } else { 3873 } else {
3867 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); 3874 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3868 } 3875 }
3869 } 3876 }
3870 } 3877 }
3871 3878
3872 // Standard 'for' loop 3879 // Standard 'for' loop
3873 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); 3880 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
(...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after
5734 factory()->NewCallRuntime(Runtime::kAppendElement, 5741 factory()->NewCallRuntime(Runtime::kAppendElement,
5735 append_element_args, 5742 append_element_args,
5736 RelocInfo::kNoPosition), 5743 RelocInfo::kNoPosition),
5737 RelocInfo::kNoPosition); 5744 RelocInfo::kNoPosition);
5738 } 5745 }
5739 // for (each of spread) %AppendElement($R, each) 5746 // for (each of spread) %AppendElement($R, each)
5740 ForEachStatement* loop = factory()->NewForEachStatement( 5747 ForEachStatement* loop = factory()->NewForEachStatement(
5741 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition); 5748 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition);
5742 ForOfStatement* for_of = loop->AsForOfStatement(); 5749 ForOfStatement* for_of = loop->AsForOfStatement();
5743 for_of->Initialize(factory()->NewVariableProxy(each), subject, 5750 for_of->Initialize(factory()->NewVariableProxy(each), subject,
5744 append_body, assign_iterator, next_element, 5751 append_body, iterator, assign_iterator, next_element,
5745 element_done, assign_each); 5752 element_done, assign_each);
5746 do_block->statements()->Add(for_of, zone()); 5753 do_block->statements()->Add(for_of, zone());
5747 } 5754 }
5748 } 5755 }
5749 // Now, rewind the original array literal to truncate everything from the 5756 // Now, rewind the original array literal to truncate everything from the
5750 // first spread (included) until the end. This fixes $R's initialization. 5757 // first spread (included) until the end. This fixes $R's initialization.
5751 lit->RewindSpreads(); 5758 lit->RewindSpreads();
5752 return factory()->NewDoExpression(do_block, result, lit->position()); 5759 return factory()->NewDoExpression(do_block, result, lit->position());
5753 } 5760 }
5754 5761
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
5892 Expression* ParserTraits::RewriteYieldStar( 5899 Expression* ParserTraits::RewriteYieldStar(
5893 Expression* generator, Expression* iterable, int pos) { 5900 Expression* generator, Expression* iterable, int pos) {
5894 5901
5895 const int nopos = RelocInfo::kNoPosition; 5902 const int nopos = RelocInfo::kNoPosition;
5896 5903
5897 auto factory = parser_->factory(); 5904 auto factory = parser_->factory();
5898 auto avfactory = parser_->ast_value_factory(); 5905 auto avfactory = parser_->ast_value_factory();
5899 auto scope = parser_->scope_; 5906 auto scope = parser_->scope_;
5900 auto zone = parser_->zone(); 5907 auto zone = parser_->zone();
5901 5908
5902 Statement* skip = factory->NewEmptyStatement(nopos);
5903 5909
neis 2016/02/12 12:30:13 The changes to RewriteYieldStar are unrelated.
5904 // Forward definition for break/continue statements. 5910 // Forward definition for break/continue statements.
5905 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos); 5911 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos);
5906 5912
5907 5913
5908 // let input = undefined; 5914 // let input = undefined;
5909 Variable* var_input = scope->NewTemporary(avfactory->empty_string()); 5915 Variable* var_input = scope->NewTemporary(avfactory->empty_string());
5910 Statement* initialize_input; 5916 Statement* initialize_input;
5911 { 5917 {
5912 Expression* input_proxy = factory->NewVariableProxy(var_input); 5918 Expression* input_proxy = factory->NewVariableProxy(var_input);
5913 Expression* assignment = factory->NewAssignment( 5919 Expression* assignment = factory->NewAssignment(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5964 } 5970 }
5965 5971
5966 Statement* throw_call; 5972 Statement* throw_call;
5967 { 5973 {
5968 Expression* call = NewThrowTypeError( 5974 Expression* call = NewThrowTypeError(
5969 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(), 5975 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(),
5970 nopos); 5976 nopos);
5971 throw_call = factory->NewExpressionStatement(call, nopos); 5977 throw_call = factory->NewExpressionStatement(call, nopos);
5972 } 5978 }
5973 5979
5974 validate_iterator = 5980 validate_iterator = factory->NewIfStatement(
5975 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 5981 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
5976 } 5982 }
5977 5983
5978 5984
5979 // output = iterator.next(input); 5985 // output = iterator.next(input);
5980 Statement* call_next; 5986 Statement* call_next;
5981 { 5987 {
5982 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); 5988 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
5983 Expression* literal = 5989 Expression* literal =
5984 factory->NewStringLiteral(avfactory->next_string(), nopos); 5990 factory->NewStringLiteral(avfactory->next_string(), nopos);
5985 Expression* next_property = 5991 Expression* next_property =
(...skipping 22 matching lines...) Expand all
6008 6014
6009 Statement* throw_call; 6015 Statement* throw_call;
6010 { 6016 {
6011 auto args = new (zone) ZoneList<Expression*>(1, zone); 6017 auto args = new (zone) ZoneList<Expression*>(1, zone);
6012 args->Add(factory->NewVariableProxy(var_output), zone); 6018 args->Add(factory->NewVariableProxy(var_output), zone);
6013 Expression* call = factory->NewCallRuntime( 6019 Expression* call = factory->NewCallRuntime(
6014 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6020 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6015 throw_call = factory->NewExpressionStatement(call, nopos); 6021 throw_call = factory->NewExpressionStatement(call, nopos);
6016 } 6022 }
6017 6023
6018 validate_next_output = 6024 validate_next_output = factory->NewIfStatement(
6019 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 6025 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6020 } 6026 }
6021 6027
6022 6028
6023 // let iteratorThrow = iterator.throw; 6029 // let iteratorThrow = iterator.throw;
6024 Variable* var_throw = scope->NewTemporary(avfactory->empty_string()); 6030 Variable* var_throw = scope->NewTemporary(avfactory->empty_string());
6025 Statement* get_throw; 6031 Statement* get_throw;
6026 { 6032 {
6027 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); 6033 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator);
6028 Expression* literal = 6034 Expression* literal =
6029 factory->NewStringLiteral(avfactory->throw_string(), nopos); 6035 factory->NewStringLiteral(avfactory->throw_string(), nopos);
(...skipping 15 matching lines...) Expand all
6045 Expression* condition = factory->NewCompareOperation( 6051 Expression* condition = factory->NewCompareOperation(
6046 Token::EQ, factory->NewVariableProxy(var_throw), 6052 Token::EQ, factory->NewVariableProxy(var_throw),
6047 factory->NewNullLiteral(nopos), nopos); 6053 factory->NewNullLiteral(nopos), nopos);
6048 6054
6049 Expression* call = NewThrowTypeError( 6055 Expression* call = NewThrowTypeError(
6050 MessageTemplate::kThrowMethodMissing, 6056 MessageTemplate::kThrowMethodMissing,
6051 avfactory->empty_string(), nopos); 6057 avfactory->empty_string(), nopos);
6052 Statement* throw_call = factory->NewExpressionStatement(call, nopos); 6058 Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6053 6059
6054 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); 6060 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos);
6055 BuildIteratorClose(then->statements(), var_iterator, Nothing<Variable*>(), 6061 Variable* var_tmp = scope->NewTemporary(avfactory->empty_string());
6056 Nothing<Variable*>()); 6062 BuildIteratorClose(
6063 then->statements(), var_iterator, Nothing<Variable*>(), var_tmp);
6057 then->statements()->Add(throw_call, zone); 6064 then->statements()->Add(throw_call, zone);
6058 check_throw = 6065 check_throw = factory->NewIfStatement(
6059 factory->NewIfStatement(condition, then, skip, nopos); 6066 condition, then, factory->NewEmptyStatement(nopos), nopos);
6060 } 6067 }
6061 6068
6062 6069
6063 // output = %_Call(iteratorThrow, iterator, input); 6070 // output = %_Call(iteratorThrow, iterator, input);
6064 Statement* call_throw; 6071 Statement* call_throw;
6065 { 6072 {
6066 auto args = new (zone) ZoneList<Expression*>(3, zone); 6073 auto args = new (zone) ZoneList<Expression*>(3, zone);
6067 args->Add(factory->NewVariableProxy(var_throw), zone); 6074 args->Add(factory->NewVariableProxy(var_throw), zone);
6068 args->Add(factory->NewVariableProxy(var_iterator), zone); 6075 args->Add(factory->NewVariableProxy(var_iterator), zone);
6069 args->Add(factory->NewVariableProxy(var_input), zone); 6076 args->Add(factory->NewVariableProxy(var_input), zone);
(...skipping 18 matching lines...) Expand all
6088 6095
6089 Statement* throw_call; 6096 Statement* throw_call;
6090 { 6097 {
6091 auto args = new (zone) ZoneList<Expression*>(1, zone); 6098 auto args = new (zone) ZoneList<Expression*>(1, zone);
6092 args->Add(factory->NewVariableProxy(var_output), zone); 6099 args->Add(factory->NewVariableProxy(var_output), zone);
6093 Expression* call = factory->NewCallRuntime( 6100 Expression* call = factory->NewCallRuntime(
6094 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6101 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6095 throw_call = factory->NewExpressionStatement(call, nopos); 6102 throw_call = factory->NewExpressionStatement(call, nopos);
6096 } 6103 }
6097 6104
6098 validate_throw_output = 6105 validate_throw_output = factory->NewIfStatement(
6099 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 6106 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6100 } 6107 }
6101 6108
6102 6109
6103 // if (output.done) break; 6110 // if (output.done) break;
6104 Statement* if_done; 6111 Statement* if_done;
6105 { 6112 {
6106 Expression* output_proxy = factory->NewVariableProxy(var_output); 6113 Expression* output_proxy = factory->NewVariableProxy(var_output);
6107 Expression* literal = 6114 Expression* literal =
6108 factory->NewStringLiteral(avfactory->done_string(), nopos); 6115 factory->NewStringLiteral(avfactory->done_string(), nopos);
6109 Expression* property = factory->NewProperty(output_proxy, literal, nopos); 6116 Expression* property = factory->NewProperty(output_proxy, literal, nopos);
6110 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos); 6117 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos);
6111 if_done = factory->NewIfStatement(property, break_loop, skip, nopos); 6118 if_done = factory->NewIfStatement(
6119 property, break_loop, factory->NewEmptyStatement(nopos), nopos);
6112 } 6120 }
6113 6121
6114 6122
6115 // mode = kReturn; 6123 // mode = kReturn;
6116 Statement* set_mode_return; 6124 Statement* set_mode_return;
6117 { 6125 {
6118 Expression* mode_proxy = factory->NewVariableProxy(var_mode); 6126 Expression* mode_proxy = factory->NewVariableProxy(var_mode);
6119 Expression* kreturn = 6127 Expression* kreturn =
6120 factory->NewSmiLiteral(JSGeneratorObject::RETURN, nopos); 6128 factory->NewSmiLiteral(JSGeneratorObject::RETURN, nopos);
6121 Expression* assignment = 6129 Expression* assignment =
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
6220 6228
6221 // switch (mode) { ... } 6229 // switch (mode) { ... }
6222 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); 6230 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos);
6223 { 6231 {
6224 auto case_next = new (zone) ZoneList<Statement*>(3, zone); 6232 auto case_next = new (zone) ZoneList<Statement*>(3, zone);
6225 case_next->Add(call_next, zone); 6233 case_next->Add(call_next, zone);
6226 case_next->Add(validate_next_output, zone); 6234 case_next->Add(validate_next_output, zone);
6227 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6235 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6228 6236
6229 auto case_return = new (zone) ZoneList<Statement*>(5, zone); 6237 auto case_return = new (zone) ZoneList<Statement*>(5, zone);
6230 BuildIteratorClose( 6238 BuildIteratorClose(case_return, var_iterator, Just(var_input), var_output);
6231 case_return, var_iterator, Just(var_input), Just(var_output));
6232 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6239 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6233 6240
6234 auto case_throw = new (zone) ZoneList<Statement*>(5, zone); 6241 auto case_throw = new (zone) ZoneList<Statement*>(5, zone);
6235 case_throw->Add(get_throw, zone); 6242 case_throw->Add(get_throw, zone);
6236 case_throw->Add(check_throw, zone); 6243 case_throw->Add(check_throw, zone);
6237 case_throw->Add(call_throw, zone); 6244 case_throw->Add(call_throw, zone);
6238 case_throw->Add(validate_throw_output, zone); 6245 case_throw->Add(validate_throw_output, zone);
6239 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6246 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
6240 6247
6241 auto cases = new (zone) ZoneList<CaseClause*>(3, zone); 6248 auto cases = new (zone) ZoneList<CaseClause*>(3, zone);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
6285 6292
6286 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); 6293 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string());
6287 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); 6294 yield_star = factory->NewDoExpression(do_block, dot_result, nopos);
6288 Rewriter::Rewrite(parser_, yield_star, avfactory); 6295 Rewriter::Rewrite(parser_, yield_star, avfactory);
6289 } 6296 }
6290 6297
6291 return yield_star; 6298 return yield_star;
6292 } 6299 }
6293 6300
6294 6301
6295 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, 6302 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements,
neis 2016/02/12 12:30:13 The changes to this BuildIteratorClose are unrelat
6296 Variable* iterator, 6303 Variable* iterator,
6297 Maybe<Variable*> input, 6304 Maybe<Variable*> input,
6298 Maybe<Variable*> output) { 6305 Variable* var_output) {
6306 //
6307 // This function adds four statements to [statements], corresponding to the
6308 // following code:
6309 //
6310 // let iteratorReturn = iterator.return;
6311 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return |input|;
6312 // output = %_Call(iteratorReturn, iterator|, input|);
6313 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6314 //
6315 // Here, |...| denotes optional parts, depending on the presence of the
6316 // input variable.
6317 //
6318
6299 const int nopos = RelocInfo::kNoPosition; 6319 const int nopos = RelocInfo::kNoPosition;
6300 auto factory = parser_->factory(); 6320 auto factory = parser_->factory();
6301 auto avfactory = parser_->ast_value_factory(); 6321 auto avfactory = parser_->ast_value_factory();
6302 auto scope = parser_->scope_;
6303 auto zone = parser_->zone(); 6322 auto zone = parser_->zone();
6304 Statement* skip = factory->NewEmptyStatement(nopos); 6323
6305 6324
6306 // let iteratorReturn = iterator.return; 6325 // let iteratorReturn = iterator.return;
6307 Variable* var = scope->NewTemporary(avfactory->empty_string()); 6326 Variable* var_return = var_output; // Reusing the output variable.
6308 Statement* get_return; 6327 Statement* get_return;
6309 { 6328 {
6310 Expression* iterator_proxy = factory->NewVariableProxy(iterator); 6329 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6311 Expression* literal = 6330 Expression* literal =
6312 factory->NewStringLiteral(avfactory->return_string(), nopos); 6331 factory->NewStringLiteral(avfactory->return_string(), nopos);
6313 Expression* property = 6332 Expression* property =
6314 factory->NewProperty(iterator_proxy, literal, nopos); 6333 factory->NewProperty(iterator_proxy, literal, nopos);
6315 Expression* return_proxy = factory->NewVariableProxy(var); 6334 Expression* return_proxy = factory->NewVariableProxy(var_return);
6316 Expression* assignment = factory->NewAssignment( 6335 Expression* assignment = factory->NewAssignment(
6317 Token::ASSIGN, return_proxy, property, nopos); 6336 Token::ASSIGN, return_proxy, property, nopos);
6318 get_return = factory->NewExpressionStatement(assignment, nopos); 6337 get_return = factory->NewExpressionStatement(assignment, nopos);
6319 } 6338 }
6320 6339
6321 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return; OR 6340
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 Expression* value = input.IsJust() ?
6330 static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) : 6349 static_cast<Expression*>(factory->NewVariableProxy(input.FromJust())) :
6331 factory->NewUndefinedLiteral(nopos); 6350 factory->NewUndefinedLiteral(nopos);
6332 6351
6333 Statement* return_undefined = factory->NewReturnStatement(value, nopos); 6352 Statement* return_undefined = factory->NewReturnStatement(value, nopos);
6334 6353
6335 check_return = 6354 check_return = factory->NewIfStatement(
6336 factory->NewIfStatement(condition, return_undefined, skip, nopos); 6355 condition, return_undefined, factory->NewEmptyStatement(nopos), nopos);
6337 } 6356 }
6338 6357
6339 // let output = %_Call(iteratorReturn, iterator); OR 6358
6340 // output = %_Call(iteratorReturn, iterator, input); 6359 // output = %_Call(iteratorReturn, iterator|, input|);
6341 Statement* call_return; 6360 Statement* call_return;
6342 { 6361 {
6343 auto args = new (zone) ZoneList<Expression*>(3, zone); 6362 auto args = new (zone) ZoneList<Expression*>(3, zone);
6344 args->Add(factory->NewVariableProxy(var), zone); 6363 args->Add(factory->NewVariableProxy(var_return), zone);
6345 args->Add(factory->NewVariableProxy(iterator), zone); 6364 args->Add(factory->NewVariableProxy(iterator), zone);
6346 if (input.IsJust()) { 6365 if (input.IsJust()) {
6347 args->Add(factory->NewVariableProxy(input.FromJust()), zone); 6366 args->Add(factory->NewVariableProxy(input.FromJust()), zone);
6348 } 6367 }
6349 6368
6350 Expression* call = 6369 Expression* call =
6351 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); 6370 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6352 Expression* output_proxy = factory->NewVariableProxy( 6371 Expression* output_proxy = factory->NewVariableProxy(var_output);
6353 output.IsJust() ? output.FromJust() : var);
6354 Expression* assignment = factory->NewAssignment( 6372 Expression* assignment = factory->NewAssignment(
6355 Token::ASSIGN, output_proxy, call, nopos); 6373 Token::ASSIGN, output_proxy, call, nopos);
6356 call_return = factory->NewExpressionStatement(assignment, nopos); 6374 call_return = factory->NewExpressionStatement(assignment, nopos);
6357 } 6375 }
6358 6376
6359 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 6377
6378 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
6360 Statement* validate_output; 6379 Statement* validate_output;
6361 { 6380 {
6362 Expression* is_receiver_call; 6381 Expression* is_receiver_call;
6363 { 6382 {
6364 auto args = new (zone) ZoneList<Expression*>(1, zone); 6383 auto args = new (zone) ZoneList<Expression*>(1, zone);
6365 args->Add(factory->NewVariableProxy(var), zone); 6384 args->Add(factory->NewVariableProxy(var_output), zone);
6366 is_receiver_call = 6385 is_receiver_call =
6367 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 6386 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6368 } 6387 }
6369 6388
6370 Statement* throw_call; 6389 Statement* throw_call;
6371 { 6390 {
6372 auto args = new (zone) ZoneList<Expression*>(1, zone); 6391 auto args = new (zone) ZoneList<Expression*>(1, zone);
6373 args->Add(factory->NewVariableProxy(var), zone); 6392 args->Add(factory->NewVariableProxy(var_output), zone);
6374 Expression* call = factory->NewCallRuntime( 6393 Expression* call = factory->NewCallRuntime(
6375 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6394 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6376 throw_call = factory->NewExpressionStatement(call, nopos); 6395 throw_call = factory->NewExpressionStatement(call, nopos);
6377 } 6396 }
6378 6397
6379 validate_output = 6398 validate_output = factory->NewIfStatement(
6380 factory->NewIfStatement(is_receiver_call, skip, throw_call, nopos); 6399 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6381 } 6400 }
6382 6401
6402
6383 statements->Add(get_return, zone); 6403 statements->Add(get_return, zone);
6384 statements->Add(check_return, zone); 6404 statements->Add(check_return, zone);
6385 statements->Add(call_return, zone); 6405 statements->Add(call_return, zone);
6386 statements->Add(validate_output, zone); 6406 statements->Add(validate_output, zone);
6387 } 6407 }
6388 6408
6389 6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419 enum { THROW, RETURN_OR_BREAK, NORMAL };
6420
6421
6422 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements,
6423 Variable* iterator,
6424 Variable* completion) {
6425 //
6426 // This function adds two statements to [statements], corresponding to the
6427 // following code:
6428 //
6429 // let iteratorReturn = iterator.return;
6430 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
6431 // let output;
6432 // if (completion === THROW) {
6433 // if (!IS_CALLABLE(iteratorReturn)) {
6434 // throw MakeTypeError(kReturnMethodNotCallable);
6435 // }
6436 // try { output = %_Call(iteratorReturn, iterator) } catch (_) { }
6437 // } else {
6438 // output = %_Call(iteratorReturn, iterator);
6439 // }
6440 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
6441 // }
6442 //
6443
6444 const int nopos = RelocInfo::kNoPosition;
6445 auto factory = parser_->factory();
6446 auto avfactory = parser_->ast_value_factory();
6447 auto scope = parser_->scope_;
6448 auto zone = parser_->zone();
6449
6450
6451 // let output;
6452 Variable* var_output = scope->NewTemporary(avfactory->empty_string());
6453
6454
6455 // let iteratorReturn = iterator.return;
6456 Variable* var_return = var_output; // Reusing the output variable.
6457 Statement* get_return;
6458 {
6459 Expression* iterator_proxy = factory->NewVariableProxy(iterator);
6460 Expression* literal =
6461 factory->NewStringLiteral(avfactory->return_string(), nopos);
6462 Expression* property =
6463 factory->NewProperty(iterator_proxy, literal, nopos);
6464 Expression* return_proxy = factory->NewVariableProxy(var_return);
6465 Expression* assignment = factory->NewAssignment(
6466 Token::ASSIGN, return_proxy, property, nopos);
6467 get_return = factory->NewExpressionStatement(assignment, nopos);
6468 }
6469
6470
6471 // if (!IS_CALLABLE(iteratorReturn)) {
6472 // throw MakeTypeError(kReturnMethodNotCallable);
6473 // }
6474 Statement* check_return_callable;
6475 {
6476 Expression* type_of = factory->NewUnaryOperation(
6477 Token::TYPEOF, factory->NewVariableProxy(var_return), nopos);
6478 Expression* function_literal = factory->NewStringLiteral(
6479 avfactory->function_string(), nopos);
6480 Expression* condition = factory->NewCompareOperation(
6481 Token::EQ_STRICT, type_of, function_literal, nopos);
6482
6483 Expression* call = NewThrowTypeError(
6484 MessageTemplate::kReturnMethodNotCallable,
6485 avfactory->empty_string(), nopos);
6486 Statement* throw_call = factory->NewExpressionStatement(call, nopos);
6487
6488 check_return_callable = factory->NewIfStatement(
6489 condition, factory->NewEmptyStatement(nopos), throw_call, nopos);
6490 }
6491
6492
6493 // output = %_Call(iteratorReturn, iterator);
6494 Statement* call_return;
6495 {
6496 auto args = new (zone) ZoneList<Expression*>(2, zone);
6497 args->Add(factory->NewVariableProxy(var_return), zone);
6498 args->Add(factory->NewVariableProxy(iterator), zone);
6499 Expression* call =
6500 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6501
6502 Expression* output_proxy = factory->NewVariableProxy(var_output);
6503 Expression* assignment = factory->NewAssignment(
6504 Token::ASSIGN, output_proxy, call, nopos);
6505 call_return = factory->NewExpressionStatement(assignment, nopos);
6506 }
6507
6508
6509 // try { output = %_Call(iteratorReturn, iterator) } catch (_) { }
6510 Statement* try_call_return;
6511 {
6512 auto args = new (zone) ZoneList<Expression*>(2, zone);
6513 args->Add(factory->NewVariableProxy(var_return), zone);
6514 args->Add(factory->NewVariableProxy(iterator), zone);
6515
6516 Expression* call =
6517 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
6518 Expression* assignment = factory->NewAssignment(
6519 Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos);
6520
6521 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6522 try_block->statements()->Add(
6523 factory->NewExpressionStatement(assignment, nopos), zone);
6524
6525 Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos);
6526
6527 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6528 Variable* catch_variable = catch_scope->DeclareLocal(
6529 avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6530 Variable::NORMAL);
6531
6532 try_call_return = factory->NewTryCatchStatement(
6533 try_block, catch_scope, catch_variable, catch_block, nopos);
6534 }
6535
6536
6537 // if (completion === THROW) {
6538 // #check_return_callable;
6539 // #try_call_return;
6540 // } else {
6541 // #call_return;
6542 // }
6543 Statement* call_return_carefully;
6544 {
6545 Expression* condition = factory->NewCompareOperation(
6546 Token::EQ_STRICT, factory->NewVariableProxy(completion),
6547 factory->NewSmiLiteral(THROW, nopos), nopos);
6548
6549 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos);
6550 then_block->statements()->Add(check_return_callable, zone);
6551 then_block->statements()->Add(try_call_return, zone);
6552
6553 call_return_carefully =
6554 factory->NewIfStatement(condition, then_block, call_return, nopos);
6555 }
6556
6557
6558 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
6559 Statement* validate_output;
6560 {
6561 Expression* is_receiver_call;
6562 {
6563 auto args = new (zone) ZoneList<Expression*>(1, zone);
6564 args->Add(factory->NewVariableProxy(var_output), zone);
6565 is_receiver_call =
6566 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
6567 }
6568
6569 Statement* throw_call;
6570 {
6571 auto args = new (zone) ZoneList<Expression*>(1, zone);
6572 args->Add(factory->NewVariableProxy(var_output), zone);
6573 Expression* call = factory->NewCallRuntime(
6574 Runtime::kThrowIteratorResultNotAnObject, args, nopos);
6575 throw_call = factory->NewExpressionStatement(call, nopos);
6576 }
6577
6578 validate_output = factory->NewIfStatement(
6579 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
6580 }
6581
6582
6583 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
6584 Statement* maybe_call_return;
6585 {
6586 Expression* condition = factory->NewCompareOperation(
6587 Token::EQ, factory->NewVariableProxy(var_return),
6588 factory->NewNullLiteral(nopos), nopos);
6589
6590 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6591 block->statements()->Add(call_return_carefully, zone);
6592 block->statements()->Add(validate_output, zone); // GAGA
6593
6594 maybe_call_return = factory->NewIfStatement(
6595 condition, factory->NewEmptyStatement(nopos), block, nopos);
6596 }
6597
6598
6599 statements->Add(get_return, zone);
6600 statements->Add(maybe_call_return, zone);
6601 }
6602
6603
6604 void ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
6605 //
6606 // This function replaces the loop's body with the following wrapping:
6607 //
6608 // let completion = RETURN_OR_BREAK;
6609 // try {
6610 // #body;
6611 // {{completion = NORMAL}};
6612 // } catch(e) {
6613 // completion = THROW;
6614 // throw e;
6615 // } finally {
6616 // if (completion !== NORMAL) {
6617 // #BuildIteratorClose(iterator, completion) // See above.
6618 // }
6619 // }
6620 //
6621
6622 const int nopos = RelocInfo::kNoPosition;
6623 auto factory = parser_->factory();
6624 auto avfactory = parser_->ast_value_factory();
6625 auto scope = parser_->scope_;
6626 auto zone = parser_->zone();
6627
6628
6629 // let completion = RETURN_OR_BREAK;
6630 Variable* var_completion = scope->NewTemporary(avfactory->empty_string());
6631 Statement* initialize_completion;
6632 {
6633 Expression* proxy = factory->NewVariableProxy(var_completion);
6634 Expression* assignment = factory->NewAssignment(
6635 Token::ASSIGN, proxy,
6636 factory->NewSmiLiteral(RETURN_OR_BREAK, nopos), nopos);
6637 initialize_completion =
6638 factory->NewExpressionStatement(assignment, nopos);
6639 }
6640
6641
6642 // {{completion = NORMAL}}
6643 Statement* set_completion_normal;
6644 {
6645 Expression* proxy = factory->NewVariableProxy(var_completion);
6646 Expression* assignment = factory->NewAssignment(
6647 Token::ASSIGN, proxy, factory->NewSmiLiteral(NORMAL, nopos), nopos);
6648
6649 Block* block = factory->NewBlock(nullptr, 1, true, nopos);
6650 block->statements()->Add(
6651 factory->NewExpressionStatement(assignment, nopos), zone);
6652 set_completion_normal = block;
6653 }
6654
6655
6656 // completion = THROW;
6657 Statement* set_completion_throw;
6658 {
6659 Expression* proxy = factory->NewVariableProxy(var_completion);
6660 Expression* assignment = factory->NewAssignment(
6661 Token::ASSIGN, proxy, factory->NewSmiLiteral(THROW, nopos), nopos);
6662 set_completion_throw = factory->NewExpressionStatement(assignment, nopos);
6663 }
6664
6665
6666 // #body;
6667 // #set_completion_normal;
6668 Block* try_block;
6669 {
6670 try_block = factory->NewBlock(nullptr, 2, false, nopos);
6671 try_block->statements()->Add(loop->body(), zone);
6672 try_block->statements()->Add(set_completion_normal, zone);
6673 }
6674
6675
6676 // if (completion !== NORMAL) {
6677 // #BuildIteratorClose
6678 // }
6679 Block* maybe_close;
6680 {
6681 Expression* condition = factory->NewCompareOperation(
6682 Token::EQ_STRICT, factory->NewVariableProxy(var_completion),
6683 factory->NewSmiLiteral(NORMAL, nopos), nopos);
6684
6685 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6686 BuildIteratorClose(
6687 block->statements(), loop->iterator(), var_completion);
6688 DCHECK(block->statements()->length() == 2);
6689
6690 maybe_close = factory->NewBlock(nullptr, 1, false, nopos);
6691 maybe_close->statements()->Add(factory->NewIfStatement(
6692 condition, factory->NewEmptyStatement(nopos), block, nopos), zone);
6693 }
6694
6695
6696 // try { #try_block }
6697 // catch(e) {
6698 // #set_completion_throw;
6699 // throw e;
6700 // }
6701 Statement* try_catch;
6702 {
6703 Block* catch_block;
6704 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6705 Variable* catch_variable = catch_scope->DeclareLocal(
6706 avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6707 Variable::NORMAL);
6708
6709 Statement* rethrow;
6710 {
6711 Expression* proxy = factory->NewVariableProxy(catch_variable);
6712 rethrow = factory->NewExpressionStatement(
6713 factory->NewThrow(proxy, nopos), nopos);
6714 }
6715
6716 catch_block = factory->NewBlock(nullptr, 2, false, nopos);
6717 catch_block->statements()->Add(set_completion_throw, zone);
6718 catch_block->statements()->Add(rethrow, zone);
6719
6720 try_catch = factory->NewTryCatchStatement(
6721 try_block, catch_scope, catch_variable, catch_block, nopos);
6722 }
6723
6724
6725 // try { #try_catch } finally { #maybe_close }
6726 Statement* try_finally;
6727 {
6728 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6729 try_block->statements()->Add(try_catch, zone);
6730
6731 try_finally =
6732 factory->NewTryFinallyStatement(try_block, maybe_close, nopos);
6733 }
6734
6735
6736 // #initialize_completion;
6737 // #try_finally;
6738 Statement* new_body;
6739 {
6740 Block* block = factory->NewBlock(nullptr, 2, false, nopos);
6741 block->statements()->Add(initialize_completion, zone);
6742 block->statements()->Add(try_finally, zone);
6743 new_body = block;
6744 }
6745
6746
6747 loop->set_body(new_body);
6748 }
6749
6750
6390 } // namespace internal 6751 } // namespace internal
6391 } // namespace v8 6752 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698