Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Side by Side Diff: runtime/vm/kernel_binary_flowgraph.cc

Issue 2998803002: [kernel] Support for top-level generic functions. (Closed)
Patch Set: Review comments. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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...) Expand 10 before | Expand all | Expand 10 after
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...) Expand 10 before | Expand all | Expand 10 after
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...) Expand 10 before | Expand all | Expand 10 after
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...) Expand all
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...) Expand 10 before | Expand all | Expand 10 after
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...) Expand 10 before | Expand all | Expand 10 after
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...) Expand 10 before | Expand all | Expand 10 after
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698