| Index: runtime/vm/parser.cc
|
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
|
| index 731c13fbc007bc438cb47ca52008b64ba03195d6..21ca85bda9b68402545174bc87600ca1e97c5f54 100644
|
| --- a/runtime/vm/parser.cc
|
| +++ b/runtime/vm/parser.cc
|
| @@ -3490,7 +3490,7 @@ SequenceNode* Parser::ParseFunc(const Function& func) {
|
| body = CloseSyncGenFunction(generated_body_closure, body);
|
| generated_body_closure.set_end_token_pos(end_token_pos);
|
| } else if (func.IsSyncGenClosure()) {
|
| - body->scope()->RecursivelyCaptureAllVariables();
|
| + // body is unchanged.
|
| } else if (func.IsAsyncGenerator()) {
|
| body = CloseAsyncGeneratorFunction(generated_body_closure, body);
|
| generated_body_closure.set_end_token_pos(end_token_pos);
|
| @@ -6319,8 +6319,8 @@ SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) {
|
| no_args));
|
|
|
| // Suspend after the close.
|
| - AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
|
| - await_marker->set_scope(current_block_->scope);
|
| + AwaitMarkerNode* await_marker =
|
| + new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
|
| current_block_->statements->Add(await_marker);
|
| ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos);
|
| continuation_ret->set_return_type(ReturnNode::kContinuationTarget);
|
| @@ -6609,6 +6609,8 @@ RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) {
|
|
|
| SequenceNode* Parser::CloseSyncGenFunction(const Function& closure,
|
| SequenceNode* closure_body) {
|
| + // Explicitly reference variables of the sync generator function from the
|
| + // closure body in order to mark them as captured.
|
| LocalVariable* existing_var =
|
| closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
|
| ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| @@ -6754,11 +6756,9 @@ void Parser::AddContinuationVariables() {
|
| LocalVariable* await_jump_var = new (Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type);
|
| current_block_->scope->AddVariable(await_jump_var);
|
| - current_block_->scope->CaptureVariable(await_jump_var);
|
| LocalVariable* await_ctx_var = new (Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type);
|
| current_block_->scope->AddVariable(await_ctx_var);
|
| - current_block_->scope->CaptureVariable(await_ctx_var);
|
| }
|
|
|
|
|
| @@ -6772,19 +6772,15 @@ void Parser::AddAsyncClosureVariables() {
|
| LocalVariable* async_op_var = new(Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
|
| current_block_->scope->AddVariable(async_op_var);
|
| - current_block_->scope->CaptureVariable(async_op_var);
|
| LocalVariable* async_then_callback_var = new(Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
|
| current_block_->scope->AddVariable(async_then_callback_var);
|
| - current_block_->scope->CaptureVariable(async_then_callback_var);
|
| LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
|
| current_block_->scope->AddVariable(async_catch_error_callback_var);
|
| - current_block_->scope->CaptureVariable(async_catch_error_callback_var);
|
| LocalVariable* async_completer = new(Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
|
| current_block_->scope->AddVariable(async_completer);
|
| - current_block_->scope->CaptureVariable(async_completer);
|
| }
|
|
|
|
|
| @@ -6803,19 +6799,15 @@ void Parser::AddAsyncGeneratorVariables() {
|
| LocalVariable* controller_var = new(Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
|
| current_block_->scope->AddVariable(controller_var);
|
| - current_block_->scope->CaptureVariable(controller_var);
|
| LocalVariable* async_op_var = new(Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
|
| current_block_->scope->AddVariable(async_op_var);
|
| - current_block_->scope->CaptureVariable(async_op_var);
|
| LocalVariable* async_then_callback_var = new(Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
|
| current_block_->scope->AddVariable(async_then_callback_var);
|
| - current_block_->scope->CaptureVariable(async_then_callback_var);
|
| LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
|
| Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
|
| current_block_->scope->AddVariable(async_catch_error_callback_var);
|
| - current_block_->scope->CaptureVariable(async_catch_error_callback_var);
|
| }
|
|
|
|
|
| @@ -6907,8 +6899,8 @@ SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func,
|
| ASSERT(!closure_func.IsNull());
|
| ASSERT(closure_body != NULL);
|
|
|
| - // Make sure the implicit variables of the async generator function
|
| - // are captured.
|
| + // Explicitly reference variables of the async genenerator function from the
|
| + // closure body in order to mark them as captured.
|
| LocalVariable* existing_var = closure_body->scope()->LookupVariable(
|
| Symbols::AwaitJumpVar(), false);
|
| ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| @@ -7046,29 +7038,6 @@ SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) {
|
| SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body);
|
| ASSERT(new_body != NULL);
|
| ASSERT(new_body->scope() != NULL);
|
| -
|
| - // Implicitly mark those variables below as captured. We currently mark all
|
| - // variables of all scopes as captured, but as soon as we do something
|
| - // smarter we rely on these internal variables to be available.
|
| - LocalVariable* existing_var = new_body->scope()->LookupVariable(
|
| - Symbols::AwaitJumpVar(), false);
|
| - ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| - existing_var = new_body->scope()->LookupVariable(
|
| - Symbols::AwaitContextVar(), false);
|
| - ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| - existing_var = new_body->scope()->LookupVariable(
|
| - Symbols::Controller(), false);
|
| - ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| - existing_var = new_body->scope()->LookupVariable(
|
| - Symbols::AsyncOperationParam(), false);
|
| - ASSERT(existing_var != NULL);
|
| - existing_var = new_body->scope()->LookupVariable(
|
| - Symbols::AsyncOperationErrorParam(), false);
|
| - ASSERT(existing_var != NULL);
|
| - existing_var = new_body->scope()->LookupVariable(
|
| - Symbols::AsyncOperationStackTraceParam(), false);
|
| - ASSERT(existing_var != NULL);
|
| - new_body->scope()->RecursivelyCaptureAllVariables();
|
| return new_body;
|
| }
|
|
|
| @@ -7108,6 +7077,8 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
|
| ASSERT(!closure.IsNull());
|
| ASSERT(closure_body != NULL);
|
|
|
| + // Explicitly reference variables of the async function from the
|
| + // closure body in order to mark them as captured.
|
| LocalVariable* existing_var =
|
| closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
|
| ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| @@ -7251,22 +7222,10 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
|
| SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) {
|
| // 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.
|
| +
|
| SequenceNode* new_body = CloseAsyncTryBlock(body);
|
| ASSERT(new_body != NULL);
|
| ASSERT(new_body->scope() != NULL);
|
| - LocalVariable* existing_var =
|
| - new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
|
| - ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| - existing_var =
|
| - new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
|
| - ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| - existing_var =
|
| - new_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
|
| - ASSERT((existing_var != NULL) && existing_var->is_captured());
|
| - new_body->scope()->RecursivelyCaptureAllVariables();
|
| return new_body;
|
| }
|
|
|
| @@ -8543,7 +8502,7 @@ static LocalVariable* LookupAsyncSavedTryContextVar(LocalScope* scope,
|
| Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
|
| try_index))));
|
| LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name);
|
| - ASSERT((var != NULL) && var->is_captured());
|
| + ASSERT(var != NULL);
|
| return var;
|
| }
|
|
|
| @@ -8735,14 +8694,15 @@ AstNode* Parser::ParseAwaitForStatement(String* label_name) {
|
| new(Z) LoadLocalNode(stream_pos, iterator_var),
|
| Symbols::MoveNext(),
|
| no_args);
|
| + OpenBlock();
|
| AstNode* await_moveNext =
|
| new(Z) AwaitNode(stream_pos,
|
| iterator_moveNext,
|
| saved_try_ctx,
|
| async_saved_try_ctx,
|
| outer_saved_try_ctx,
|
| - outer_async_saved_try_ctx);
|
| - OpenBlock();
|
| + outer_async_saved_try_ctx,
|
| + current_block_->scope);
|
| AwaitTransformer at(current_block_->statements, async_temp_scope_);
|
| await_moveNext = at.Transform(await_moveNext);
|
| SequenceNode* await_preamble = CloseBlock();
|
| @@ -9574,7 +9534,6 @@ void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) {
|
| Type::ZoneHandle(Z, Type::DynamicType()));
|
| ASSERT(async_temp_scope_ != NULL);
|
| async_temp_scope_->AddVariable(async_saved_try_ctx);
|
| - current_block_->scope->CaptureVariable(async_saved_try_ctx);
|
| ASSERT(saved_try_context != NULL);
|
| current_block_->statements->Add(new(Z) StoreLocalNode(
|
| Scanner::kNoSourcePos,
|
| @@ -9908,8 +9867,8 @@ AstNode* Parser::ParseYieldStatement() {
|
| new(Z) LiteralNode(TokenPos(), Bool::True()));
|
| yield->AddNode(set_is_yield_each);
|
| }
|
| - AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
|
| - await_marker->set_scope(current_block_->scope);
|
| + AwaitMarkerNode* await_marker =
|
| + new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
|
| yield->AddNode(await_marker);
|
| // Return true to indicate that a value has been generated.
|
| ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
|
| @@ -9976,8 +9935,8 @@ AstNode* Parser::ParseYieldStatement() {
|
| new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL);
|
| yield->AddNode(if_is_cancelled);
|
|
|
| - AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
|
| - await_marker->set_scope(current_block_->scope);
|
| + AwaitMarkerNode* await_marker =
|
| + new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
|
| yield->AddNode(await_marker);
|
| ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
|
| continuation_return->set_return_type(ReturnNode::kContinuationTarget);
|
| @@ -10997,7 +10956,8 @@ AstNode* Parser::ParseUnaryExpr() {
|
| saved_try_ctx,
|
| async_saved_try_ctx,
|
| outer_saved_try_ctx,
|
| - outer_async_saved_try_ctx);
|
| + outer_async_saved_try_ctx,
|
| + current_block_->scope);
|
| } else if (IsPrefixOperator(CurrentToken())) {
|
| Token::Kind unary_op = CurrentToken();
|
| if (unary_op == Token::kSUB) {
|
|
|