| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 <map> | 5 #include <map> |
| 6 #include <set> | 6 #include <set> |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "vm/kernel_to_il.h" | 9 #include "vm/kernel_to_il.h" |
| 10 | 10 |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 (depth_.function_ == 0) ? &result_->yield_context_variable : &temp, | 713 (depth_.function_ == 0) ? &result_->yield_context_variable : &temp, |
| 714 Symbols::AwaitContextVar()); | 714 Symbols::AwaitContextVar()); |
| 715 } | 715 } |
| 716 { | 716 { |
| 717 LocalVariable* temp = | 717 LocalVariable* temp = |
| 718 scope_->LookupVariable(Symbols::AsyncOperation(), true); | 718 scope_->LookupVariable(Symbols::AsyncOperation(), true); |
| 719 if (temp != NULL) { | 719 if (temp != NULL) { |
| 720 scope_->CaptureVariable(temp); | 720 scope_->CaptureVariable(temp); |
| 721 } | 721 } |
| 722 } | 722 } |
| 723 if (FLAG_causal_async_stacks) { | |
| 724 // TODO(28777): Either remove the variable here, or update the dart side | |
| 725 // so we don't always generate it if this flag is not set. | |
| 726 LocalVariable* temp = | |
| 727 scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true); | |
| 728 if (temp != NULL) { | |
| 729 scope_->CaptureVariable(temp); | |
| 730 } | |
| 731 } | |
| 732 } | 723 } |
| 733 } | 724 } |
| 734 | 725 |
| 735 | 726 |
| 736 void ScopeBuilder::VisitYieldStatement(YieldStatement* node) { | 727 void ScopeBuilder::VisitYieldStatement(YieldStatement* node) { |
| 737 ASSERT(node->is_native()); | 728 ASSERT(node->is_native()); |
| 738 if (depth_.function_ == 0) { | 729 if (depth_.function_ == 0) { |
| 739 AddSwitchVariable(); | 730 AddSwitchVariable(); |
| 740 // Promote all currently visible local variables into the context. | 731 // Promote all currently visible local variables into the context. |
| 741 // TODO(27590) CaptureLocalVariables promotes to many variables into | 732 // TODO(27590) CaptureLocalVariables promotes to many variables into |
| (...skipping 1815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2557 Value* value = Pop(); | 2548 Value* value = Pop(); |
| 2558 ASSERT(stack_ == NULL); | 2549 ASSERT(stack_ == NULL); |
| 2559 | 2550 |
| 2560 const Function& function = parsed_function_->function(); | 2551 const Function& function = parsed_function_->function(); |
| 2561 if (FLAG_support_debugger && position.IsDebugPause() && | 2552 if (FLAG_support_debugger && position.IsDebugPause() && |
| 2562 !function.is_native()) { | 2553 !function.is_native()) { |
| 2563 instructions <<= | 2554 instructions <<= |
| 2564 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); | 2555 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); |
| 2565 } | 2556 } |
| 2566 | 2557 |
| 2567 if (FLAG_causal_async_stacks && | |
| 2568 function.name() == Symbols::AsyncOperation().raw()) { | |
| 2569 // We are returning from an asynchronous closure. Before we do that, be | |
| 2570 // sure to clear the thread's asynchronous stack trace. | |
| 2571 const Function& target = Function::ZoneHandle( | |
| 2572 Z, I->object_store()->async_clear_thread_stack_trace()); | |
| 2573 ASSERT(!target.IsNull()); | |
| 2574 instructions += StaticCall(TokenPosition::kNoSource, target, 0); | |
| 2575 instructions += Drop(); | |
| 2576 } | |
| 2577 | |
| 2578 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); | 2558 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); |
| 2579 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); | 2559 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); |
| 2580 | 2560 |
| 2581 instructions <<= return_instr; | 2561 instructions <<= return_instr; |
| 2582 | 2562 |
| 2583 return instructions.closed(); | 2563 return instructions.closed(); |
| 2584 } | 2564 } |
| 2585 | 2565 |
| 2586 | 2566 |
| 2587 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, | 2567 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3184 body += NullConstant(); | 3164 body += NullConstant(); |
| 3185 body += Return(dart_function.end_token_pos()); | 3165 body += Return(dart_function.end_token_pos()); |
| 3186 } | 3166 } |
| 3187 | 3167 |
| 3188 // If functions body contains any yield points build switch statement that | 3168 // If functions body contains any yield points build switch statement that |
| 3189 // selects a continuation point based on the value of :await_jump_var. | 3169 // selects a continuation point based on the value of :await_jump_var. |
| 3190 if (!yield_continuations_.is_empty()) { | 3170 if (!yield_continuations_.is_empty()) { |
| 3191 // The code we are building will be executed right after we enter | 3171 // The code we are building will be executed right after we enter |
| 3192 // the function and before any nested contexts are allocated. | 3172 // the function and before any nested contexts are allocated. |
| 3193 // Reset current context_depth_ to match this. | 3173 // Reset current context_depth_ to match this. |
| 3194 const intptr_t current_context_depth = context_depth_; | 3174 intptr_t current_context_depth = context_depth_; |
| 3195 context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); | 3175 context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); |
| 3196 | 3176 |
| 3197 // Prepend an entry corresponding to normal entry to the function. | 3177 // Prepend an entry corresponding to normal entry to the function. |
| 3198 yield_continuations_.InsertAt( | 3178 yield_continuations_.InsertAt( |
| 3199 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL), | 3179 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL), |
| 3200 CatchClauseNode::kInvalidTryIndex)); | 3180 CatchClauseNode::kInvalidTryIndex)); |
| 3201 yield_continuations_[0].entry->LinkTo(body.entry); | 3181 yield_continuations_[0].entry->LinkTo(body.entry); |
| 3202 | 3182 |
| 3203 // Build a switch statement. | 3183 // Build a switch statement. |
| 3204 Fragment dispatch; | 3184 Fragment dispatch; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3250 | 3230 |
| 3251 // False branch will contain the next comparison. | 3231 // False branch will contain the next comparison. |
| 3252 dispatch = Fragment(dispatch.entry, otherwise); | 3232 dispatch = Fragment(dispatch.entry, otherwise); |
| 3253 block = otherwise; | 3233 block = otherwise; |
| 3254 } | 3234 } |
| 3255 body = dispatch; | 3235 body = dispatch; |
| 3256 | 3236 |
| 3257 context_depth_ = current_context_depth; | 3237 context_depth_ = current_context_depth; |
| 3258 } | 3238 } |
| 3259 | 3239 |
| 3260 if (FLAG_causal_async_stacks && | |
| 3261 dart_function.name() == Symbols::AsyncOperation().raw()) { | |
| 3262 // The code we are building will be executed right after we enter | |
| 3263 // the function and before any nested contexts are allocated. | |
| 3264 // Reset current context_depth_ to match this. | |
| 3265 const intptr_t current_context_depth = context_depth_; | |
| 3266 context_depth_ = scopes_->yield_jump_variable->owner()->context_level(); | |
| 3267 | |
| 3268 Fragment instructions; | |
| 3269 LocalScope* scope = parsed_function_->node_sequence()->scope(); | |
| 3270 | |
| 3271 const Function& target = Function::ZoneHandle( | |
| 3272 Z, I->object_store()->async_set_thread_stack_trace()); | |
| 3273 ASSERT(!target.IsNull()); | |
| 3274 | |
| 3275 // Fetch and load :async_stack_trace | |
| 3276 LocalVariable* async_stack_trace_var = | |
| 3277 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); | |
| 3278 ASSERT((async_stack_trace_var != NULL) && | |
| 3279 async_stack_trace_var->is_captured()); | |
| 3280 instructions += LoadLocal(async_stack_trace_var); | |
| 3281 instructions += PushArgument(); | |
| 3282 | |
| 3283 // Call _asyncSetThreadStackTrace | |
| 3284 instructions += StaticCall(TokenPosition::kNoSource, target, 1); | |
| 3285 instructions += Drop(); | |
| 3286 | |
| 3287 body = instructions + body; | |
| 3288 context_depth_ = current_context_depth; | |
| 3289 } | |
| 3290 | |
| 3291 if (FLAG_support_debugger && function->position().IsDebugPause() && | 3240 if (FLAG_support_debugger && function->position().IsDebugPause() && |
| 3292 !dart_function.is_native() && dart_function.is_debuggable()) { | 3241 !dart_function.is_native() && dart_function.is_debuggable()) { |
| 3293 // If a switch was added above: Start the switch by injecting a debugable | 3242 // If a switch was added above: Start the switch by injecting a debugable |
| 3294 // safepoint so stepping over an await works. | 3243 // safepoint so stepping over an await works. |
| 3295 // If not, still start the body with a debugable safepoint to ensure | 3244 // If not, still start the body with a debugable safepoint to ensure |
| 3296 // breaking on a method always happens, even if there are no | 3245 // breaking on a method always happens, even if there are no |
| 3297 // assignments/calls/runtimecalls in the first basic block. | 3246 // assignments/calls/runtimecalls in the first basic block. |
| 3298 // Place this check at the last parameter to ensure parameters | 3247 // Place this check at the last parameter to ensure parameters |
| 3299 // are in scope in the debugger at method entry. | 3248 // are in scope in the debugger at method entry. |
| 3300 const int num_params = dart_function.NumParameters(); | 3249 const int num_params = dart_function.NumParameters(); |
| (...skipping 3030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6331 thread->clear_sticky_error(); | 6280 thread->clear_sticky_error(); |
| 6332 return error.raw(); | 6281 return error.raw(); |
| 6333 } | 6282 } |
| 6334 } | 6283 } |
| 6335 | 6284 |
| 6336 | 6285 |
| 6337 } // namespace kernel | 6286 } // namespace kernel |
| 6338 } // namespace dart | 6287 } // namespace dart |
| 6339 | 6288 |
| 6340 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6289 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |