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) { |