| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #include "src/parsing/parser.h" |     5 #include "src/parsing/parser.h" | 
|     6  |     6  | 
|     7 #include "src/api.h" |     7 #include "src/api.h" | 
|     8 #include "src/ast/ast.h" |     8 #include "src/ast/ast.h" | 
|     9 #include "src/ast/ast-expression-rewriter.h" |     9 #include "src/ast/ast-expression-rewriter.h" | 
|    10 #include "src/ast/ast-expression-visitor.h" |    10 #include "src/ast/ast-expression-visitor.h" | 
| (...skipping 6545 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6556         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |  6556         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); | 
|  6557   } |  6557   } | 
|  6558  |  6558  | 
|  6559   statements->Add(get_return, zone); |  6559   statements->Add(get_return, zone); | 
|  6560   statements->Add(check_return, zone); |  6560   statements->Add(check_return, zone); | 
|  6561   statements->Add(call_return, zone); |  6561   statements->Add(call_return, zone); | 
|  6562   statements->Add(validate_output, zone); |  6562   statements->Add(validate_output, zone); | 
|  6563 } |  6563 } | 
|  6564  |  6564  | 
|  6565  |  6565  | 
|  6566 // Runtime encoding of different completion modes. |  6566 void ParserTraits::FinalizeIteratorUse( | 
|  6567 enum ForOfLoopBodyCompletion { BODY_COMPLETED, BODY_ABORTED, BODY_THREW }; |  6567     Variable* completion, Expression* condition, Variable* iter, | 
 |  6568     Block* iterator_use, Block* target) { | 
 |  6569   if (!FLAG_harmony_iterator_close) return; | 
 |  6570  | 
 |  6571   // | 
 |  6572   // This function adds two statements to [target], corresponding to the | 
 |  6573   // following code: | 
 |  6574   // | 
 |  6575   //   completion = NORMAL; | 
 |  6576   //   try { | 
 |  6577   //     try { | 
 |  6578   //       iterator_use | 
 |  6579   //     } catch(e) { | 
 |  6580   //       if (completion === ABRUPT) completion = THROW; | 
 |  6581   //       throw e; | 
 |  6582   //     } | 
 |  6583   //   } finally { | 
 |  6584   //     if (condition) { | 
 |  6585   //       #BuildIteratorCloseForCompletion(iter, completion) | 
 |  6586   //     } | 
 |  6587   //   } | 
 |  6588   // | 
 |  6589  | 
 |  6590   const int nopos = RelocInfo::kNoPosition; | 
 |  6591   auto factory = parser_->factory(); | 
 |  6592   auto avfactory = parser_->ast_value_factory(); | 
 |  6593   auto scope = parser_->scope_; | 
 |  6594   auto zone = parser_->zone(); | 
 |  6595  | 
 |  6596   // completion = NORMAL; | 
 |  6597   Statement* initialize_completion; | 
 |  6598   { | 
 |  6599     Expression* proxy = factory->NewVariableProxy(completion); | 
 |  6600     Expression* assignment = factory->NewAssignment( | 
 |  6601         Token::ASSIGN, proxy, | 
 |  6602         factory->NewSmiLiteral(Parser::NORMAL, nopos), nopos); | 
 |  6603     initialize_completion = | 
 |  6604         factory->NewExpressionStatement(assignment, nopos); | 
 |  6605   } | 
 |  6606  | 
 |  6607   // if (completion === ABRUPT) completion = THROW; | 
 |  6608   Statement* set_completion_throw; | 
 |  6609   { | 
 |  6610     Expression* condition = factory->NewCompareOperation( | 
 |  6611         Token::EQ_STRICT, factory->NewVariableProxy(completion), | 
 |  6612         factory->NewSmiLiteral(Parser::ABRUPT, nopos), nopos); | 
 |  6613  | 
 |  6614     Expression* proxy = factory->NewVariableProxy(completion); | 
 |  6615     Expression* assignment = factory->NewAssignment( | 
 |  6616         Token::ASSIGN, proxy, factory->NewSmiLiteral(Parser::THROW, nopos), | 
 |  6617         nopos); | 
 |  6618     Statement* statement = factory->NewExpressionStatement(assignment, nopos); | 
 |  6619     set_completion_throw = factory->NewIfStatement( | 
 |  6620         condition, statement, factory->NewEmptyStatement(nopos), nopos); | 
 |  6621   } | 
 |  6622  | 
 |  6623   // if (condition) { | 
 |  6624   //   #BuildIteratorCloseForCompletion(iter, completion) | 
 |  6625   // } | 
 |  6626   Block* maybe_close; | 
 |  6627   { | 
 |  6628     Block* block = factory->NewBlock(nullptr, 2, true, nopos); | 
 |  6629     parser_->BuildIteratorCloseForCompletion( | 
 |  6630         block->statements(), iter, completion); | 
 |  6631     DCHECK(block->statements()->length() == 2); | 
 |  6632  | 
 |  6633     maybe_close = factory->NewBlock(nullptr, 1, true, nopos); | 
 |  6634     maybe_close->statements()->Add(factory->NewIfStatement( | 
 |  6635         condition, block, factory->NewEmptyStatement(nopos), nopos), zone); | 
 |  6636   } | 
 |  6637  | 
 |  6638   // try { #try_block } | 
 |  6639   // catch(e) { | 
 |  6640   //   #set_completion_throw; | 
 |  6641   //   throw e; | 
 |  6642   // } | 
 |  6643   Statement* try_catch; | 
 |  6644   { | 
 |  6645     Scope* catch_scope = parser_->NewScope(scope, CATCH_SCOPE); | 
 |  6646     Variable* catch_variable = catch_scope->DeclareLocal( | 
 |  6647         avfactory->dot_catch_string(), VAR, kCreatedInitialized, | 
 |  6648         Variable::NORMAL); | 
 |  6649  | 
 |  6650     Statement* rethrow; | 
 |  6651     { | 
 |  6652       Expression* proxy = factory->NewVariableProxy(catch_variable); | 
 |  6653       rethrow = factory->NewExpressionStatement( | 
 |  6654           factory->NewThrow(proxy, nopos), nopos); | 
 |  6655     } | 
 |  6656  | 
 |  6657     Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos); | 
 |  6658     catch_block->statements()->Add(set_completion_throw, zone); | 
 |  6659     catch_block->statements()->Add(rethrow, zone); | 
 |  6660  | 
 |  6661     try_catch = factory->NewTryCatchStatement( | 
 |  6662         iterator_use, catch_scope, catch_variable, catch_block, nopos); | 
 |  6663   } | 
 |  6664  | 
 |  6665   // try { #try_catch } finally { #maybe_close } | 
 |  6666   Statement* try_finally; | 
 |  6667   { | 
 |  6668     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | 
 |  6669     try_block->statements()->Add(try_catch, zone); | 
 |  6670  | 
 |  6671     try_finally = | 
 |  6672         factory->NewTryFinallyStatement(try_block, maybe_close, nopos); | 
 |  6673   } | 
 |  6674  | 
 |  6675   target->statements()->Add(initialize_completion, zone); | 
 |  6676   target->statements()->Add(try_finally, zone); | 
 |  6677 } | 
 |  6678  | 
