| Index: runtime/vm/parser.cc
 | 
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
 | 
| index f9664bd666ce8766eeb4873f386e798b52c06f37..a5b49ee3fc1e49a5e6d4e1ffd5c96b14da3e81aa 100644
 | 
| --- a/runtime/vm/parser.cc
 | 
| +++ b/runtime/vm/parser.cc
 | 
| @@ -6817,6 +6817,8 @@ void Parser::OpenAsyncTryBlock() {
 | 
|    // This is the outermost try-catch in the function.
 | 
|    ASSERT(try_stack_ == NULL);
 | 
|    PushTry(current_block_);
 | 
| +  // Validate that we always get try index of 0.
 | 
| +  ASSERT(try_stack_->try_index() == CatchClauseNode::kImplicitAsyncTryIndex);
 | 
|  
 | 
|    SetupSavedTryContext(context_var);
 | 
|  }
 | 
| @@ -7086,6 +7088,7 @@ void Parser::AddAsyncGeneratorVariables() {
 | 
|    //   var :async_then_callback;
 | 
|    //   var :async_catch_error_callback;
 | 
|    //   var :async_stack_trace;
 | 
| +  //   var :controller_stream;
 | 
|    // These variables are used to store the async generator closure containing
 | 
|    // the body of the async* function. They are used by the await operator.
 | 
|    LocalVariable* controller_var =
 | 
| @@ -7108,6 +7111,10 @@ void Parser::AddAsyncGeneratorVariables() {
 | 
|        LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
 | 
|                      Symbols::AsyncStackTraceVar(), Object::dynamic_type());
 | 
|    current_block_->scope->AddVariable(async_stack_trace);
 | 
| +  LocalVariable* controller_stream = new (Z)
 | 
| +      LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
 | 
| +                    Symbols::ControllerStream(), Object::dynamic_type());
 | 
| +  current_block_->scope->AddVariable(controller_stream);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -7177,7 +7184,8 @@ RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) {
 | 
|  //   var :async_then_callback = _asyncThenWrapperHelper(:async_op);
 | 
|  //   var :async_catch_error_callback = _asyncCatchErrorWrapperHelper(:async_op);
 | 
|  //   :controller = new _AsyncStarStreamController(:async_op);
 | 
| -//   return :controller.stream;
 | 
| +//   var :controller_stream = :controller.stream;
 | 
| +//   return :controller_stream;
 | 
|  // }
 | 
|  SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func,
 | 
|                                                    SequenceNode* closure_body) {
 | 
| @@ -7208,6 +7216,9 @@ SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func,
 | 
|    existing_var = closure_body->scope()->LookupVariable(
 | 
|        Symbols::AsyncStackTraceVar(), false);
 | 
|    ASSERT((existing_var != NULL) && existing_var->is_captured());
 | 
| +  existing_var =
 | 
| +      closure_body->scope()->LookupVariable(Symbols::ControllerStream(), false);
 | 
| +  ASSERT((existing_var != NULL) && existing_var->is_captured());
 | 
|  
 | 
|    const Library& async_lib = Library::Handle(Library::AsyncLibrary());
 | 
|  
 | 
| @@ -7316,13 +7327,28 @@ SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func,
 | 
|        TokenPosition::kNoSource, controller_var, controller_constructor_call);
 | 
|    current_block_->statements->Add(store_controller);
 | 
|  
 | 
| +  // Grab :controller.stream
 | 
| +  InstanceGetterNode* controller_stream = new (Z) InstanceGetterNode(
 | 
| +      TokenPosition::kNoSource,
 | 
| +      new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_var),
 | 
| +      Symbols::Stream());
 | 
| +
 | 
| +  // Store :controller.stream into :controller_stream inside the closure.
 | 
| +  // We have to remember the stream because a new instance is generated for
 | 
| +  // each getter invocation and in order to recreate the linkage, we need the
 | 
| +  // awaited on instance.
 | 
| +  LocalVariable* controller_stream_var =
 | 
| +      current_block_->scope->LookupVariable(Symbols::ControllerStream(), false);
 | 
| +  ASSERT(controller_stream_var != NULL);
 | 
