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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_to_il.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/kernel_binary_flowgraph.cc
diff --git a/runtime/vm/kernel_binary_flowgraph.cc b/runtime/vm/kernel_binary_flowgraph.cc
index 3f0d127a76aee16c8a0f227c19cfcb577102f01c..da57ef7df48a679165510a90d286ebf0f9f84204 100644
--- a/runtime/vm/kernel_binary_flowgraph.cc
+++ b/runtime/vm/kernel_binary_flowgraph.cc
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/kernel_binary_flowgraph.h"
-
#include "vm/compiler.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
@@ -1094,9 +1093,15 @@ void StreamingScopeBuilder::VisitTypeParameterType() {
// factory constructor function.
HandleSpecialLoad(&result_->type_arguments_variable,
Symbols::TypeArgumentsParameter());
- } else {
- // The type argument vector is stored on the instance object. We therefore
- // need to capture `this`.
+ } else if (!function.IsGeneric()) {
+ // KERNEL_GENERIC_METHODS_UNDONE(sjindel):
+ // Currently we only support generic toplevel methods. For no special load
+ // needs to be prepared for these, because the 'LocalVariable' for the type
+ // arguments is set on the 'ParsedFunction' directly. So we do nothing for
+ // generic methods.
+
+ // The type argument vector is stored on the
+ // instance object. We therefore need to capture `this`.
HandleSpecialLoad(&result_->this_variable, Symbols::This());
}
@@ -1626,13 +1631,13 @@ void StreamingDartTypeTranslator::BuildTypeParameterType() {
: 0;
if (procedure_type_parameter_count > 0) {
if (procedure_type_parameter_count > parameter_index) {
- // Here we technically could load the correct one via something like
- // result_ ^= dart::TypeArguments::Handle(
- // Z, active_class_->member->type_parameters())
- // .TypeAt(parameter_index);
- // but that isn't currently supported elsewhere
- // (FlowGraphBuilder::LoadFunctionTypeArguments()).
- result_ ^= dart::Type::DynamicType();
+ if (FLAG_reify_generic_functions) {
+ result_ ^= dart::TypeArguments::Handle(
+ Z, active_class_->member->type_parameters())
+ .TypeAt(parameter_index);
+ } else {
+ result_ ^= dart::Type::DynamicType();
+ }
return;
}
parameter_index -= procedure_type_parameter_count;
@@ -2949,11 +2954,21 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfConvertedClosureFunction(
Fragment body(normal_entry);
body += flow_graph_builder_->CheckStackOverflowInPrologue();
+ body += NullConstant();
+ LocalVariable* result = MakeTemporary();
// Load all the arguments.
ASSERT(target.is_static());
+ // KERNEL_GENERIC_METHODS_UNDONE(sjindel): Since the frontend can't yet emit
+ // generic methods into kernel, all type parameters to the target must come
+ // from the context. When generic methods are fully supported, we will need to
+ // get the type arguments provided by the caller and append them to the
+ // captured type arguments via 'prependTypeArguments'.
+
FunctionNodeHelper function_node_helper(this);
+ function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
+ intptr_t type_param_count = PeekUInt();
function_node_helper.ReadUntilExcluding(
FunctionNodeHelper::kPositionalParameters);
@@ -2966,6 +2981,15 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfConvertedClosureFunction(
// to that function as the first parameter.
body += LoadLocal(LookupVariable(ReaderOffset())); // 0th variable offset.
body += flow_graph_builder_->LoadField(Closure::context_offset());
+ LocalVariable* context = MakeTemporary();
+
+ if (type_param_count > 0) {
+ body += LoadLocal(context);
+ body += flow_graph_builder_->LoadField(Context::variable_offset(0));
+ body += PushArgument();
+ }
+
+ body += LoadLocal(context);
body += PushArgument();
SkipVariableDeclaration(); // read 0th variable.
@@ -2994,11 +3018,14 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfConvertedClosureFunction(
// Forward them to the target.
const intptr_t argument_count =
- positional_argument_count + named_argument_count;
+ 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
body += StaticCall(TokenPosition::kNoSource, target, argument_count,
- argument_names);
+ argument_names, type_param_count);
// Return the result.
+ body += StoreLocal(TokenPosition::kNoSource, result);
+ body += Drop();
+ body += Drop();
body += Return(function_node_helper.end_position_);
return new (Z)
@@ -4404,9 +4431,10 @@ Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
const Function& target,
intptr_t argument_count,
- const Array& argument_names) {
+ const Array& argument_names,
+ intptr_t type_args_count) {
return flow_graph_builder_->StaticCall(position, target, argument_count,
- argument_names);
+ argument_names, type_args_count);
}
Fragment StreamingFlowGraphBuilder::InstanceCall(
@@ -5825,9 +5853,25 @@ Fragment StreamingFlowGraphBuilder::BuildClosureCreation(
StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset());
instructions += Drop();
-
SkipDartType(); // skip function type of the closure.
- SkipListOfDartTypes(); // skip list of type arguments.
+
+ // KERNEL_GENERIC_METHODS_UNDONE(sjindel): When generic methods are fully
+ // supported in kernel, we'll need to store a NULL in the type arguments slot
+ // when type arguments are absent, so the wrapper for the target function can
+ // tell how many type args are captured vs. provided by the caller of the
+ // closure.
+
+ intptr_t types_count = ReadListLength(); // read type count.
+ if (types_count > 0) {
+ instructions += LoadLocal(context);
+
+ const TypeArguments& type_args =
+ T.BuildTypeArguments(types_count); // read list of type arguments.
+ instructions += TranslateInstantiatedTypeArguments(type_args);
+
+ instructions += StoreInstanceField(TokenPosition::kNoSource,
+ Context::variable_offset(0));
+ }
return instructions;
}
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_to_il.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698