| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED | 8 #ifndef DART_PRECOMPILED |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 8650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8661 new_loop_var = true; | 8661 new_loop_var = true; |
| 8662 loop_var_type = ParseConstFinalVarOrType( | 8662 loop_var_type = ParseConstFinalVarOrType( |
| 8663 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : | 8663 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
| 8664 ClassFinalizer::kIgnore); | 8664 ClassFinalizer::kIgnore); |
| 8665 } | 8665 } |
| 8666 intptr_t loop_var_pos = TokenPos(); | 8666 intptr_t loop_var_pos = TokenPos(); |
| 8667 const String* loop_var_name = ExpectIdentifier("variable name expected"); | 8667 const String* loop_var_name = ExpectIdentifier("variable name expected"); |
| 8668 | 8668 |
| 8669 // Parse stream expression. | 8669 // Parse stream expression. |
| 8670 ExpectToken(Token::kIN); | 8670 ExpectToken(Token::kIN); |
| 8671 const intptr_t stream_pos = TokenPos(); | 8671 const intptr_t stream_expr_pos = TokenPos(); |
| 8672 AstNode* stream_expr = | 8672 AstNode* stream_expr = |
| 8673 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8673 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8674 ExpectToken(Token::kRPAREN); | 8674 ExpectToken(Token::kRPAREN); |
| 8675 | 8675 |
| 8676 // Open a block for the iterator variable and the try-finally | 8676 // Open a block for the iterator variable and the try-finally |
| 8677 // statement that contains the loop. | 8677 // statement that contains the loop. |
| 8678 OpenBlock(); | 8678 OpenBlock(); |
| 8679 const Block* loop_block = current_block_; | 8679 const Block* loop_block = current_block_; |
| 8680 | 8680 |
| 8681 // Build creation of implicit StreamIterator. | 8681 // Build creation of implicit StreamIterator. |
| 8682 // var :for-in-iter = new StreamIterator(stream_expr). | 8682 // var :for-in-iter = new StreamIterator(stream_expr). |
| 8683 const Class& stream_iterator_cls = | 8683 const Class& stream_iterator_cls = |
| 8684 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class()); | 8684 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class()); |
| 8685 ASSERT(!stream_iterator_cls.IsNull()); | 8685 ASSERT(!stream_iterator_cls.IsNull()); |
| 8686 const Function& iterator_ctor = | 8686 const Function& iterator_ctor = |
| 8687 Function::ZoneHandle(Z, stream_iterator_cls.LookupFunction( | 8687 Function::ZoneHandle(Z, stream_iterator_cls.LookupFunction( |
| 8688 Symbols::StreamIteratorConstructor())); | 8688 Symbols::StreamIteratorConstructor())); |
| 8689 ASSERT(!iterator_ctor.IsNull()); | 8689 ASSERT(!iterator_ctor.IsNull()); |
| 8690 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(Scanner::kNoSourcePos); | 8690 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos); |
| 8691 ctor_args->Add(stream_expr); | 8691 ctor_args->Add(stream_expr); |
| 8692 ConstructorCallNode* ctor_call = | 8692 ConstructorCallNode* ctor_call = |
| 8693 new (Z) ConstructorCallNode(Scanner::kNoSourcePos, | 8693 new (Z) ConstructorCallNode(stream_expr_pos, |
| 8694 TypeArguments::ZoneHandle(Z), | 8694 TypeArguments::ZoneHandle(Z), |
| 8695 iterator_ctor, | 8695 iterator_ctor, |
| 8696 ctor_args); | 8696 ctor_args); |
| 8697 const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType()); | 8697 const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 8698 LocalVariable* iterator_var = new(Z) LocalVariable( | 8698 LocalVariable* iterator_var = new(Z) LocalVariable( |
| 8699 stream_pos, Symbols::ForInIter(), iterator_type); | 8699 stream_expr_pos, Symbols::ForInIter(), iterator_type); |
| 8700 current_block_->scope->AddVariable(iterator_var); | 8700 current_block_->scope->AddVariable(iterator_var); |
| 8701 AstNode* iterator_init = | 8701 AstNode* iterator_init = |
| 8702 new(Z) StoreLocalNode(stream_pos, iterator_var, ctor_call); | 8702 new(Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call); |
| 8703 current_block_->statements->Add(iterator_init); | 8703 current_block_->statements->Add(iterator_init); |
| 8704 | 8704 |
| 8705 // We need to ensure that the stream is cancelled after the loop. | 8705 // We need to ensure that the stream is cancelled after the loop. |
| 8706 // Thus, wrap the loop in a try-finally that calls :for-in-iter.close() | 8706 // Thus, wrap the loop in a try-finally that calls :for-in-iter.close() |
| 8707 // in the finally clause. It is harmless to call close() if the stream | 8707 // in the finally clause. It is harmless to call close() if the stream |
| 8708 // is already cancelled (when moveNext() returns false). | 8708 // is already cancelled (when moveNext() returns false). |
| 8709 // Note: even though this is async code, we do not need to set up | 8709 // Note: even though this is async code, we do not need to set up |
| 8710 // the closurized saved_exception_var and saved_stack_trace_var because | 8710 // the closurized saved_exception_var and saved_stack_trace_var because |
| 8711 // there can not be a suspend/resume event before the exception is | 8711 // there can not be a suspend/resume event before the exception is |
| 8712 // rethrown in the catch clause. The catch block of the implicit | 8712 // rethrown in the catch clause. The catch block of the implicit |
| (...skipping 17 matching lines...) Expand all Loading... |
| 8730 // Build while loop condition. | 8730 // Build while loop condition. |
| 8731 // while (await :for-in-iter.moveNext()) | 8731 // while (await :for-in-iter.moveNext()) |
| 8732 LocalVariable* saved_try_ctx; | 8732 LocalVariable* saved_try_ctx; |
| 8733 LocalVariable* async_saved_try_ctx; | 8733 LocalVariable* async_saved_try_ctx; |
| 8734 LocalVariable* outer_saved_try_ctx; | 8734 LocalVariable* outer_saved_try_ctx; |
| 8735 LocalVariable* outer_async_saved_try_ctx; | 8735 LocalVariable* outer_async_saved_try_ctx; |
| 8736 CheckAsyncOpInTryBlock(&saved_try_ctx, | 8736 CheckAsyncOpInTryBlock(&saved_try_ctx, |
| 8737 &async_saved_try_ctx, | 8737 &async_saved_try_ctx, |
| 8738 &outer_saved_try_ctx, | 8738 &outer_saved_try_ctx, |
| 8739 &outer_async_saved_try_ctx); | 8739 &outer_async_saved_try_ctx); |
| 8740 ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_pos); | 8740 ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_expr_pos); |
| 8741 AstNode* iterator_moveNext = new(Z) InstanceCallNode( | 8741 AstNode* iterator_moveNext = new(Z) InstanceCallNode( |
| 8742 stream_pos, | 8742 stream_expr_pos, |
| 8743 new(Z) LoadLocalNode(stream_pos, iterator_var), | 8743 new(Z) LoadLocalNode(stream_expr_pos, iterator_var), |
| 8744 Symbols::MoveNext(), | 8744 Symbols::MoveNext(), |
| 8745 no_args); | 8745 no_args); |
| 8746 OpenBlock(); | 8746 OpenBlock(); |
| 8747 AstNode* await_moveNext = | 8747 AstNode* await_moveNext = |
| 8748 new(Z) AwaitNode(stream_pos, | 8748 new(Z) AwaitNode(stream_expr_pos, |
| 8749 iterator_moveNext, | 8749 iterator_moveNext, |
| 8750 saved_try_ctx, | 8750 saved_try_ctx, |
| 8751 async_saved_try_ctx, | 8751 async_saved_try_ctx, |
| 8752 outer_saved_try_ctx, | 8752 outer_saved_try_ctx, |
| 8753 outer_async_saved_try_ctx, | 8753 outer_async_saved_try_ctx, |
| 8754 current_block_->scope); | 8754 current_block_->scope); |
| 8755 AwaitTransformer at(current_block_->statements, async_temp_scope_); | 8755 AwaitTransformer at(current_block_->statements, async_temp_scope_); |
| 8756 await_moveNext = at.Transform(await_moveNext); | 8756 await_moveNext = at.Transform(await_moveNext); |
| 8757 SequenceNode* await_preamble = CloseBlock(); | 8757 SequenceNode* await_preamble = CloseBlock(); |
| 8758 | 8758 |
| (...skipping 5704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14463 const ArgumentListNode& function_args, | 14463 const ArgumentListNode& function_args, |
| 14464 const LocalVariable* temp_for_last_arg, | 14464 const LocalVariable* temp_for_last_arg, |
| 14465 bool is_super_invocation) { | 14465 bool is_super_invocation) { |
| 14466 UNREACHABLE(); | 14466 UNREACHABLE(); |
| 14467 return NULL; | 14467 return NULL; |
| 14468 } | 14468 } |
| 14469 | 14469 |
| 14470 } // namespace dart | 14470 } // namespace dart |
| 14471 | 14471 |
| 14472 #endif // DART_PRECOMPILED | 14472 #endif // DART_PRECOMPILED |
| OLD | NEW |