| 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 6000 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6011 // | 6011 // | 
| 6012 //     if (mode === kReturn) { | 6012 //     if (mode === kReturn) { | 
| 6013 //       return {value: output.value, done: true}; | 6013 //       return {value: output.value, done: true}; | 
| 6014 //     } | 6014 //     } | 
| 6015 //     output.value | 6015 //     output.value | 
| 6016 //   } | 6016 //   } | 
| 6017 // | 6017 // | 
| 6018 // IteratorClose(iterator) expands to the following: | 6018 // IteratorClose(iterator) expands to the following: | 
| 6019 // | 6019 // | 
| 6020 //   let iteratorReturn = iterator.return; | 6020 //   let iteratorReturn = iterator.return; | 
| 6021 //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return; | 6021 //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 
| 6022 //   let output = %_Call(iteratorReturn, iterator); | 6022 //     let output = %_Call(iteratorReturn, iterator); | 
| 6023 //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 6023 //     if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 
|  | 6024 //   } | 
| 6024 // | 6025 // | 
| 6025 // IteratorClose(iterator, input, output) expands to the following: | 6026 // IteratorClose(iterator, input, output) expands to the following: | 
| 6026 // | 6027 // | 
| 6027 //   let iteratorReturn = iterator.return; | 6028 //   let iteratorReturn = iterator.return; | 
| 6028 //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; | 6029 //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; | 
| 6029 //   output = %_Call(iteratorReturn, iterator, input); | 6030 //   output = %_Call(iteratorReturn, iterator, input); | 
| 6030 //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 6031 //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 
| 6031 | 6032 | 
| 6032 |  | 
| 6033 Expression* ParserTraits::RewriteYieldStar( | 6033 Expression* ParserTraits::RewriteYieldStar( | 
| 6034     Expression* generator, Expression* iterable, int pos) { | 6034     Expression* generator, Expression* iterable, int pos) { | 
| 6035 | 6035 | 
| 6036   const int nopos = RelocInfo::kNoPosition; | 6036   const int nopos = RelocInfo::kNoPosition; | 
| 6037 | 6037 | 
| 6038   auto factory = parser_->factory(); | 6038   auto factory = parser_->factory(); | 
| 6039   auto avfactory = parser_->ast_value_factory(); | 6039   auto avfactory = parser_->ast_value_factory(); | 
| 6040   auto scope = parser_->scope_; | 6040   auto scope = parser_->scope_; | 
| 6041   auto zone = parser_->zone(); | 6041   auto zone = parser_->zone(); | 
| 6042 | 6042 | 
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6185     Expression* condition = factory->NewCompareOperation( | 6185     Expression* condition = factory->NewCompareOperation( | 
| 6186         Token::EQ, factory->NewVariableProxy(var_throw), | 6186         Token::EQ, factory->NewVariableProxy(var_throw), | 
| 6187         factory->NewNullLiteral(nopos), nopos); | 6187         factory->NewNullLiteral(nopos), nopos); | 
| 6188 | 6188 | 
| 6189     Expression* call = NewThrowTypeError( | 6189     Expression* call = NewThrowTypeError( | 
| 6190         MessageTemplate::kThrowMethodMissing, | 6190         MessageTemplate::kThrowMethodMissing, | 
| 6191         avfactory->empty_string(), nopos); | 6191         avfactory->empty_string(), nopos); | 
| 6192     Statement* throw_call = factory->NewExpressionStatement(call, nopos); | 6192     Statement* throw_call = factory->NewExpressionStatement(call, nopos); | 
| 6193 | 6193 | 
| 6194     Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); | 6194     Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); | 
| 6195     Variable* var_tmp = scope->NewTemporary(avfactory->empty_string()); | 6195     parser_->BuildIteratorCloseForCompletion( | 
| 6196     BuildIteratorClose(then->statements(), var_iterator, Nothing<Variable*>(), | 6196         then->statements(), var_iterator, | 
| 6197                        var_tmp); | 6197         factory->NewSmiLiteral(Parser::kNormalCompletion, nopos)); | 
| 6198     then->statements()->Add(throw_call, zone); | 6198     then->statements()->Add(throw_call, zone); | 
| 6199     check_throw = factory->NewIfStatement( | 6199     check_throw = factory->NewIfStatement( | 
| 6200         condition, then, factory->NewEmptyStatement(nopos), nopos); | 6200         condition, then, factory->NewEmptyStatement(nopos), nopos); | 
| 6201   } | 6201   } | 
| 6202 | 6202 | 
| 6203 | 6203 | 
| 6204   // output = %_Call(iteratorThrow, iterator, input); | 6204   // output = %_Call(iteratorThrow, iterator, input); | 
| 6205   Statement* call_throw; | 6205   Statement* call_throw; | 
| 6206   { | 6206   { | 
| 6207     auto args = new (zone) ZoneList<Expression*>(3, zone); | 6207     auto args = new (zone) ZoneList<Expression*>(3, zone); | 
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6384 | 6384 | 
| 6385   // switch (mode) { ... } | 6385   // switch (mode) { ... } | 
| 6386   SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); | 6386   SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); | 
| 6387   { | 6387   { | 
| 6388     auto case_next = new (zone) ZoneList<Statement*>(3, zone); | 6388     auto case_next = new (zone) ZoneList<Statement*>(3, zone); | 
| 6389     case_next->Add(call_next, zone); | 6389     case_next->Add(call_next, zone); | 
| 6390     case_next->Add(validate_next_output, zone); | 6390     case_next->Add(validate_next_output, zone); | 
| 6391     case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6391     case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 
| 6392 | 6392 | 
| 6393     auto case_return = new (zone) ZoneList<Statement*>(5, zone); | 6393     auto case_return = new (zone) ZoneList<Statement*>(5, zone); | 
| 6394     BuildIteratorClose(case_return, var_iterator, Just(var_input), var_output); | 6394     BuildIteratorClose(case_return, var_iterator, var_input, var_output); | 
| 6395     case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6395     case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 
| 6396 | 6396 | 
| 6397     auto case_throw = new (zone) ZoneList<Statement*>(5, zone); | 6397     auto case_throw = new (zone) ZoneList<Statement*>(5, zone); | 
| 6398     case_throw->Add(get_throw, zone); | 6398     case_throw->Add(get_throw, zone); | 
| 6399     case_throw->Add(check_throw, zone); | 6399     case_throw->Add(check_throw, zone); | 
| 6400     case_throw->Add(call_throw, zone); | 6400     case_throw->Add(call_throw, zone); | 
| 6401     case_throw->Add(validate_throw_output, zone); | 6401     case_throw->Add(validate_throw_output, zone); | 
| 6402     case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 6402     case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); | 
| 6403 | 6403 | 
| 6404     auto cases = new (zone) ZoneList<CaseClause*>(3, zone); | 6404     auto cases = new (zone) ZoneList<CaseClause*>(3, zone); | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6471 | 6471 | 
| 6472     Statement* throw_call = factory->NewExpressionStatement(error, pos); | 6472     Statement* throw_call = factory->NewExpressionStatement(error, pos); | 
| 6473 | 6473 | 
| 6474     validate_var = factory->NewIfStatement( | 6474     validate_var = factory->NewIfStatement( | 
| 6475         condition, factory->NewEmptyStatement(nopos), throw_call, nopos); | 6475         condition, factory->NewEmptyStatement(nopos), throw_call, nopos); | 
| 6476   } | 6476   } | 
| 6477   return validate_var; | 6477   return validate_var; | 
| 6478 } | 6478 } | 
| 6479 | 6479 | 
| 6480 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 6480 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, | 
| 6481                                       Variable* iterator, | 6481                                       Variable* iterator, Variable* input, | 
| 6482                                       Maybe<Variable*> input, |  | 
| 6483                                       Variable* var_output) { | 6482                                       Variable* var_output) { | 
| 6484   // | 6483   // | 
| 6485   // This function adds four statements to [statements], corresponding to the | 6484   // This function adds four statements to [statements], corresponding to the | 
| 6486   // following code: | 6485   // following code: | 
| 6487   // | 6486   // | 
| 6488   //   let iteratorReturn = iterator.return; | 6487   //   let iteratorReturn = iterator.return; | 
| 6489   //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 6488   //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 
| 6490   //     return {value: input, done: true}; | 6489   //     return {value: input, done: true}; | 
| 6491   //   } | 6490   //   } | 
| 6492   //   output = %_Call(iteratorReturn, iterator, input); | 6491   //   output = %_Call(iteratorReturn, iterator, input); | 
| 6493   //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 6492   //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 
| 6494   // | 6493   // | 
| 6495   // When the input variable is not given, the return statement becomes |  | 
| 6496   //   return {value: undefined, done: true}; |  | 
| 6497   // and %_Call has only two arguments: |  | 
| 6498   //   output = %_Call(iteratorReturn, iterator); |  | 
| 6499   // |  | 
| 6500   // The reason for allowing input is that BuildIteratorClose |  | 
| 6501   // can then be reused to handle the return case in yield*. |  | 
| 6502   // |  | 
| 6503 | 6494 | 
| 6504   const int nopos = RelocInfo::kNoPosition; | 6495   const int nopos = RelocInfo::kNoPosition; | 
| 6505   auto factory = parser_->factory(); | 6496   auto factory = parser_->factory(); | 
| 6506   auto avfactory = parser_->ast_value_factory(); | 6497   auto avfactory = parser_->ast_value_factory(); | 
| 6507   auto zone = parser_->zone(); | 6498   auto zone = parser_->zone(); | 
| 6508 | 6499 | 
| 6509   // let iteratorReturn = iterator.return; | 6500   // let iteratorReturn = iterator.return; | 
| 6510   Variable* var_return = var_output;  // Reusing the output variable. | 6501   Variable* var_return = var_output;  // Reusing the output variable. | 
| 6511   Statement* get_return; | 6502   Statement* get_return; | 
| 6512   { | 6503   { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 6523 | 6514 | 
| 6524   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 6515   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 
| 6525   //   return {value: input, done: true}; | 6516   //   return {value: input, done: true}; | 
| 6526   // } | 6517   // } | 
| 6527   Statement* check_return; | 6518   Statement* check_return; | 
| 6528   { | 6519   { | 
| 6529     Expression* condition = factory->NewCompareOperation( | 6520     Expression* condition = factory->NewCompareOperation( | 
| 6530         Token::EQ, factory->NewVariableProxy(var_return), | 6521         Token::EQ, factory->NewVariableProxy(var_return), | 
| 6531         factory->NewNullLiteral(nopos), nopos); | 6522         factory->NewNullLiteral(nopos), nopos); | 
| 6532 | 6523 | 
| 6533     Expression* value = input.IsJust() | 6524     Expression* value = factory->NewVariableProxy(input); | 
| 6534                             ? static_cast<Expression*>( |  | 
| 6535                                   factory->NewVariableProxy(input.FromJust())) |  | 
| 6536                             : factory->NewUndefinedLiteral(nopos); |  | 
| 6537 | 6525 | 
| 6538     Statement* return_input = | 6526     Statement* return_input = | 
| 6539         factory->NewReturnStatement(BuildIteratorResult(value, true), nopos); | 6527         factory->NewReturnStatement(BuildIteratorResult(value, true), nopos); | 
| 6540 | 6528 | 
| 6541     check_return = factory->NewIfStatement( | 6529     check_return = factory->NewIfStatement( | 
| 6542         condition, return_input, factory->NewEmptyStatement(nopos), nopos); | 6530         condition, return_input, factory->NewEmptyStatement(nopos), nopos); | 
| 6543   } | 6531   } | 
| 6544 | 6532 | 
| 6545   // output = %_Call(iteratorReturn, iterator, input); | 6533   // output = %_Call(iteratorReturn, iterator, input); | 
| 6546   Statement* call_return; | 6534   Statement* call_return; | 
| 6547   { | 6535   { | 
| 6548     auto args = new (zone) ZoneList<Expression*>(3, zone); | 6536     auto args = new (zone) ZoneList<Expression*>(3, zone); | 
| 6549     args->Add(factory->NewVariableProxy(var_return), zone); | 6537     args->Add(factory->NewVariableProxy(var_return), zone); | 
| 6550     args->Add(factory->NewVariableProxy(iterator), zone); | 6538     args->Add(factory->NewVariableProxy(iterator), zone); | 
| 6551     if (input.IsJust()) { | 6539     args->Add(factory->NewVariableProxy(input), zone); | 
| 6552       args->Add(factory->NewVariableProxy(input.FromJust()), zone); |  | 
| 6553     } |  | 
| 6554 | 6540 | 
| 6555     Expression* call = | 6541     Expression* call = | 
| 6556         factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 6542         factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 
| 6557     Expression* output_proxy = factory->NewVariableProxy(var_output); | 6543     Expression* output_proxy = factory->NewVariableProxy(var_output); | 
| 6558     Expression* assignment = factory->NewAssignment( | 6544     Expression* assignment = factory->NewAssignment( | 
| 6559         Token::ASSIGN, output_proxy, call, nopos); | 6545         Token::ASSIGN, output_proxy, call, nopos); | 
| 6560     call_return = factory->NewExpressionStatement(assignment, nopos); | 6546     call_return = factory->NewExpressionStatement(assignment, nopos); | 
| 6561   } | 6547   } | 
| 6562 | 6548 | 
| 6563   // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); | 6549   // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6643     set_completion_throw = factory->NewIfStatement( | 6629     set_completion_throw = factory->NewIfStatement( | 
| 6644         condition, statement, factory->NewEmptyStatement(nopos), nopos); | 6630         condition, statement, factory->NewEmptyStatement(nopos), nopos); | 
| 6645   } | 6631   } | 
| 6646 | 6632 | 
| 6647   // if (condition) { | 6633   // if (condition) { | 
| 6648   //   #BuildIteratorCloseForCompletion(iter, completion) | 6634   //   #BuildIteratorCloseForCompletion(iter, completion) | 
| 6649   // } | 6635   // } | 
| 6650   Block* maybe_close; | 6636   Block* maybe_close; | 
| 6651   { | 6637   { | 
| 6652     Block* block = factory->NewBlock(nullptr, 2, true, nopos); | 6638     Block* block = factory->NewBlock(nullptr, 2, true, nopos); | 
| 6653     parser_->BuildIteratorCloseForCompletion(block->statements(), iter, | 6639     Expression* proxy = factory->NewVariableProxy(completion); | 
| 6654                                              completion); | 6640     parser_->BuildIteratorCloseForCompletion(block->statements(), iter, proxy); | 
| 6655     DCHECK(block->statements()->length() == 2); | 6641     DCHECK(block->statements()->length() == 2); | 
| 6656 | 6642 | 
| 6657     maybe_close = factory->NewBlock(nullptr, 1, true, nopos); | 6643     maybe_close = factory->NewBlock(nullptr, 1, true, nopos); | 
| 6658     maybe_close->statements()->Add( | 6644     maybe_close->statements()->Add( | 
| 6659         factory->NewIfStatement(condition, block, | 6645         factory->NewIfStatement(condition, block, | 
| 6660                                 factory->NewEmptyStatement(nopos), nopos), | 6646                                 factory->NewEmptyStatement(nopos), nopos), | 
| 6661         zone); | 6647         zone); | 
| 6662   } | 6648   } | 
| 6663 | 6649 | 
| 6664   // try { #try_block } | 6650   // try { #try_block } | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6703     try_finally = | 6689     try_finally = | 
| 6704         factory->NewTryFinallyStatement(try_block, maybe_close, nopos); | 6690         factory->NewTryFinallyStatement(try_block, maybe_close, nopos); | 
| 6705   } | 6691   } | 
| 6706 | 6692 | 
| 6707   target->statements()->Add(initialize_completion, zone); | 6693   target->statements()->Add(initialize_completion, zone); | 
| 6708   target->statements()->Add(try_finally, zone); | 6694   target->statements()->Add(try_finally, zone); | 
| 6709 } | 6695 } | 
| 6710 | 6696 | 
| 6711 void ParserTraits::BuildIteratorCloseForCompletion( | 6697 void ParserTraits::BuildIteratorCloseForCompletion( | 
| 6712     ZoneList<Statement*>* statements, Variable* iterator, | 6698     ZoneList<Statement*>* statements, Variable* iterator, | 
| 6713     Variable* completion) { | 6699     Expression* completion) { | 
| 6714   // | 6700   // | 
| 6715   // This function adds two statements to [statements], corresponding to the | 6701   // This function adds two statements to [statements], corresponding to the | 
| 6716   // following code: | 6702   // following code: | 
| 6717   // | 6703   // | 
| 6718   //   let iteratorReturn = iterator.return; | 6704   //   let iteratorReturn = iterator.return; | 
| 6719   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 6705   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 
| 6720   //     if (completion === kThrowCompletion) { | 6706   //     if (completion === kThrowCompletion) { | 
| 6721   //       if (!IS_CALLABLE(iteratorReturn)) { | 6707   //       if (!IS_CALLABLE(iteratorReturn)) { | 
| 6722   //         throw MakeTypeError(kReturnMethodNotCallable); | 6708   //         throw MakeTypeError(kReturnMethodNotCallable); | 
| 6723   //       } | 6709   //       } | 
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6838 | 6824 | 
| 6839   // if (completion === kThrowCompletion) { | 6825   // if (completion === kThrowCompletion) { | 
| 6840   //   #check_return_callable; | 6826   //   #check_return_callable; | 
| 6841   //   #try_call_return; | 6827   //   #try_call_return; | 
| 6842   // } else { | 6828   // } else { | 
| 6843   //   #validate_return; | 6829   //   #validate_return; | 
| 6844   // } | 6830   // } | 
| 6845   Statement* call_return_carefully; | 6831   Statement* call_return_carefully; | 
| 6846   { | 6832   { | 
| 6847     Expression* condition = factory->NewCompareOperation( | 6833     Expression* condition = factory->NewCompareOperation( | 
| 6848         Token::EQ_STRICT, factory->NewVariableProxy(completion), | 6834         Token::EQ_STRICT, completion, | 
| 6849         factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); | 6835         factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); | 
| 6850 | 6836 | 
| 6851     Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); | 6837     Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); | 
| 6852     then_block->statements()->Add(check_return_callable, zone); | 6838     then_block->statements()->Add(check_return_callable, zone); | 
| 6853     then_block->statements()->Add(try_call_return, zone); | 6839     then_block->statements()->Add(try_call_return, zone); | 
| 6854 | 6840 | 
| 6855     call_return_carefully = | 6841     call_return_carefully = | 
| 6856         factory->NewIfStatement(condition, then_block, validate_return, nopos); | 6842         factory->NewIfStatement(condition, then_block, validate_return, nopos); | 
| 6857   } | 6843   } | 
| 6858 | 6844 | 
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 7003                         try_block, target); | 6989                         try_block, target); | 
| 7004     final_loop = target; | 6990     final_loop = target; | 
| 7005   } | 6991   } | 
| 7006 | 6992 | 
| 7007   return final_loop; | 6993   return final_loop; | 
| 7008 } | 6994 } | 
| 7009 | 6995 | 
| 7010 | 6996 | 
| 7011 }  // namespace internal | 6997 }  // namespace internal | 
| 7012 }  // namespace v8 | 6998 }  // namespace v8 | 
| OLD | NEW | 
|---|