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