|  6568  |  6679  | 
|  6569 void ParserTraits::BuildIteratorCloseForCompletion( |  6680 void ParserTraits::BuildIteratorCloseForCompletion( | 
|  6570     ZoneList<Statement*>* statements, Variable* iterator, |  6681     ZoneList<Statement*>* statements, Variable* iterator, | 
|  6571     Variable* completion) { |  6682     Variable* completion) { | 
|  6572   // |  6683   // | 
|  6573   // This function adds two statements to [statements], corresponding to the |  6684   // This function adds two statements to [statements], corresponding to the | 
|  6574   // following code: |  6685   // following code: | 
|  6575   // |  6686   // | 
|  6576   //   let iteratorReturn = iterator.return; |  6687   //   let iteratorReturn = iterator.return; | 
|  6577   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |  6688   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 
|  6578   //     if (completion === BODY_THREW) { |  6689   //     if (completion === THROW) { | 
|  6579   //       if (!IS_CALLABLE(iteratorReturn)) { |  6690   //       if (!IS_CALLABLE(iteratorReturn)) { | 
|  6580   //         throw MakeTypeError(kReturnMethodNotCallable); |  6691   //         throw MakeTypeError(kReturnMethodNotCallable); | 
|  6581   //       } |  6692   //       } | 
|  6582   //       try { %_Call(iteratorReturn, iterator) } catch (_) { } |  6693   //       try { %_Call(iteratorReturn, iterator) } catch (_) { } | 
|  6583   //     } else { |  6694   //     } else { | 
|  6584   //       let output = %_Call(iteratorReturn, iterator); |  6695   //       let output = %_Call(iteratorReturn, iterator); | 
|  6585   //       if (!IS_RECEIVER(output)) { |  6696   //       if (!IS_RECEIVER(output)) { | 
|  6586   //         %ThrowIterResultNotAnObject(output); |  6697   //         %ThrowIterResultNotAnObject(output); | 
|  6587   //       } |  6698   //       } | 
|  6588   //     } |  6699   //     } | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6686     } |  6797     } | 
|  6687  |  6798  | 
|  6688     Statement* check_return = factory->NewIfStatement( |  6799     Statement* check_return = factory->NewIfStatement( | 
|  6689         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); |  6800         is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); | 
|  6690  |  6801  | 
|  6691     validate_return = factory->NewBlock(nullptr, 2, false, nopos); |  6802     validate_return = factory->NewBlock(nullptr, 2, false, nopos); | 
|  6692     validate_return->statements()->Add(call_return, zone); |  6803     validate_return->statements()->Add(call_return, zone); | 
|  6693     validate_return->statements()->Add(check_return, zone); |  6804     validate_return->statements()->Add(check_return, zone); | 
|  6694   } |  6805   } | 
|  6695  |  6806  | 
|  6696   // if (completion === BODY_THREW) { |  6807   // if (completion === THROW) { | 
|  6697   //   #check_return_callable; |  6808   //   #check_return_callable; | 
|  6698   //   #try_call_return; |  6809   //   #try_call_return; | 
|  6699   // } else { |  6810   // } else { | 
|  6700   //   #validate_return; |  6811   //   #validate_return; | 
|  6701   // } |  6812   // } | 
|  6702   Statement* call_return_carefully; |  6813   Statement* call_return_carefully; | 
|  6703   { |  6814   { | 
|  6704     Expression* condition = factory->NewCompareOperation( |  6815     Expression* condition = factory->NewCompareOperation( | 
|  6705         Token::EQ_STRICT, factory->NewVariableProxy(completion), |  6816         Token::EQ_STRICT, factory->NewVariableProxy(completion), | 
|  6706         factory->NewSmiLiteral(BODY_THREW, nopos), nopos); |  6817         factory->NewSmiLiteral(Parser::THROW, nopos), nopos); | 
|  6707  |  6818  | 
|  6708     Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); |  6819     Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); | 
|  6709     then_block->statements()->Add(check_return_callable, zone); |  6820     then_block->statements()->Add(check_return_callable, zone); | 
|  6710     then_block->statements()->Add(try_call_return, zone); |  6821     then_block->statements()->Add(try_call_return, zone); | 
|  6711  |  6822  | 
|  6712     call_return_carefully = |  6823     call_return_carefully = | 
|  6713         factory->NewIfStatement(condition, then_block, validate_return, nopos); |  6824         factory->NewIfStatement(condition, then_block, validate_return, nopos); | 
|  6714   } |  6825   } | 
|  6715  |  6826  | 
|  6716   // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } |  6827   // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  6730   statements->Add(maybe_call_return, zone); |  6841   statements->Add(maybe_call_return, zone); | 
|  6731 } |  6842 } | 
|  6732  |  6843  | 
|  6733  |  6844  | 
|  6734 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { |  6845 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { | 
|  6735   if (!FLAG_harmony_iterator_close) return loop; |  6846   if (!FLAG_harmony_iterator_close) return loop; | 
|  6736  |  6847  | 
|  6737   // |  6848   // | 
|  6738   // This function replaces the loop with the following wrapping: |  6849   // This function replaces the loop with the following wrapping: | 
|  6739   // |  6850   // | 
|  6740   //   let completion = BODY_COMPLETED; |  | 
|  6741   //   let each; |  6851   //   let each; | 
 |  6852   //   let completion = NORMAL; | 
|  6742   //   try { |  6853   //   try { | 
|  6743   //     #loop; |  6854   //     try { | 
|  6744   //   } catch(e) { |  6855   //       #loop; | 
|  6745   //     if (completion === BODY_ABORTED) completion = BODY_THREW; |  6856   //     } catch(e) { | 
|  6746   //     throw e; |  6857   //       if (completion === ABRUPT) completion = THROW; | 
 |  6858   //       throw e; | 
 |  6859   //     } | 
|  6747   //   } finally { |  6860   //   } finally { | 
|  6748   //     if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) { |  6861   //     if (!(completion === NORMAL || IS_UNDEFINED(#iterator))) { | 
|  6749   //       #BuildIteratorCloseForCompletion(#iterator, completion) |  6862   //       #BuildIteratorCloseForCompletion(#iterator, completion) | 
|  6750   //     } |  6863   //     } | 
|  6751   //   } |  6864   //   } | 
|  6752   // |  6865   // | 
|  6753   // where the loop's body is wrapped as follows: |  6866   // where the loop's body is wrapped as follows: | 
|  6754   // |  6867   // | 
|  6755   //   { |  6868   //   { | 
|  6756   //     #loop-body |  6869   //     #loop-body | 
|  6757   //     {{completion = BODY_COMPLETED;}} |  6870   //     {{completion = NORMAL;}} | 
|  6758   //   } |  6871   //   } | 
|  6759   // |  6872   // | 
|  6760   // and assign_each is wrapped as follows |  6873   // and the loop's assign_each is wrapped as follows | 
|  6761   // |  6874   // | 
|  6762   //   do { |  6875   //   do { | 
|  6763   //     {{completion = BODY_ABORTED;}} |  6876   //     {{completion = ABRUPT;}} | 
|  6764   //     #assign-each |  6877   //     #assign-each | 
|  6765   //   } into each |  6878   //   } | 
 |  6879   // | 
|  6766  |  6880  | 
|  6767   const int nopos = RelocInfo::kNoPosition; |  6881   const int nopos = RelocInfo::kNoPosition; | 
|  6768   auto factory = parser_->factory(); |  6882   auto factory = parser_->factory(); | 
|  6769   auto avfactory = parser_->ast_value_factory(); |  6883   auto avfactory = parser_->ast_value_factory(); | 
|  6770   auto scope = parser_->scope_; |  6884   auto scope = parser_->scope_; | 
|  6771   auto zone = parser_->zone(); |  6885   auto zone = parser_->zone(); | 
|  6772  |  6886  | 
|  6773   // let completion = BODY_COMPLETED; |  | 
|  6774   Variable* var_completion = scope->NewTemporary(avfactory->empty_string()); |  6887   Variable* var_completion = scope->NewTemporary(avfactory->empty_string()); | 
|  6775   Statement* initialize_completion; |  | 
|  6776   { |  | 
|  6777     Expression* proxy = factory->NewVariableProxy(var_completion); |  | 
|  6778     Expression* assignment = factory->NewAssignment( |  | 
|  6779         Token::ASSIGN, proxy, |  | 
|  6780         factory->NewSmiLiteral(BODY_COMPLETED, nopos), nopos); |  | 
|  6781     initialize_completion = |  | 
|  6782         factory->NewExpressionStatement(assignment, nopos); |  | 
|  6783   } |  | 
|  6784  |  6888  | 
|  6785   // let each; |  6889   // let each; | 
|  6786   Variable* var_each = scope->NewTemporary(avfactory->empty_string()); |  6890   Variable* var_each = scope->NewTemporary(avfactory->empty_string()); | 
|  6787   Statement* initialize_each; |  6891   Statement* initialize_each; | 
|  6788   { |  6892   { | 
|  6789     Expression* proxy = factory->NewVariableProxy(var_each); |  6893     Expression* proxy = factory->NewVariableProxy(var_each); | 
|  6790     Expression* assignment = factory->NewAssignment( |  6894     Expression* assignment = factory->NewAssignment( | 
|  6791         Token::ASSIGN, proxy, |  6895         Token::ASSIGN, proxy, | 
|  6792         factory->NewUndefinedLiteral(nopos), nopos); |  6896         factory->NewUndefinedLiteral(nopos), nopos); | 
|  6793     initialize_each = |  6897     initialize_each = | 
|  6794         factory->NewExpressionStatement(assignment, nopos); |  6898         factory->NewExpressionStatement(assignment, nopos); | 
|  6795   } |  6899   } | 
|  6796  |  6900  | 
|  6797   // if (completion === BODY_ABORTED) completion = BODY_THREW; |  6901   // !(completion === NORMAL || IS_UNDEFINED(#iterator)) | 
|  6798   Statement* set_completion_throw; |  6902   Expression* closing_condition; | 
|  6799   { |  6903   { | 
|  6800     Expression* condition = factory->NewCompareOperation( |  6904     Expression* lhs = factory->NewCompareOperation( | 
|  6801         Token::EQ_STRICT, factory->NewVariableProxy(var_completion), |  6905         Token::EQ_STRICT, factory->NewVariableProxy(var_completion), | 
|  6802         factory->NewSmiLiteral(BODY_ABORTED, nopos), nopos); |  6906         factory->NewSmiLiteral(Parser::NORMAL, nopos), nopos); | 
|  6803  |  6907     Expression* rhs = factory->NewCompareOperation( | 
|  6804     Expression* proxy = factory->NewVariableProxy(var_completion); |  6908         Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()), | 
|  6805     Expression* assignment = factory->NewAssignment( |  6909         factory->NewUndefinedLiteral(nopos), nopos); | 
|  6806         Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_THREW, nopos), |  6910     closing_condition = factory->NewUnaryOperation( | 
 |  6911         Token::NOT, | 
 |  6912         factory->NewBinaryOperation(Token::OR, lhs, rhs, nopos), | 
|  6807         nopos); |  6913         nopos); | 
|  6808     Statement* statement = factory->NewExpressionStatement(assignment, nopos); |  | 
|  6809     set_completion_throw = factory->NewIfStatement( |  | 
|  6810         condition, statement, factory->NewEmptyStatement(nopos), nopos); |  | 
|  6811   } |  6914   } | 
|  6812  |  6915  | 
|  6813   // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) { |  6916   // {{completion = NORMAL;}} | 
|  6814   //   #BuildIteratorCloseForCompletion(#iterator, completion) |  | 
|  6815   // } |  | 
|  6816   Block* maybe_close; |  | 
|  6817   { |  | 
|  6818     Expression* condition1 = factory->NewCompareOperation( |  | 
|  6819         Token::EQ_STRICT, factory->NewVariableProxy(var_completion), |  | 
|  6820         factory->NewSmiLiteral(BODY_COMPLETED, nopos), nopos); |  | 
|  6821     Expression* condition2 = factory->NewCompareOperation( |  | 
|  6822         Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()), |  | 
|  6823         factory->NewUndefinedLiteral(nopos), nopos); |  | 
|  6824     Expression* condition = factory->NewBinaryOperation( |  | 
|  6825         Token::OR, condition1, condition2, nopos); |  | 
|  6826  |  | 
|  6827     Block* block = factory->NewBlock(nullptr, 2, false, nopos); |  | 
|  6828     BuildIteratorCloseForCompletion( |  | 
|  6829         block->statements(), loop->iterator(), var_completion); |  | 
|  6830     DCHECK(block->statements()->length() == 2); |  | 
|  6831  |  | 
|  6832     maybe_close = factory->NewBlock(nullptr, 1, false, nopos); |  | 
|  6833     maybe_close->statements()->Add(factory->NewIfStatement( |  | 
|  6834         condition, factory->NewEmptyStatement(nopos), block, nopos), zone); |  | 
|  6835   } |  | 
|  6836  |  | 
|  6837   // try { #try_block } |  | 
|  6838   // catch(e) { |  | 
|  6839   //   #set_completion_throw; |  | 
|  6840   //   throw e; |  | 
|  6841   // } |  | 
|  6842   Statement* try_catch; |  | 
|  6843   { |  | 
|  6844     Scope* catch_scope = NewScope(scope, CATCH_SCOPE); |  | 
|  6845     Variable* catch_variable = catch_scope->DeclareLocal( |  | 
|  6846         avfactory->dot_catch_string(), VAR, kCreatedInitialized, |  | 
|  6847         Variable::NORMAL); |  | 
|  6848  |  | 
|  6849     Statement* rethrow; |  | 
|  6850     { |  | 
|  6851       Expression* proxy = factory->NewVariableProxy(catch_variable); |  | 
|  6852       rethrow = factory->NewExpressionStatement( |  | 
|  6853           factory->NewThrow(proxy, nopos), nopos); |  | 
|  6854     } |  | 
|  6855  |  | 
|  6856     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); |  | 
|  6857     try_block->statements()->Add(loop, zone); |  | 
|  6858  |  | 
|  6859     Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos); |  | 
|  6860     catch_block->statements()->Add(set_completion_throw, zone); |  | 
|  6861     catch_block->statements()->Add(rethrow, zone); |  | 
|  6862  |  | 
|  6863     try_catch = factory->NewTryCatchStatement( |  | 
|  6864         try_block, catch_scope, catch_variable, catch_block, nopos); |  | 
|  6865   } |  | 
|  6866  |  | 
|  6867   // try { #try_catch } finally { #maybe_close } |  | 
|  6868   Statement* try_finally; |  | 
|  6869   { |  | 
|  6870     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); |  | 
|  6871     try_block->statements()->Add(try_catch, zone); |  | 
|  6872  |  | 
|  6873     try_finally = |  | 
|  6874         factory->NewTryFinallyStatement(try_block, maybe_close, nopos); |  | 
|  6875   } |  | 
|  6876  |  | 
|  6877   // #initialize_completion; |  | 
|  6878   // #initialize_each; |  | 
|  6879   // #try_finally; |  | 
|  6880   Statement* final_loop; |  | 
|  6881   { |  | 
|  6882     Block* block = factory->NewBlock(nullptr, 2, false, nopos); |  | 
|  6883     block->statements()->Add(initialize_completion, zone); |  | 
|  6884     block->statements()->Add(initialize_each, zone); |  | 
|  6885     block->statements()->Add(try_finally, zone); |  | 
|  6886     final_loop = block; |  | 
|  6887   } |  | 
|  6888  |  | 
|  6889   // {{completion = BODY_COMPLETED;}} |  | 
|  6890   Statement* set_completion_normal; |  6917   Statement* set_completion_normal; | 
|  6891   { |  6918   { | 
|  6892     Expression* proxy = factory->NewVariableProxy(var_completion); |  6919     Expression* proxy = factory->NewVariableProxy(var_completion); | 
|  6893     Expression* assignment = factory->NewAssignment( |  6920     Expression* assignment = factory->NewAssignment( | 
|  6894         Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_COMPLETED, nopos), |  6921         Token::ASSIGN, proxy, factory->NewSmiLiteral(Parser::NORMAL, nopos), | 
|  6895         nopos); |  6922         nopos); | 
|  6896  |  6923  | 
|  6897     Block* block = factory->NewBlock(nullptr, 1, true, nopos); |  6924     Block* block = factory->NewBlock(nullptr, 1, true, nopos); | 
|  6898     block->statements()->Add( |  6925     block->statements()->Add( | 
|  6899         factory->NewExpressionStatement(assignment, nopos), zone); |  6926         factory->NewExpressionStatement(assignment, nopos), zone); | 
|  6900     set_completion_normal = block; |  6927     set_completion_normal = block; | 
|  6901   } |  6928   } | 
|  6902  |  6929  | 
|  6903   // { #loop-body; #set_completion_normal } |  6930   // {{completion = ABRUPT;}} | 
|  6904   Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); |  6931   Statement* set_completion_abrupt; | 
|  6905   new_body->statements()->Add(loop->body(), zone); |  | 
|  6906   new_body->statements()->Add(set_completion_normal, zone); |  | 
|  6907  |  | 
|  6908   loop->set_body(new_body); |  | 
|  6909  |  | 
|  6910   // {{completion = BODY_ABORTED;}} |  | 
|  6911   Statement* set_completion_break; |  | 
|  6912   { |  6932   { | 
|  6913     Expression* proxy = factory->NewVariableProxy(var_completion); |  6933     Expression* proxy = factory->NewVariableProxy(var_completion); | 
|  6914     Expression* assignment = factory->NewAssignment( |  6934     Expression* assignment = factory->NewAssignment( | 
|  6915         Token::ASSIGN, proxy, factory->NewSmiLiteral(BODY_ABORTED, nopos), |  6935         Token::ASSIGN, proxy, factory->NewSmiLiteral(Parser::ABRUPT, nopos), | 
|  6916         nopos); |  6936         nopos); | 
|  6917  |  6937  | 
|  6918     Block* block = factory->NewBlock(nullptr, 1, true, nopos); |  6938     Block* block = factory->NewBlock(nullptr, 1, true, nopos); | 
|  6919     block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), |  6939     block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), | 
|  6920                              zone); |  6940                              zone); | 
|  6921     set_completion_break = block; |  6941     set_completion_abrupt = block; | 
|  6922   } |  6942   } | 
|  6923  |  6943  | 
|  6924   // { #set_completion_break; #assign-each } |  6944   // { #loop-body; #set_completion_normal } | 
 |  6945   Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); | 
 |  6946   { | 
 |  6947     new_body->statements()->Add(loop->body(), zone); | 
 |  6948     new_body->statements()->Add(set_completion_normal, zone); | 
 |  6949   } | 
 |  6950  | 
 |  6951   // { #set_completion_abrupt; #assign-each } | 
