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 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos); | 484 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos); |
485 } | 485 } |
486 // ...and one more time for '~foo' => 'foo^(~0)'. | 486 // ...and one more time for '~foo' => 'foo^(~0)'. |
487 if (op == Token::BIT_NOT) { | 487 if (op == Token::BIT_NOT) { |
488 return factory->NewBinaryOperation( | 488 return factory->NewBinaryOperation( |
489 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); | 489 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); |
490 } | 490 } |
491 return factory->NewUnaryOperation(op, expression, pos); | 491 return factory->NewUnaryOperation(op, expression, pos); |
492 } | 492 } |
493 | 493 |
| 494 Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) { |
| 495 int pos = RelocInfo::kNoPosition; |
| 496 AstNodeFactory* factory = parser_->factory(); |
| 497 Zone* zone = parser_->zone(); |
| 498 |
| 499 if (value == nullptr) value = factory->NewUndefinedLiteral(pos); |
| 500 |
| 501 auto args = new (zone) ZoneList<Expression*>(2, zone); |
| 502 args->Add(value, zone); |
| 503 args->Add(factory->NewBooleanLiteral(done, pos), zone); |
| 504 |
| 505 return factory->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args, |
| 506 pos); |
| 507 } |
494 | 508 |
495 Expression* ParserTraits::NewThrowReferenceError( | 509 Expression* ParserTraits::NewThrowReferenceError( |
496 MessageTemplate::Template message, int pos) { | 510 MessageTemplate::Template message, int pos) { |
497 return NewThrowError(Runtime::kNewReferenceError, message, | 511 return NewThrowError(Runtime::kNewReferenceError, message, |
498 parser_->ast_value_factory()->empty_string(), pos); | 512 parser_->ast_value_factory()->empty_string(), pos); |
499 } | 513 } |
500 | 514 |
501 | 515 |
502 Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message, | 516 Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message, |
503 const AstRawString* arg, | 517 const AstRawString* arg, |
(...skipping 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2778 } | 2792 } |
2779 | 2793 |
2780 // ES6 14.6.1 Static Semantics: IsInTailPosition | 2794 // ES6 14.6.1 Static Semantics: IsInTailPosition |
2781 if (FLAG_harmony_tailcalls && !is_sloppy(language_mode())) { | 2795 if (FLAG_harmony_tailcalls && !is_sloppy(language_mode())) { |
2782 function_state_->AddExpressionInTailPosition(return_value); | 2796 function_state_->AddExpressionInTailPosition(return_value); |
2783 } | 2797 } |
2784 } | 2798 } |
2785 ExpectSemicolon(CHECK_OK); | 2799 ExpectSemicolon(CHECK_OK); |
2786 | 2800 |
2787 if (is_generator()) { | 2801 if (is_generator()) { |
2788 Expression* generator = factory()->NewVariableProxy( | 2802 return_value = BuildIteratorResult(return_value, true); |
2789 function_state_->generator_object_variable()); | |
2790 Expression* yield = factory()->NewYield( | |
2791 generator, return_value, Yield::kFinal, loc.beg_pos); | |
2792 result = factory()->NewExpressionStatement(yield, loc.beg_pos); | |
2793 } else { | |
2794 result = factory()->NewReturnStatement(return_value, loc.beg_pos); | |
2795 } | 2803 } |
2796 | 2804 |
| 2805 result = factory()->NewReturnStatement(return_value, loc.beg_pos); |
| 2806 |
2797 Scope* decl_scope = scope_->DeclarationScope(); | 2807 Scope* decl_scope = scope_->DeclarationScope(); |
2798 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { | 2808 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { |
2799 ReportMessageAt(loc, MessageTemplate::kIllegalReturn); | 2809 ReportMessageAt(loc, MessageTemplate::kIllegalReturn); |
2800 *ok = false; | 2810 *ok = false; |
2801 return NULL; | 2811 return NULL; |
2802 } | 2812 } |
2803 return result; | 2813 return result; |
2804 } | 2814 } |
2805 | 2815 |
2806 | 2816 |
(...skipping 1859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4666 inner_block->set_scope(inner_scope); | 4676 inner_block->set_scope(inner_scope); |
4667 body = inner_block->statements(); | 4677 body = inner_block->statements(); |
4668 } | 4678 } |
4669 | 4679 |
4670 { | 4680 { |
4671 BlockState block_state(&scope_, inner_scope); | 4681 BlockState block_state(&scope_, inner_scope); |
4672 | 4682 |
4673 if (IsGeneratorFunction(kind)) { | 4683 if (IsGeneratorFunction(kind)) { |
4674 // We produce: | 4684 // We produce: |
4675 // | 4685 // |
4676 // try { InitialYield; ...body...; FinalYield } | 4686 // try { InitialYield; ...body...; return {value: undefined, done: true} } |
4677 // finally { %GeneratorClose(generator) } | 4687 // finally { %GeneratorClose(generator) } |
4678 // | 4688 // |
4679 // - InitialYield yields the actual generator object. | 4689 // - InitialYield yields the actual generator object. |
4680 // - FinalYield yields {value: foo, done: true} where foo is the | 4690 // - Any return statement inside the body will have its argument wrapped |
4681 // completion value of body. (This is needed here in case the body | 4691 // in a "done" iterator result object. |
4682 // falls through without an explicit return.) | |
4683 // - Any return statement inside the body will be converted into a similar | |
4684 // FinalYield. | |
4685 // - If the generator terminates for whatever reason, we must close it. | 4692 // - If the generator terminates for whatever reason, we must close it. |
4686 // Hence the finally clause. | 4693 // Hence the finally clause. |
4687 | 4694 |
4688 Block* try_block = | 4695 Block* try_block = |
4689 factory()->NewBlock(nullptr, 3, false, RelocInfo::kNoPosition); | 4696 factory()->NewBlock(nullptr, 3, false, RelocInfo::kNoPosition); |
4690 | 4697 |
4691 { | 4698 { |
4692 ZoneList<Expression*>* arguments = | 4699 ZoneList<Expression*>* arguments = |
4693 new (zone()) ZoneList<Expression*>(0, zone()); | 4700 new (zone()) ZoneList<Expression*>(0, zone()); |
4694 CallRuntime* allocation = factory()->NewCallRuntime( | 4701 CallRuntime* allocation = factory()->NewCallRuntime( |
4695 Runtime::kCreateJSGeneratorObject, arguments, pos); | 4702 Runtime::kCreateJSGeneratorObject, arguments, pos); |
4696 VariableProxy* init_proxy = factory()->NewVariableProxy( | 4703 VariableProxy* init_proxy = factory()->NewVariableProxy( |
4697 function_state_->generator_object_variable()); | 4704 function_state_->generator_object_variable()); |
4698 Assignment* assignment = factory()->NewAssignment( | 4705 Assignment* assignment = factory()->NewAssignment( |
4699 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition); | 4706 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition); |
4700 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4707 VariableProxy* get_proxy = factory()->NewVariableProxy( |
4701 function_state_->generator_object_variable()); | 4708 function_state_->generator_object_variable()); |
4702 Yield* yield = factory()->NewYield( | 4709 Yield* yield = |
4703 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); | 4710 factory()->NewYield(get_proxy, assignment, RelocInfo::kNoPosition); |
4704 try_block->statements()->Add( | 4711 try_block->statements()->Add( |
4705 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition), | 4712 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition), |
4706 zone()); | 4713 zone()); |
4707 } | 4714 } |
4708 | 4715 |
4709 ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK); | 4716 ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK); |
4710 | 4717 |
4711 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4718 Statement* final_return = factory()->NewReturnStatement( |
4712 function_state_->generator_object_variable()); | 4719 BuildIteratorResult(nullptr, true), RelocInfo::kNoPosition); |
4713 Expression* undefined = | 4720 try_block->statements()->Add(final_return, zone()); |
4714 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | |
4715 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, | |
4716 RelocInfo::kNoPosition); | |
4717 try_block->statements()->Add( | |
4718 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition), | |
4719 zone()); | |
4720 | 4721 |
4721 Block* finally_block = | 4722 Block* finally_block = |
4722 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); | 4723 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); |
4723 ZoneList<Expression*>* args = | 4724 ZoneList<Expression*>* args = |
4724 new (zone()) ZoneList<Expression*>(1, zone()); | 4725 new (zone()) ZoneList<Expression*>(1, zone()); |
4725 VariableProxy* call_proxy = factory()->NewVariableProxy( | 4726 VariableProxy* call_proxy = factory()->NewVariableProxy( |
4726 function_state_->generator_object_variable()); | 4727 function_state_->generator_object_variable()); |
4727 args->Add(call_proxy, zone()); | 4728 args->Add(call_proxy, zone()); |
4728 Expression* call = factory()->NewCallRuntime( | 4729 Expression* call = factory()->NewCallRuntime( |
4729 Runtime::kGeneratorClose, args, RelocInfo::kNoPosition); | 4730 Runtime::kGeneratorClose, args, RelocInfo::kNoPosition); |
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6115 Statement* set_mode_return; | 6116 Statement* set_mode_return; |
6116 { | 6117 { |
6117 Expression* mode_proxy = factory->NewVariableProxy(var_mode); | 6118 Expression* mode_proxy = factory->NewVariableProxy(var_mode); |
6118 Expression* kreturn = | 6119 Expression* kreturn = |
6119 factory->NewSmiLiteral(JSGeneratorObject::RETURN, nopos); | 6120 factory->NewSmiLiteral(JSGeneratorObject::RETURN, nopos); |
6120 Expression* assignment = | 6121 Expression* assignment = |
6121 factory->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); | 6122 factory->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); |
6122 set_mode_return = factory->NewExpressionStatement(assignment, nopos); | 6123 set_mode_return = factory->NewExpressionStatement(assignment, nopos); |
6123 } | 6124 } |
6124 | 6125 |
6125 | 6126 // Yield(output); |
6126 // RawYield(output); | |
6127 Statement* yield_output; | 6127 Statement* yield_output; |
6128 { | 6128 { |
6129 Expression* output_proxy = factory->NewVariableProxy(var_output); | 6129 Expression* output_proxy = factory->NewVariableProxy(var_output); |
6130 Yield* yield = factory->NewYield( | 6130 Yield* yield = factory->NewYield(generator, output_proxy, nopos); |
6131 generator, output_proxy, Yield::kInitial, nopos); | |
6132 yield_output = factory->NewExpressionStatement(yield, nopos); | 6131 yield_output = factory->NewExpressionStatement(yield, nopos); |
6133 } | 6132 } |
6134 | 6133 |
6135 | 6134 |
6136 // mode = kNext; | 6135 // mode = kNext; |
6137 Statement* set_mode_next; | 6136 Statement* set_mode_next; |
6138 { | 6137 { |
6139 Expression* mode_proxy = factory->NewVariableProxy(var_mode); | 6138 Expression* mode_proxy = factory->NewVariableProxy(var_mode); |
6140 Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::NEXT, nopos); | 6139 Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::NEXT, nopos); |
6141 Expression* assignment = | 6140 Expression* assignment = |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6930 Expression* do_each = | 6929 Expression* do_each = |
6931 factory->NewDoExpression(new_assign_each, var_each, nopos); | 6930 factory->NewDoExpression(new_assign_each, var_each, nopos); |
6932 loop->set_assign_each(do_each); | 6931 loop->set_assign_each(do_each); |
6933 | 6932 |
6934 return final_loop; | 6933 return final_loop; |
6935 } | 6934 } |
6936 | 6935 |
6937 | 6936 |
6938 } // namespace internal | 6937 } // namespace internal |
6939 } // namespace v8 | 6938 } // namespace v8 |
OLD | NEW |