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 |