|  6925   Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); |  6952   Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); | 
|  6926   new_assign_each->statements()->Add(set_completion_break, zone); |  6953   { | 
|  6927   new_assign_each->statements()->Add( |  6954     new_assign_each->statements()->Add(set_completion_abrupt, zone); | 
|  6928       factory->NewExpressionStatement(loop->assign_each(), nopos), zone); |  6955     new_assign_each->statements()->Add( | 
 |  6956         factory->NewExpressionStatement(loop->assign_each(), nopos), zone); | 
 |  6957   } | 
|  6929  |  6958  | 
|  6930   Expression* do_each = |  6959   // Now put things together. | 
|  6931       factory->NewDoExpression(new_assign_each, var_each, nopos); |  6960  | 
|  6932   loop->set_assign_each(do_each); |  6961   loop->set_body(new_body); | 
 |  6962   loop->set_assign_each( | 
 |  6963       factory->NewDoExpression(new_assign_each, var_each, nopos)); | 
 |  6964  | 
 |  6965   Statement* final_loop; | 
 |  6966   { | 
 |  6967     Block* target = factory->NewBlock(nullptr, 3, false, nopos); | 
 |  6968     target->statements()->Add(initialize_each, zone); | 
 |  6969  | 
 |  6970     Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); | 
 |  6971     try_block->statements()->Add(loop, zone); | 
 |  6972  | 
 |  6973     FinalizeIteratorUse( | 
 |  6974         var_completion, closing_condition, loop->iterator(), try_block, target); | 
 |  6975     final_loop = target; | 
 |  6976   } | 
|  6933  |  6977  | 
|  6934   return final_loop; |  6978   return final_loop; | 
|  6935 } |  6979 } | 
|  6936  |  6980  | 
|  6937  |  6981  | 
|  6938 }  // namespace internal |  6982 }  // namespace internal | 
|  6939 }  // namespace v8 |  6983 }  // namespace v8 | 
| OLD | NEW |