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 "vm/kernel_binary_flowgraph.h" | 5 #include "vm/kernel_binary_flowgraph.h" |
6 | |
7 #include "vm/compiler.h" | 6 #include "vm/compiler.h" |
8 #include "vm/longjump.h" | 7 #include "vm/longjump.h" |
9 #include "vm/object_store.h" | 8 #include "vm/object_store.h" |
10 | 9 |
11 #if !defined(DART_PRECOMPILED_RUNTIME) | 10 #if !defined(DART_PRECOMPILED_RUNTIME) |
12 | 11 |
13 namespace dart { | 12 namespace dart { |
14 namespace kernel { | 13 namespace kernel { |
15 | 14 |
16 #define Z (zone_) | 15 #define Z (zone_) |
(...skipping 1077 matching lines...) Loading... | |
1094 Function& function = Function::Handle(Z, parsed_function_->function().raw()); | 1093 Function& function = Function::Handle(Z, parsed_function_->function().raw()); |
1095 while (function.IsClosureFunction()) { | 1094 while (function.IsClosureFunction()) { |
1096 function = function.parent_function(); | 1095 function = function.parent_function(); |
1097 } | 1096 } |
1098 | 1097 |
1099 if (function.IsFactory()) { | 1098 if (function.IsFactory()) { |
1100 // The type argument vector is passed as the very first argument to the | 1099 // The type argument vector is passed as the very first argument to the |
1101 // factory constructor function. | 1100 // factory constructor function. |
1102 HandleSpecialLoad(&result_->type_arguments_variable, | 1101 HandleSpecialLoad(&result_->type_arguments_variable, |
1103 Symbols::TypeArgumentsParameter()); | 1102 Symbols::TypeArgumentsParameter()); |
1104 } else { | 1103 } else if (!function.IsGeneric()) { |
1105 // The type argument vector is stored on the instance object. We therefore | 1104 // TODO(sjindel): Kernel generic methods undone. Currently we only support |
1106 // need to capture `this`. | 1105 // generic toplevel methods. For no special load needs to be prepared for |
1106 // these, because the 'LocalVariable' for the type arguments is set on the | |
1107 // 'ParsedFunction' directly. So we do nothing for generic methods. | |
1108 | |
1109 // The type argument vector is stored on the | |
1110 // instance object. We therefore need to capture `this`. | |
1107 HandleSpecialLoad(&result_->this_variable, Symbols::This()); | 1111 HandleSpecialLoad(&result_->this_variable, Symbols::This()); |
1108 } | 1112 } |
1109 | 1113 |
1110 builder_->ReadUInt(); // read index for parameter. | 1114 builder_->ReadUInt(); // read index for parameter. |
1111 builder_->SkipOptionalDartType(); // read bound bound. | 1115 builder_->SkipOptionalDartType(); // read bound bound. |
1112 } | 1116 } |
1113 | 1117 |
1114 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { | 1118 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { |
1115 // "Peek" ahead into the function node | 1119 // "Peek" ahead into the function node |
1116 intptr_t offset = builder_->ReaderOffset(); | 1120 intptr_t offset = builder_->ReaderOffset(); |
(...skipping 506 matching lines...) Loading... | |
1623 } | 1627 } |
1624 parameter_index -= class_types.Length(); | 1628 parameter_index -= class_types.Length(); |
1625 } | 1629 } |
1626 | 1630 |
1627 intptr_t procedure_type_parameter_count = | 1631 intptr_t procedure_type_parameter_count = |
1628 active_class_->MemberIsProcedure() | 1632 active_class_->MemberIsProcedure() |
1629 ? active_class_->MemberTypeParameterCount(Z) | 1633 ? active_class_->MemberTypeParameterCount(Z) |
1630 : 0; | 1634 : 0; |
1631 if (procedure_type_parameter_count > 0) { | 1635 if (procedure_type_parameter_count > 0) { |
1632 if (procedure_type_parameter_count > parameter_index) { | 1636 if (procedure_type_parameter_count > parameter_index) { |
1633 // Here we technically could load the correct one via something like | 1637 if (FLAG_reify_generic_functions) { |
1634 // result_ ^= dart::TypeArguments::Handle( | 1638 result_ ^= dart::TypeArguments::Handle( |
1635 // Z, active_class_->member->type_parameters()) | 1639 Z, active_class_->member->type_parameters()) |
1636 // .TypeAt(parameter_index); | 1640 .TypeAt(parameter_index); |
1637 // but that isn't currently supported elsewhere | 1641 } else { |
1638 // (FlowGraphBuilder::LoadFunctionTypeArguments()). | 1642 result_ ^= dart::Type::DynamicType(); |
1639 result_ ^= dart::Type::DynamicType(); | 1643 } |
1640 return; | 1644 return; |
1641 } | 1645 } |
1642 parameter_index -= procedure_type_parameter_count; | 1646 parameter_index -= procedure_type_parameter_count; |
1643 } | 1647 } |
1644 } | 1648 } |
1645 | 1649 |
1646 if (type_parameter_scope_ != NULL && parameter_index >= 0 && | 1650 if (type_parameter_scope_ != NULL && parameter_index >= 0 && |
1647 parameter_index < type_parameter_scope_->outer_parameter_count() + | 1651 parameter_index < type_parameter_scope_->outer_parameter_count() + |
1648 type_parameter_scope_->parameter_count()) { | 1652 type_parameter_scope_->parameter_count()) { |
1649 result_ ^= dart::Type::DynamicType(); | 1653 result_ ^= dart::Type::DynamicType(); |
(...skipping 1324 matching lines...) Loading... | |
2974 const Function& function) { | 2978 const Function& function) { |
2975 const Function& target = Function::ZoneHandle(Z, function.parent_function()); | 2979 const Function& target = Function::ZoneHandle(Z, function.parent_function()); |
2976 | 2980 |
2977 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); | 2981 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); |
2978 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( | 2982 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( |
2979 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId); | 2983 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId); |
2980 SetupDefaultParameterValues(); | 2984 SetupDefaultParameterValues(); |
2981 | 2985 |
2982 Fragment body(normal_entry); | 2986 Fragment body(normal_entry); |
2983 body += flow_graph_builder_->CheckStackOverflowInPrologue(); | 2987 body += flow_graph_builder_->CheckStackOverflowInPrologue(); |
2988 body += NullConstant(); | |
2989 LocalVariable* result = MakeTemporary(); | |
2984 | 2990 |
2985 // Load all the arguments. | 2991 // Load all the arguments. |
2986 ASSERT(target.is_static()); | 2992 ASSERT(target.is_static()); |
2987 | 2993 |
2994 // KERNEL_GENERIC_METHODS_UNDONE(sjindel): Since the frontend can't yet emit | |
Dmitry Stefantsov
2017/08/16 11:44:39
How about creating an issue and using something li
sjindel
2017/08/16 12:57:12
Done.
| |
2995 // generic methods into kernel, all type parameters to the target must come | |
2996 // from the context. When generic methods are fully supported, we will need to | |
2997 // get the type arguments provided by the caller and append them to the | |
2998 // captured type arguments via 'prependTypeArguments'. | |
2999 | |
2988 FunctionNodeHelper function_node_helper(this); | 3000 FunctionNodeHelper function_node_helper(this); |
3001 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters); | |
3002 intptr_t type_param_count = PeekUInt(); | |
2989 function_node_helper.ReadUntilExcluding( | 3003 function_node_helper.ReadUntilExcluding( |
2990 FunctionNodeHelper::kPositionalParameters); | 3004 FunctionNodeHelper::kPositionalParameters); |
2991 | 3005 |
2992 // Positional. | 3006 // Positional. |
2993 const intptr_t positional_argument_count = ReadListLength(); | 3007 const intptr_t positional_argument_count = ReadListLength(); |
2994 | 3008 |
2995 // The first argument is the instance of the closure class. For converted | 3009 // The first argument is the instance of the closure class. For converted |
2996 // closures its context field contains the context vector that is used by the | 3010 // closures its context field contains the context vector that is used by the |
2997 // converted top-level function (target) explicitly and that should be passed | 3011 // converted top-level function (target) explicitly and that should be passed |
2998 // to that function as the first parameter. | 3012 // to that function as the first parameter. |
2999 body += LoadLocal(LookupVariable( | 3013 body += LoadLocal(LookupVariable( |
3000 ReaderOffset() + relative_kernel_offset_)); // 0th variable offset. | 3014 ReaderOffset() + relative_kernel_offset_)); // 0th variable offset. |
3001 body += flow_graph_builder_->LoadField(Closure::context_offset()); | 3015 body += flow_graph_builder_->LoadField(Closure::context_offset()); |
3016 LocalVariable* context = MakeTemporary(); | |
3017 | |
3018 if (type_param_count > 0) { | |
3019 body += LoadLocal(context); | |
3020 body += flow_graph_builder_->LoadField(Context::variable_offset(0)); | |
3021 body += PushArgument(); | |
3022 } | |
3023 | |
3024 body += LoadLocal(context); | |
3002 body += PushArgument(); | 3025 body += PushArgument(); |
3003 SkipVariableDeclaration(); // read 0th variable. | 3026 SkipVariableDeclaration(); // read 0th variable. |
3004 | 3027 |
3005 // The rest of the parameters are the same for the method of the Closure class | 3028 // The rest of the parameters are the same for the method of the Closure class |
3006 // being invoked and the top-level function (target). | 3029 // being invoked and the top-level function (target). |
3007 for (intptr_t i = 1; i < positional_argument_count; i++) { | 3030 for (intptr_t i = 1; i < positional_argument_count; i++) { |
3008 body += LoadLocal(LookupVariable( | 3031 body += LoadLocal(LookupVariable( |
3009 ReaderOffset() + relative_kernel_offset_)); // ith variable offset. | 3032 ReaderOffset() + relative_kernel_offset_)); // ith variable offset. |
3010 body += PushArgument(); | 3033 body += PushArgument(); |
3011 SkipVariableDeclaration(); // read ith variable. | 3034 SkipVariableDeclaration(); // read ith variable. |
(...skipping 12 matching lines...) Loading... | |
3024 | 3047 |
3025 // read ith variable. | 3048 // read ith variable. |
3026 VariableDeclarationHelper helper(this); | 3049 VariableDeclarationHelper helper(this); |
3027 helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); | 3050 helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); |
3028 | 3051 |
3029 argument_names.SetAt(i, H.DartSymbol(helper.name_index_)); | 3052 argument_names.SetAt(i, H.DartSymbol(helper.name_index_)); |
3030 } | 3053 } |
3031 } | 3054 } |
3032 | 3055 |
3033 // Forward them to the target. | 3056 // Forward them to the target. |
3034 const intptr_t argument_count = | 3057 intptr_t argument_count = positional_argument_count + named_argument_count; |
3035 positional_argument_count + named_argument_count; | 3058 if (type_param_count) ++argument_count; |
3036 body += StaticCall(TokenPosition::kNoSource, target, argument_count, | 3059 body += StaticCall(TokenPosition::kNoSource, target, argument_count, |
3037 argument_names); | 3060 argument_names, type_param_count); |
3038 | 3061 |
3039 // Return the result. | 3062 // Return the result. |
3063 body += StoreLocal(TokenPosition::kNoSource, result); | |
3064 body += Drop(); | |
3065 body += Drop(); | |
3040 body += Return(function_node_helper.end_position_); | 3066 body += Return(function_node_helper.end_position_); |
3041 | 3067 |
3042 return new (Z) | 3068 return new (Z) |
3043 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, | 3069 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, |
3044 flow_graph_builder_->next_block_id_ - 1); | 3070 flow_graph_builder_->next_block_id_ - 1); |
3045 } | 3071 } |
3046 | 3072 |
3047 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(bool constructor) { | 3073 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(bool constructor) { |
3048 const Function& dart_function = parsed_function()->function(); | 3074 const Function& dart_function = parsed_function()->function(); |
3049 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); | 3075 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); |
(...skipping 1381 matching lines...) Loading... | |
4431 | 4457 |
4432 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, | 4458 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, |
4433 const Function& target, | 4459 const Function& target, |
4434 intptr_t argument_count) { | 4460 intptr_t argument_count) { |
4435 return flow_graph_builder_->StaticCall(position, target, argument_count); | 4461 return flow_graph_builder_->StaticCall(position, target, argument_count); |
4436 } | 4462 } |
4437 | 4463 |
4438 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, | 4464 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, |
4439 const Function& target, | 4465 const Function& target, |
4440 intptr_t argument_count, | 4466 intptr_t argument_count, |
4441 const Array& argument_names) { | 4467 const Array& argument_names, |
4468 intptr_t type_args_count) { | |
4442 return flow_graph_builder_->StaticCall(position, target, argument_count, | 4469 return flow_graph_builder_->StaticCall(position, target, argument_count, |
4443 argument_names); | 4470 argument_names, type_args_count); |
4444 } | 4471 } |
4445 | 4472 |
4446 Fragment StreamingFlowGraphBuilder::InstanceCall( | 4473 Fragment StreamingFlowGraphBuilder::InstanceCall( |
4447 TokenPosition position, | 4474 TokenPosition position, |
4448 const dart::String& name, | 4475 const dart::String& name, |
4449 Token::Kind kind, | 4476 Token::Kind kind, |
4450 intptr_t argument_count, | 4477 intptr_t argument_count, |
4451 intptr_t checked_argument_count) { | 4478 intptr_t checked_argument_count) { |
4452 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, | 4479 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, |
4453 checked_argument_count); | 4480 checked_argument_count); |
(...skipping 1397 matching lines...) Loading... | |
5851 instructions += Constant(function); | 5878 instructions += Constant(function); |
5852 instructions += | 5879 instructions += |
5853 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset()); | 5880 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset()); |
5854 | 5881 |
5855 instructions += LoadLocal(closure); | 5882 instructions += LoadLocal(closure); |
5856 instructions += LoadLocal(context); | 5883 instructions += LoadLocal(context); |
5857 instructions += | 5884 instructions += |
5858 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset()); | 5885 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset()); |
5859 | 5886 |
5860 instructions += Drop(); | 5887 instructions += Drop(); |
5888 SkipDartType(); // skip function type of the closure. | |
5861 | 5889 |
5862 SkipDartType(); // skip function type of the closure. | 5890 // TODO(sjindel): Kernel generic methods undone. When generic methods are |
5863 SkipListOfDartTypes(); // skip list of type arguments. | 5891 // fully supported in kernel, we'll need to store a NULL in the type arguments |
5892 // slot when type arguments are absent, so the wrapper for the target function | |
5893 // can tell how many type args are captured vs. provided by the caller of the | |
5894 // closure. | |
5895 | |
5896 intptr_t types_count = ReadListLength(); // read type count. | |
5897 if (types_count > 0) { | |
5898 instructions += LoadLocal(context); | |
5899 | |
5900 const TypeArguments& type_args = | |
5901 T.BuildTypeArguments(types_count); // read list of type arguments. | |
5902 instructions += TranslateInstantiatedTypeArguments(type_args); | |
5903 | |
5904 instructions += StoreInstanceField(TokenPosition::kNoSource, | |
5905 Context::variable_offset(0)); | |
5906 } | |
5864 | 5907 |
5865 return instructions; | 5908 return instructions; |
5866 } | 5909 } |
5867 | 5910 |
5868 Fragment StreamingFlowGraphBuilder::BuildInvalidStatement() { | 5911 Fragment StreamingFlowGraphBuilder::BuildInvalidStatement() { |
5869 H.ReportError("Invalid statements not implemented yet!"); | 5912 H.ReportError("Invalid statements not implemented yet!"); |
5870 return Fragment(); | 5913 return Fragment(); |
5871 } | 5914 } |
5872 | 5915 |
5873 Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() { | 5916 Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() { |
(...skipping 1375 matching lines...) Loading... | |
7249 } | 7292 } |
7250 } | 7293 } |
7251 | 7294 |
7252 return Array::Handle(Array::null()); | 7295 return Array::Handle(Array::null()); |
7253 } | 7296 } |
7254 | 7297 |
7255 } // namespace kernel | 7298 } // namespace kernel |
7256 } // namespace dart | 7299 } // namespace dart |
7257 | 7300 |
7258 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 7301 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |