| 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 <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 bool has_dot = scanner()->ContainsDot(); | 497 bool has_dot = scanner()->ContainsDot(); |
| 498 double value = scanner()->DoubleValue(); | 498 double value = scanner()->DoubleValue(); |
| 499 return factory()->NewNumberLiteral(value, pos, has_dot); | 499 return factory()->NewNumberLiteral(value, pos, has_dot); |
| 500 } | 500 } |
| 501 default: | 501 default: |
| 502 DCHECK(false); | 502 DCHECK(false); |
| 503 } | 503 } |
| 504 return NULL; | 504 return NULL; |
| 505 } | 505 } |
| 506 | 506 |
| 507 Expression* Parser::GetIterator(Expression* iterable, int pos) { | |
| 508 Expression* iterator_symbol_literal = | |
| 509 factory()->NewSymbolLiteral("iterator_symbol", kNoSourcePosition); | |
| 510 Expression* prop = | |
| 511 factory()->NewProperty(iterable, iterator_symbol_literal, pos); | |
| 512 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(0, zone()); | |
| 513 return factory()->NewCall(prop, args, pos); | |
| 514 } | |
| 515 | |
| 516 void Parser::MarkTailPosition(Expression* expression) { | 507 void Parser::MarkTailPosition(Expression* expression) { |
| 517 expression->MarkTail(); | 508 expression->MarkTail(); |
| 518 } | 509 } |
| 519 | 510 |
| 520 Expression* Parser::NewV8Intrinsic(const AstRawString* name, | 511 Expression* Parser::NewV8Intrinsic(const AstRawString* name, |
| 521 ZoneList<Expression*>* args, int pos, | 512 ZoneList<Expression*>* args, int pos, |
| 522 bool* ok) { | 513 bool* ok) { |
| 523 if (extension_ != nullptr) { | 514 if (extension_ != nullptr) { |
| 524 // The extension structures are only accessible while parsing the | 515 // The extension structures are only accessible while parsing the |
| 525 // very first time, not when reparsing because of lazy compilation. | 516 // very first time, not when reparsing because of lazy compilation. |
| (...skipping 1540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2066 // proper ES6 iterator finalization. In that case, the result is not | 2057 // proper ES6 iterator finalization. In that case, the result is not |
| 2067 // immediately a ForOfStatement. | 2058 // immediately a ForOfStatement. |
| 2068 | 2059 |
| 2069 const int nopos = kNoSourcePosition; | 2060 const int nopos = kNoSourcePosition; |
| 2070 auto avfactory = ast_value_factory(); | 2061 auto avfactory = ast_value_factory(); |
| 2071 | 2062 |
| 2072 Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string()); | 2063 Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string()); |
| 2073 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); | 2064 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
| 2074 Variable* completion = NewTemporary(avfactory->empty_string()); | 2065 Variable* completion = NewTemporary(avfactory->empty_string()); |
| 2075 | 2066 |
| 2076 // iterator = iterable[Symbol.iterator]() | 2067 // iterator = GetIterator(iterable) |
| 2077 Expression* assign_iterator; | 2068 Expression* assign_iterator; |
| 2078 { | 2069 { |
| 2079 assign_iterator = factory()->NewAssignment( | 2070 assign_iterator = factory()->NewAssignment( |
| 2080 Token::ASSIGN, factory()->NewVariableProxy(iterator), | 2071 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| 2081 GetIterator(iterable, iterable->position()), iterable->position()); | 2072 factory()->NewGetIterator(iterable, iterable->position()), |
| 2073 iterable->position()); |
| 2082 } | 2074 } |
| 2083 | 2075 |
| 2084 // !%_IsJSReceiver(result = iterator.next()) && | 2076 // !%_IsJSReceiver(result = iterator.next()) && |
| 2085 // %ThrowIteratorResultNotAnObject(result) | 2077 // %ThrowIteratorResultNotAnObject(result) |
| 2086 Expression* next_result; | 2078 Expression* next_result; |
| 2087 { | 2079 { |
| 2088 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2080 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2089 next_result = | 2081 next_result = |
| 2090 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); | 2082 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); |
| 2091 } | 2083 } |
| (...skipping 2474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4566 // | 4558 // |
| 4567 // do { | 4559 // do { |
| 4568 // const kNext = 0; | 4560 // const kNext = 0; |
| 4569 // const kReturn = 1; | 4561 // const kReturn = 1; |
| 4570 // const kThrow = 2; | 4562 // const kThrow = 2; |
| 4571 // | 4563 // |
| 4572 // let input = function.sent; | 4564 // let input = function.sent; |
| 4573 // let mode = kNext; | 4565 // let mode = kNext; |
| 4574 // let output = undefined; | 4566 // let output = undefined; |
| 4575 // | 4567 // |
| 4576 // let iterator = iterable[Symbol.iterator](); | 4568 // let iterator = GetIterator(iterable); |
| 4577 // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid); | |
| 4578 // | 4569 // |
| 4579 // while (true) { | 4570 // while (true) { |
| 4580 // // From the generator to the iterator: | 4571 // // From the generator to the iterator: |
| 4581 // // Forward input according to resume mode and obtain output. | 4572 // // Forward input according to resume mode and obtain output. |
| 4582 // switch (mode) { | 4573 // switch (mode) { |
| 4583 // case kNext: | 4574 // case kNext: |
| 4584 // output = iterator.next(input); | 4575 // output = iterator.next(input); |
| 4585 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4576 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
| 4586 // break; | 4577 // break; |
| 4587 // case kReturn: | 4578 // case kReturn: |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4670 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); | 4661 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); |
| 4671 Statement* initialize_output; | 4662 Statement* initialize_output; |
| 4672 { | 4663 { |
| 4673 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4664 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
| 4674 Expression* assignment = | 4665 Expression* assignment = |
| 4675 factory()->NewAssignment(Token::ASSIGN, output_proxy, | 4666 factory()->NewAssignment(Token::ASSIGN, output_proxy, |
| 4676 factory()->NewUndefinedLiteral(nopos), nopos); | 4667 factory()->NewUndefinedLiteral(nopos), nopos); |
| 4677 initialize_output = factory()->NewExpressionStatement(assignment, nopos); | 4668 initialize_output = factory()->NewExpressionStatement(assignment, nopos); |
| 4678 } | 4669 } |
| 4679 | 4670 |
| 4680 // let iterator = iterable[Symbol.iterator]; | 4671 // let iterator = GetIterator(iterable); |
| 4681 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); | 4672 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); |
| 4682 Statement* get_iterator; | 4673 Statement* get_iterator; |
| 4683 { | 4674 { |
| 4684 Expression* iterator = GetIterator(iterable, nopos); | 4675 Expression* iterator = factory()->NewGetIterator(iterable, nopos); |
| 4685 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4676 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
| 4686 Expression* assignment = factory()->NewAssignment( | 4677 Expression* assignment = factory()->NewAssignment( |
| 4687 Token::ASSIGN, iterator_proxy, iterator, nopos); | 4678 Token::ASSIGN, iterator_proxy, iterator, nopos); |
| 4688 get_iterator = factory()->NewExpressionStatement(assignment, nopos); | 4679 get_iterator = factory()->NewExpressionStatement(assignment, nopos); |
| 4689 } | 4680 } |
| 4690 | 4681 |
| 4691 // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid); | |
| 4692 Statement* validate_iterator; | |
| 4693 { | |
| 4694 Expression* is_receiver_call; | |
| 4695 { | |
| 4696 auto args = new (zone()) ZoneList<Expression*>(1, zone()); | |
| 4697 args->Add(factory()->NewVariableProxy(var_iterator), zone()); | |
| 4698 is_receiver_call = | |
| 4699 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | |
| 4700 } | |
| 4701 | |
| 4702 Statement* throw_call; | |
| 4703 { | |
| 4704 Expression* call = | |
| 4705 NewThrowTypeError(MessageTemplate::kSymbolIteratorInvalid, | |
| 4706 ast_value_factory()->empty_string(), nopos); | |
| 4707 throw_call = factory()->NewExpressionStatement(call, nopos); | |
| 4708 } | |
| 4709 | |
| 4710 validate_iterator = factory()->NewIfStatement( | |
| 4711 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, | |
| 4712 nopos); | |
| 4713 } | |
| 4714 | |
| 4715 // output = iterator.next(input); | 4682 // output = iterator.next(input); |
| 4716 Statement* call_next; | 4683 Statement* call_next; |
| 4717 { | 4684 { |
| 4718 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4685 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
| 4719 Expression* literal = | 4686 Expression* literal = |
| 4720 factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos); | 4687 factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos); |
| 4721 Expression* next_property = | 4688 Expression* next_property = |
| 4722 factory()->NewProperty(iterator_proxy, literal, nopos); | 4689 factory()->NewProperty(iterator_proxy, literal, nopos); |
| 4723 Expression* input_proxy = factory()->NewVariableProxy(var_input); | 4690 Expression* input_proxy = factory()->NewVariableProxy(var_input); |
| 4724 auto args = new (zone()) ZoneList<Expression*>(1, zone()); | 4691 auto args = new (zone()) ZoneList<Expression*>(1, zone()); |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5009 | 4976 |
| 5010 loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body); | 4977 loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body); |
| 5011 } | 4978 } |
| 5012 | 4979 |
| 5013 // do { ... } | 4980 // do { ... } |
| 5014 DoExpression* yield_star; | 4981 DoExpression* yield_star; |
| 5015 { | 4982 { |
| 5016 // The rewriter needs to process the get_value statement only, hence we | 4983 // The rewriter needs to process the get_value statement only, hence we |
| 5017 // put the preceding statements into an init block. | 4984 // put the preceding statements into an init block. |
| 5018 | 4985 |
| 5019 Block* do_block_ = factory()->NewBlock(nullptr, 7, true, nopos); | 4986 Block* do_block_ = factory()->NewBlock(nullptr, 6, true, nopos); |
| 5020 do_block_->statements()->Add(initialize_input, zone()); | 4987 do_block_->statements()->Add(initialize_input, zone()); |
| 5021 do_block_->statements()->Add(initialize_mode, zone()); | 4988 do_block_->statements()->Add(initialize_mode, zone()); |
| 5022 do_block_->statements()->Add(initialize_output, zone()); | 4989 do_block_->statements()->Add(initialize_output, zone()); |
| 5023 do_block_->statements()->Add(get_iterator, zone()); | 4990 do_block_->statements()->Add(get_iterator, zone()); |
| 5024 do_block_->statements()->Add(validate_iterator, zone()); | |
| 5025 do_block_->statements()->Add(loop, zone()); | 4991 do_block_->statements()->Add(loop, zone()); |
| 5026 do_block_->statements()->Add(maybe_return_value, zone()); | 4992 do_block_->statements()->Add(maybe_return_value, zone()); |
| 5027 | 4993 |
| 5028 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); | 4994 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 5029 do_block->statements()->Add(do_block_, zone()); | 4995 do_block->statements()->Add(do_block_, zone()); |
| 5030 do_block->statements()->Add(get_value, zone()); | 4996 do_block->statements()->Add(get_value, zone()); |
| 5031 | 4997 |
| 5032 Variable* dot_result = | 4998 Variable* dot_result = |
| 5033 NewTemporary(ast_value_factory()->dot_result_string()); | 4999 NewTemporary(ast_value_factory()->dot_result_string()); |
| 5034 yield_star = factory()->NewDoExpression(do_block, dot_result, nopos); | 5000 yield_star = factory()->NewDoExpression(do_block, dot_result, nopos); |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5480 | 5446 |
| 5481 return final_loop; | 5447 return final_loop; |
| 5482 } | 5448 } |
| 5483 | 5449 |
| 5484 #undef CHECK_OK | 5450 #undef CHECK_OK |
| 5485 #undef CHECK_OK_VOID | 5451 #undef CHECK_OK_VOID |
| 5486 #undef CHECK_FAILED | 5452 #undef CHECK_FAILED |
| 5487 | 5453 |
| 5488 } // namespace internal | 5454 } // namespace internal |
| 5489 } // namespace v8 | 5455 } // namespace v8 |
| OLD | NEW |