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 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1087 Function& function = Function::Handle(Z, parsed_function_->function().raw()); | 1086 Function& function = Function::Handle(Z, parsed_function_->function().raw()); |
1088 while (function.IsClosureFunction()) { | 1087 while (function.IsClosureFunction()) { |
1089 function = function.parent_function(); | 1088 function = function.parent_function(); |
1090 } | 1089 } |
1091 | 1090 |
1092 if (function.IsFactory()) { | 1091 if (function.IsFactory()) { |
1093 // The type argument vector is passed as the very first argument to the | 1092 // The type argument vector is passed as the very first argument to the |
1094 // factory constructor function. | 1093 // factory constructor function. |
1095 HandleSpecialLoad(&result_->type_arguments_variable, | 1094 HandleSpecialLoad(&result_->type_arguments_variable, |
1096 Symbols::TypeArgumentsParameter()); | 1095 Symbols::TypeArgumentsParameter()); |
1097 } else { | 1096 } else if (!function.IsGeneric()) { |
1098 // The type argument vector is stored on the instance object. We therefore | 1097 // KERNEL_GENERIC_METHODS_UNDONE(sjindel): |
1099 // need to capture `this`. | 1098 // Currently we only support generic toplevel methods. For no special load |
1099 // needs to be prepared for these, because the 'LocalVariable' for the type | |
1100 // arguments is set on the 'ParsedFunction' directly. So we do nothing for | |
1101 // generic methods. | |
1102 | |
1103 // The type argument vector is stored on the | |
1104 // instance object. We therefore need to capture `this`. | |
1100 HandleSpecialLoad(&result_->this_variable, Symbols::This()); | 1105 HandleSpecialLoad(&result_->this_variable, Symbols::This()); |
1101 } | 1106 } |
1102 | 1107 |
1103 builder_->ReadUInt(); // read index for parameter. | 1108 builder_->ReadUInt(); // read index for parameter. |
1104 builder_->SkipOptionalDartType(); // read bound bound. | 1109 builder_->SkipOptionalDartType(); // read bound bound. |
1105 } | 1110 } |
1106 | 1111 |
1107 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { | 1112 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { |
1108 // "Peek" ahead into the function node | 1113 // "Peek" ahead into the function node |
1109 intptr_t offset = builder_->ReaderOffset(); | 1114 intptr_t offset = builder_->ReaderOffset(); |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1619 } | 1624 } |
1620 parameter_index -= class_types.Length(); | 1625 parameter_index -= class_types.Length(); |
1621 } | 1626 } |
1622 | 1627 |
1623 intptr_t procedure_type_parameter_count = | 1628 intptr_t procedure_type_parameter_count = |
1624 active_class_->MemberIsProcedure() | 1629 active_class_->MemberIsProcedure() |
1625 ? active_class_->MemberTypeParameterCount(Z) | 1630 ? active_class_->MemberTypeParameterCount(Z) |
1626 : 0; | 1631 : 0; |
1627 if (procedure_type_parameter_count > 0) { | 1632 if (procedure_type_parameter_count > 0) { |
1628 if (procedure_type_parameter_count > parameter_index) { | 1633 if (procedure_type_parameter_count > parameter_index) { |
1629 // Here we technically could load the correct one via something like | 1634 if (FLAG_reify_generic_functions) { |
1630 // result_ ^= dart::TypeArguments::Handle( | 1635 result_ ^= dart::TypeArguments::Handle( |
1631 // Z, active_class_->member->type_parameters()) | 1636 Z, active_class_->member->type_parameters()) |
1632 // .TypeAt(parameter_index); | 1637 .TypeAt(parameter_index); |
1633 // but that isn't currently supported elsewhere | 1638 } else { |
1634 // (FlowGraphBuilder::LoadFunctionTypeArguments()). | 1639 result_ ^= dart::Type::DynamicType(); |
1635 result_ ^= dart::Type::DynamicType(); | 1640 } |
1636 return; | 1641 return; |
1637 } | 1642 } |
1638 parameter_index -= procedure_type_parameter_count; | 1643 parameter_index -= procedure_type_parameter_count; |
1639 } | 1644 } |
1640 } | 1645 } |
1641 | 1646 |
1642 if (type_parameter_scope_ != NULL && parameter_index >= 0 && | 1647 if (type_parameter_scope_ != NULL && parameter_index >= 0 && |
1643 parameter_index < type_parameter_scope_->outer_parameter_count() + | 1648 parameter_index < type_parameter_scope_->outer_parameter_count() + |
1644 type_parameter_scope_->parameters_count()) { | 1649 type_parameter_scope_->parameters_count()) { |
1645 result_ ^= dart::Type::DynamicType(); | 1650 result_ ^= dart::Type::DynamicType(); |
(...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2942 const Function& function) { | 2947 const Function& function) { |
2943 const Function& target = Function::ZoneHandle(Z, function.parent_function()); | 2948 const Function& target = Function::ZoneHandle(Z, function.parent_function()); |
2944 | 2949 |
2945 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); | 2950 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); |
2946 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( | 2951 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( |
2947 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId); | 2952 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId); |
2948 SetupDefaultParameterValues(); | 2953 SetupDefaultParameterValues(); |
2949 | 2954 |
2950 Fragment body(normal_entry); | 2955 Fragment body(normal_entry); |
2951 body += flow_graph_builder_->CheckStackOverflowInPrologue(); | 2956 body += flow_graph_builder_->CheckStackOverflowInPrologue(); |
2957 body += NullConstant(); | |
2958 LocalVariable* result = MakeTemporary(); | |
2952 | 2959 |
2953 // Load all the arguments. | 2960 // Load all the arguments. |
2954 ASSERT(target.is_static()); | 2961 ASSERT(target.is_static()); |
2955 | 2962 |
2963 // KERNEL_GENERIC_METHODS_UNDONE(sjindel): Since the frontend can't yet emit | |
2964 // generic methods into kernel, all type parameters to the target must come | |
2965 // from the context. When generic methods are fully supported, we will need to | |
2966 // get the type arguments provided by the caller and append them to the | |
2967 // captured type arguments via 'prependTypeArguments'. | |
2968 | |
2956 FunctionNodeHelper function_node_helper(this); | 2969 FunctionNodeHelper function_node_helper(this); |
2970 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters); | |
2971 intptr_t type_param_count = PeekUInt(); | |
2957 function_node_helper.ReadUntilExcluding( | 2972 function_node_helper.ReadUntilExcluding( |
2958 FunctionNodeHelper::kPositionalParameters); | 2973 FunctionNodeHelper::kPositionalParameters); |
2959 | 2974 |
2960 // Positional. | 2975 // Positional. |
2961 const intptr_t positional_argument_count = ReadListLength(); | 2976 const intptr_t positional_argument_count = ReadListLength(); |
2962 | 2977 |
2963 // The first argument is the instance of the closure class. For converted | 2978 // The first argument is the instance of the closure class. For converted |
2964 // closures its context field contains the context vector that is used by the | 2979 // closures its context field contains the context vector that is used by the |
2965 // converted top-level function (target) explicitly and that should be passed | 2980 // converted top-level function (target) explicitly and that should be passed |
2966 // to that function as the first parameter. | 2981 // to that function as the first parameter. |
2967 body += LoadLocal(LookupVariable(ReaderOffset())); // 0th variable offset. | 2982 body += LoadLocal(LookupVariable(ReaderOffset())); // 0th variable offset. |
2968 body += flow_graph_builder_->LoadField(Closure::context_offset()); | 2983 body += flow_graph_builder_->LoadField(Closure::context_offset()); |
2984 LocalVariable* context = MakeTemporary(); | |
2985 | |
2986 if (type_param_count > 0) { | |
2987 body += LoadLocal(context); | |
2988 body += flow_graph_builder_->LoadField(Context::variable_offset(0)); | |
2989 body += PushArgument(); | |
2990 } | |
2991 | |
2992 body += LoadLocal(context); | |
2969 body += PushArgument(); | 2993 body += PushArgument(); |
2970 SkipVariableDeclaration(); // read 0th variable. | 2994 SkipVariableDeclaration(); // read 0th variable. |
2971 | 2995 |
2972 // The rest of the parameters are the same for the method of the Closure class | 2996 // The rest of the parameters are the same for the method of the Closure class |
2973 // being invoked and the top-level function (target). | 2997 // being invoked and the top-level function (target). |
2974 for (intptr_t i = 1; i < positional_argument_count; i++) { | 2998 for (intptr_t i = 1; i < positional_argument_count; i++) { |
2975 body += LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset. | 2999 body += LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset. |
2976 body += PushArgument(); | 3000 body += PushArgument(); |
2977 SkipVariableDeclaration(); // read ith variable. | 3001 SkipVariableDeclaration(); // read ith variable. |
2978 } | 3002 } |
2979 | 3003 |
2980 // Named. | 3004 // Named. |
2981 const intptr_t named_argument_count = ReadListLength(); | 3005 const intptr_t named_argument_count = ReadListLength(); |
2982 Array& argument_names = Array::ZoneHandle(Z); | 3006 Array& argument_names = Array::ZoneHandle(Z); |
2983 if (named_argument_count > 0) { | 3007 if (named_argument_count > 0) { |
2984 argument_names = Array::New(named_argument_count); | 3008 argument_names = Array::New(named_argument_count); |
2985 for (intptr_t i = 0; i < named_argument_count; i++) { | 3009 for (intptr_t i = 0; i < named_argument_count; i++) { |
2986 body += | 3010 body += |
2987 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset. | 3011 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset. |
2988 body += PushArgument(); | 3012 body += PushArgument(); |
2989 argument_names.SetAt( | 3013 argument_names.SetAt( |
2990 i, H.DartSymbol(GetNameFromVariableDeclaration(ReaderOffset()))); | 3014 i, H.DartSymbol(GetNameFromVariableDeclaration(ReaderOffset()))); |
2991 SkipVariableDeclaration(); // read ith variable. | 3015 SkipVariableDeclaration(); // read ith variable. |
2992 } | 3016 } |
2993 } | 3017 } |
2994 | 3018 |
2995 // Forward them to the target. | 3019 // Forward them to the target. |
2996 const intptr_t argument_count = | 3020 const intptr_t argument_count = |
2997 positional_argument_count + named_argument_count; | 3021 positional_argument_count + named_argument_count + !!type_param_count; |
jensj
2017/08/14 06:47:13
Something like
```
intptr_t argument_count = posi
sjindel
2017/08/14 11:05:50
Done, although 'argument_count' can't be 'const' a
| |
2998 body += StaticCall(TokenPosition::kNoSource, target, argument_count, | 3022 body += StaticCall(TokenPosition::kNoSource, target, argument_count, |
2999 argument_names); | 3023 argument_names, type_param_count); |
3000 | 3024 |
3001 // Return the result. | 3025 // Return the result. |
3026 body += StoreLocal(TokenPosition::kNoSource, result); | |
3027 body += Drop(); | |
3028 body += Drop(); | |
3002 body += Return(function_node_helper.end_position_); | 3029 body += Return(function_node_helper.end_position_); |
3003 | 3030 |
3004 return new (Z) | 3031 return new (Z) |
3005 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, | 3032 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, |
3006 flow_graph_builder_->next_block_id_ - 1); | 3033 flow_graph_builder_->next_block_id_ - 1); |
3007 } | 3034 } |
3008 | 3035 |
3009 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction( | 3036 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction( |
3010 intptr_t constructor_class_parent_offset) { | 3037 intptr_t constructor_class_parent_offset) { |
3011 const Function& dart_function = parsed_function()->function(); | 3038 const Function& dart_function = parsed_function()->function(); |
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4397 | 4424 |
4398 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, | 4425 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, |
4399 const Function& target, | 4426 const Function& target, |
4400 intptr_t argument_count) { | 4427 intptr_t argument_count) { |
4401 return flow_graph_builder_->StaticCall(position, target, argument_count); | 4428 return flow_graph_builder_->StaticCall(position, target, argument_count); |
4402 } | 4429 } |
4403 | 4430 |
4404 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, | 4431 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, |
4405 const Function& target, | 4432 const Function& target, |
4406 intptr_t argument_count, | 4433 intptr_t argument_count, |
4407 const Array& argument_names) { | 4434 const Array& argument_names, |
4435 intptr_t type_args_count) { | |
4408 return flow_graph_builder_->StaticCall(position, target, argument_count, | 4436 return flow_graph_builder_->StaticCall(position, target, argument_count, |
4409 argument_names); | 4437 argument_names, type_args_count); |
4410 } | 4438 } |
4411 | 4439 |
4412 Fragment StreamingFlowGraphBuilder::InstanceCall( | 4440 Fragment StreamingFlowGraphBuilder::InstanceCall( |
4413 TokenPosition position, | 4441 TokenPosition position, |
4414 const dart::String& name, | 4442 const dart::String& name, |
4415 Token::Kind kind, | 4443 Token::Kind kind, |
4416 intptr_t argument_count, | 4444 intptr_t argument_count, |
4417 intptr_t checked_argument_count) { | 4445 intptr_t checked_argument_count) { |
4418 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, | 4446 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, |
4419 checked_argument_count); | 4447 checked_argument_count); |
(...skipping 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5818 instructions += Constant(function); | 5846 instructions += Constant(function); |
5819 instructions += | 5847 instructions += |
5820 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset()); | 5848 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset()); |
5821 | 5849 |
5822 instructions += LoadLocal(closure); | 5850 instructions += LoadLocal(closure); |
5823 instructions += LoadLocal(context); | 5851 instructions += LoadLocal(context); |
5824 instructions += | 5852 instructions += |
5825 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset()); | 5853 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset()); |
5826 | 5854 |
5827 instructions += Drop(); | 5855 instructions += Drop(); |
5856 SkipDartType(); // skip function type of the closure. | |
5828 | 5857 |
5829 SkipDartType(); // skip function type of the closure. | 5858 // KERNEL_GENERIC_METHODS_UNDONE(sjindel): When generic methods are fully |
5830 SkipListOfDartTypes(); // skip list of type arguments. | 5859 // supported in kernel, we'll need to store a NULL in the type arguments slot |
5860 // when type arguments are absent, so the wrapper for the target function can | |
5861 // tell how many type args are captured vs. provided by the caller of the | |
5862 // closure. | |
5863 | |
5864 intptr_t types_count = ReadListLength(); // read type count. | |
5865 if (types_count > 0) { | |
5866 instructions += LoadLocal(context); | |
5867 | |
5868 const TypeArguments& type_args = | |
5869 T.BuildTypeArguments(types_count); // read list of type arguments. | |
5870 instructions += TranslateInstantiatedTypeArguments(type_args); | |
5871 | |
5872 instructions += StoreInstanceField(TokenPosition::kNoSource, | |
5873 Context::variable_offset(0)); | |
5874 } | |
5831 | 5875 |
5832 return instructions; | 5876 return instructions; |
5833 } | 5877 } |
5834 | 5878 |
5835 Fragment StreamingFlowGraphBuilder::BuildInvalidStatement() { | 5879 Fragment StreamingFlowGraphBuilder::BuildInvalidStatement() { |
5836 H.ReportError("Invalid statements not implemented yet!"); | 5880 H.ReportError("Invalid statements not implemented yet!"); |
5837 return Fragment(); | 5881 return Fragment(); |
5838 } | 5882 } |
5839 | 5883 |
5840 Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() { | 5884 Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() { |
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7201 } | 7245 } |
7202 } | 7246 } |
7203 | 7247 |
7204 return Array::Handle(Array::null()); | 7248 return Array::Handle(Array::null()); |
7205 } | 7249 } |
7206 | 7250 |
7207 } // namespace kernel | 7251 } // namespace kernel |
7208 } // namespace dart | 7252 } // namespace dart |
7209 | 7253 |
7210 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 7254 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |