Chromium Code Reviews| 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand all 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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 |