| Index: runtime/vm/parser.cc
|
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
|
| index d80d951afc0fab08637eb1c456a4d57f554acaa2..ebc5308d1e8a6301b36fab2159365ad28b961ca9 100644
|
| --- a/runtime/vm/parser.cc
|
| +++ b/runtime/vm/parser.cc
|
| @@ -5426,7 +5426,6 @@ void Parser::OpenFunctionBlock(const Function& func) {
|
| void Parser::OpenAsyncClosure() {
|
| TRACE_PARSER("OpenAsyncClosure");
|
| parsed_function()->set_await_temps_scope(current_block_->scope);
|
| - // TODO(mlippautz): Set up explicit jump table for await continuations.
|
| }
|
|
|
|
|
| @@ -5523,6 +5522,8 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
|
| // Add to AST:
|
| // var :async_op;
|
| // var :async_completer;
|
| + // var :await_jump_var;
|
| + // var :await_ctx_var;
|
| LocalVariable* async_op_var = new (I) LocalVariable(
|
| Scanner::kNoSourcePos,
|
| Symbols::AsyncOperation(),
|
| @@ -5537,11 +5538,25 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
|
| current_block_->scope->AddVariable(async_completer);
|
| found = closure_body->scope()->CaptureVariable(Symbols::AsyncCompleter());
|
| ASSERT(found);
|
| + LocalVariable* await_jump_var = new (I) LocalVariable(
|
| + Scanner::kNoSourcePos,
|
| + Symbols::AwaitJumpVar(),
|
| + Type::ZoneHandle(I, Type::DynamicType()));
|
| + current_block_->scope->AddVariable(await_jump_var);
|
| + found = closure_body->scope()->CaptureVariable(Symbols::AwaitJumpVar());
|
| + ASSERT(found);
|
| + LocalVariable* await_ctx_var = new (I) LocalVariable(
|
| + Scanner::kNoSourcePos,
|
| + Symbols::AwaitContextVar(),
|
| + Type::ZoneHandle(I, Type::DynamicType()));
|
| + current_block_->scope->AddVariable(await_ctx_var);
|
| + found = closure_body->scope()->CaptureVariable(Symbols::AwaitContextVar());
|
| + ASSERT(found);
|
|
|
| // Add to AST:
|
| // :async_completer = new Completer();
|
| - ArgumentListNode* empty_args = new (I) ArgumentListNode(
|
| - Scanner::kNoSourcePos);
|
| + ArgumentListNode* empty_args =
|
| + new (I) ArgumentListNode(Scanner::kNoSourcePos);
|
| ConstructorCallNode* completer_constructor_node = new (I) ConstructorCallNode(
|
| Scanner::kNoSourcePos,
|
| TypeArguments::ZoneHandle(I),
|
| @@ -5592,6 +5607,13 @@ void Parser::CloseAsyncClosure(SequenceNode* body) {
|
| TRACE_PARSER("CloseAsyncClosure");
|
| // We need a temporary expression to store intermediate return values.
|
| parsed_function()->EnsureExpressionTemp();
|
| + // Implicitly mark those variables below as captured. We currently mark all
|
| + // variables of all scopes as captured (below), but as soon as we do something
|
| + // smarter we rely on these internal variables to be available.
|
| + body->scope()->LookupVariable(Symbols::Completer(), false);
|
| + body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
|
| + body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
|
| + body->scope()->RecursivelyCaptureAllVariables();
|
| }
|
|
|
|
|
|
|