OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1124 // However, factories may create an instance of the wrong type. | 1124 // However, factories may create an instance of the wrong type. |
1125 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { | 1125 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { |
1126 const AbstractType& dst_type = | 1126 const AbstractType& dst_type = |
1127 AbstractType::ZoneHandle(Z, function.result_type()); | 1127 AbstractType::ZoneHandle(Z, function.result_type()); |
1128 return_value = | 1128 return_value = |
1129 BuildAssignableValue(node->value()->token_pos(), return_value, | 1129 BuildAssignableValue(node->value()->token_pos(), return_value, |
1130 dst_type, Symbols::FunctionResult()); | 1130 dst_type, Symbols::FunctionResult()); |
1131 } | 1131 } |
1132 } | 1132 } |
1133 | 1133 |
1134 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { | |
rmacnak
2017/01/26 18:05:57
&& FLAG_sane_async_stacks
Cutch
2017/01/31 23:45:31
Done.
| |
1135 // We are returning from an asynchronous closure. Before we do that, be | |
1136 // sure to clear the thread's asynchronous stack trace. | |
1137 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | |
1138 ASSERT(!async_lib.IsNull()); | |
1139 const String& private_name = String::ZoneHandle( | |
1140 async_lib.PrivateName(Symbols::ClearAsyncThreadStackTrace())); | |
1141 ASSERT(!private_name.IsNull()); | |
1142 const Function& async_clear_thread_stack_trace = Function::ZoneHandle( | |
1143 Z, | |
1144 Resolver::ResolveStatic(async_lib, String::ZoneHandle(String::null()), | |
rmacnak
2017/01/26 18:05:57
It might be worth caching the three helper functio
Cutch
2017/01/31 23:45:31
Done.
| |
1145 private_name, 0, Object::null_array())); | |
1146 ASSERT(!async_clear_thread_stack_trace.IsNull()); | |
1147 // Mark that this function is not debuggable. | |
1148 async_clear_thread_stack_trace.set_is_debuggable(false); | |
rmacnak
2017/01/26 18:05:57
I thought we can't step into native functions anyw
Cutch
2017/01/31 23:45:30
Acknowledged.
| |
1149 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = | |
1150 new (Z) ZoneGrowableArray<PushArgumentInstr*>(0); | |
1151 StaticCallInstr* call_async_clear_thread_stack_trace = new (Z) | |
1152 StaticCallInstr(node->token_pos().ToSynthetic(), | |
1153 async_clear_thread_stack_trace, Object::null_array(), | |
1154 no_arguments, owner()->ic_data_array()); | |
1155 Do(call_async_clear_thread_stack_trace); | |
1156 } | |
1157 | |
1134 // Async functions contain two types of return statements: | 1158 // Async functions contain two types of return statements: |
1135 // 1) Returns that should complete the completer once all finally blocks have | 1159 // 1) Returns that should complete the completer once all finally blocks have |
1136 // been inlined (call: :async_completer.complete(return_value)). These | 1160 // been inlined (call: :async_completer.complete(return_value)). These |
1137 // returns end up returning null in the end. | 1161 // returns end up returning null in the end. |
1138 // 2) "Continuation" returns that should not complete the completer but return | 1162 // 2) "Continuation" returns that should not complete the completer but return |
1139 // the value. | 1163 // the value. |
1140 // | 1164 // |
1141 // We distinguish those kinds of nodes via is_regular_return(). | 1165 // We distinguish those kinds of nodes via is_regular_return(). |
1142 // | 1166 // |
1143 if (function.IsAsyncClosure() && | 1167 if (function.IsAsyncClosure() && |
(...skipping 2636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3780 // the function. | 3804 // the function. |
3781 Value* null_constant = Bind( | 3805 Value* null_constant = Bind( |
3782 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); | 3806 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); |
3783 Do(BuildStoreLocal(*temp_local, null_constant, | 3807 Do(BuildStoreLocal(*temp_local, null_constant, |
3784 ST(node->token_pos()))); | 3808 ST(node->token_pos()))); |
3785 } | 3809 } |
3786 } | 3810 } |
3787 } | 3811 } |
3788 } | 3812 } |
3789 | 3813 |
3814 if (is_top_level_sequence && | |
3815 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { | |
rmacnak
2017/01/26 18:05:57
&& FLAG_sane_async_stacks
Cutch
2017/01/31 23:45:30
Done.
| |
3816 LocalScope* top_scope = node->scope(); | |
3817 // Fetch the :async_stack_trace variable and store it into the thread. | |
3818 LocalVariable* async_stack_trace_var = | |
3819 top_scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); | |
3820 ASSERT((async_stack_trace_var != NULL) && | |
3821 async_stack_trace_var->is_captured()); | |
3822 // Load :async_stack_trace | |
3823 Value* async_stack_trace_value = Bind(BuildLoadLocal( | |
3824 *async_stack_trace_var, node->token_pos().ToSynthetic())); | |
3825 // Setup arguments for _asyncSetThreadStackTrace. | |
3826 ZoneGrowableArray<PushArgumentInstr*>* arguments = | |
3827 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); | |
3828 arguments->Add(PushArgument(async_stack_trace_value)); | |
3829 | |
3830 // Lookup _asyncSetThreadStackTrace | |
3831 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | |
3832 ASSERT(!async_lib.IsNull()); | |
3833 const String& private_name = String::ZoneHandle( | |
3834 async_lib.PrivateName(Symbols::SetAsyncThreadStackTrace())); | |
3835 ASSERT(!private_name.IsNull()); | |
3836 const Function& async_set_thread_stack_trace = Function::ZoneHandle( | |
3837 Z, | |
3838 Resolver::ResolveStatic(async_lib, String::ZoneHandle(String::null()), | |
3839 private_name, 1, Object::null_array())); | |
siva
2017/01/26 19:26:23
Agree with Ryan might be worth caching these funct
Cutch
2017/01/31 23:45:30
Done.
| |
3840 ASSERT(!async_set_thread_stack_trace.IsNull()); | |
3841 // Mark that this function is not debuggable. | |
3842 async_set_thread_stack_trace.set_is_debuggable(false); | |
3843 // Call _asyncSetThreadStackTrace | |
3844 StaticCallInstr* call_async_set_thread_stack_trace = new (Z) | |
3845 StaticCallInstr(node->token_pos().ToSynthetic(), | |
3846 async_set_thread_stack_trace, Object::null_array(), | |
3847 arguments, owner()->ic_data_array()); | |
3848 Do(call_async_set_thread_stack_trace); | |
3849 } | |
3850 | |
3851 | |
3790 if (FLAG_support_debugger && is_top_level_sequence && | 3852 if (FLAG_support_debugger && is_top_level_sequence && |
3791 function.is_debuggable()) { | 3853 function.is_debuggable()) { |
3792 // Place a debug check at method entry to ensure breaking on a method always | 3854 // Place a debug check at method entry to ensure breaking on a method always |
3793 // happens, even if there are no assignments/calls/runtimecalls in the first | 3855 // happens, even if there are no assignments/calls/runtimecalls in the first |
3794 // basic block. Place this check at the last parameter to ensure parameters | 3856 // basic block. Place this check at the last parameter to ensure parameters |
3795 // are in scope in the debugger at method entry. | 3857 // are in scope in the debugger at method entry. |
3796 const int num_params = function.NumParameters(); | 3858 const int num_params = function.NumParameters(); |
3797 TokenPosition check_pos = TokenPosition::kNoSource; | 3859 TokenPosition check_pos = TokenPosition::kNoSource; |
3798 if (num_params > 0) { | 3860 if (num_params > 0) { |
3799 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 3861 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4333 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); | 4395 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); |
4334 ASSERT(found); | 4396 ASSERT(found); |
4335 } | 4397 } |
4336 | 4398 |
4337 | 4399 |
4338 void FlowGraphBuilder::Bailout(const char* reason) const { | 4400 void FlowGraphBuilder::Bailout(const char* reason) const { |
4339 parsed_function_.Bailout("FlowGraphBuilder", reason); | 4401 parsed_function_.Bailout("FlowGraphBuilder", reason); |
4340 } | 4402 } |
4341 | 4403 |
4342 } // namespace dart | 4404 } // namespace dart |
OLD | NEW |