| +
 | 
| +  StoreLocalNode* store_controller_stream = new (Z) StoreLocalNode(
 | 
| +      TokenPosition::kNoSource, controller_stream_var, controller_stream);
 | 
| +  current_block_->statements->Add(store_controller_stream);
 | 
| +
 | 
|    // return :controller.stream;
 | 
|    ReturnNode* return_node = new (Z) ReturnNode(
 | 
|        TokenPosition::kNoSource,
 | 
| -      new (Z) InstanceGetterNode(
 | 
| -          TokenPosition::kNoSource,
 | 
| -          new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_var),
 | 
| -          Symbols::Stream()));
 | 
| +      new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_stream_var));
 | 
|    current_block_->statements->Add(return_node);
 | 
|    return CloseBlock();
 | 
|  }
 | 
| @@ -9066,6 +9092,37 @@ AstNode* Parser::ParseAwaitForStatement(String* label_name) {
 | 
|        ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
 | 
|    ExpectToken(Token::kRPAREN);
 | 
|  
 | 
| +  // Create :stream to store the stream into temporarily.
 | 
| +  LocalVariable* stream_var =
 | 
| +      new (Z) LocalVariable(stream_expr_pos, stream_expr_pos,
 | 
| +                            Symbols::ColonStream(), Object::dynamic_type());
 | 
| +  current_block_->scope->AddVariable(stream_var);
 | 
| +
 | 
| +  // Store the stream expression into a variable.
 | 
| +  StoreLocalNode* store_stream_var =
 | 
| +      new (Z) StoreLocalNode(stream_expr_pos, stream_var, stream_expr);
 | 
| +  current_block_->statements->Add(store_stream_var);
 | 
| +
 | 
| +  // Register the awaiter on the stream by invoking `_asyncStarListenHelper`.
 | 
| +  const Library& async_lib = Library::Handle(Library::AsyncLibrary());
 | 
| +  const Function& async_star_listen_helper = Function::ZoneHandle(
 | 
| +      Z,
 | 
| +      async_lib.LookupFunctionAllowPrivate(Symbols::_AsyncStarListenHelper()));
 | 
| +  ASSERT(!async_star_listen_helper.IsNull());
 | 
| +  LocalVariable* async_op_var =
 | 
| +      current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
 | 
| +  ASSERT(async_op_var != NULL);
 | 
| +  ArgumentListNode* async_star_listen_helper_args =
 | 
| +      new (Z) ArgumentListNode(stream_expr_pos);
 | 
| +  async_star_listen_helper_args->Add(
 | 
| +      new (Z) LoadLocalNode(stream_expr_pos, stream_var));
 | 
| +  async_star_listen_helper_args->Add(
 | 
| +      new (Z) LoadLocalNode(stream_expr_pos, async_op_var));
 | 
| +  StaticCallNode* async_star_listen_helper_call = new (Z) StaticCallNode(
 | 
| +      stream_expr_pos, async_star_listen_helper, async_star_listen_helper_args);
 | 
| +
 | 
| +  current_block_->statements->Add(async_star_listen_helper_call);
 | 
| +
 | 
|    // Build creation of implicit StreamIterator.
 | 
|    // var :for-in-iter = new StreamIterator(stream_expr).
 | 
|    const Class& stream_iterator_cls =
 | 
| @@ -9076,7 +9133,7 @@ AstNode* Parser::ParseAwaitForStatement(String* label_name) {
 | 
|        stream_iterator_cls.LookupFunction(Symbols::StreamIteratorConstructor()));
 | 
|    ASSERT(!iterator_ctor.IsNull());
 | 
|    ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos);
 | 
| -  ctor_args->Add(stream_expr);
 | 
| +  ctor_args->Add(new (Z) LoadLocalNode(stream_expr_pos, stream_var));
 | 
|    ConstructorCallNode* ctor_call = new (Z) ConstructorCallNode(
 | 
|        stream_expr_pos, TypeArguments::ZoneHandle(Z), iterator_ctor, ctor_args);
 | 
|    const AbstractType& iterator_type = Object::dynamic_type();
 | 
| 
 |