Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index c3f39cc83debf3d225c75efb18ff2879ace8263d..3437a04f69af8a3127fc7a27eb22c75a15c6dad0 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -346,6 +346,8 @@ void ParsedFunction::AllocateVariables() { |
const intptr_t num_fixed_params = function().num_fixed_parameters(); |
const intptr_t num_opt_params = function().NumOptionalParameters(); |
const intptr_t num_params = num_fixed_params + num_opt_params; |
+ const intptr_t type_args_slot = function().IsGeneric() ? 1 : 0; |
+ |
// Compute start indices to parameters and locals, and the number of |
// parameters to copy. |
if (num_opt_params == 0) { |
@@ -366,8 +368,8 @@ void ParsedFunction::AllocateVariables() { |
// in the context(s). |
bool found_captured_variables = false; |
int next_free_frame_index = scope->AllocateVariables( |
- first_parameter_index_, num_params, first_stack_local_index_, NULL, |
- &found_captured_variables); |
+ first_parameter_index_, num_params, type_args_slot, |
+ first_stack_local_index_, NULL, &found_captured_variables); |
// Frame indices are relative to the frame pointer and are decreasing. |
ASSERT(next_free_frame_index <= first_stack_local_index_); |
@@ -1804,6 +1806,10 @@ SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
void Parser::BuildDispatcherScope(const Function& func, |
const ArgumentsDescriptor& desc) { |
+ if (desc.TypeArgsLen() > 0) { |
+ // TODO(regis): Make func generic. |
+ UNIMPLEMENTED(); |
+ } |
ParamList params; |
// Receiver first. |
TokenPosition token_pos = func.token_pos(); |
@@ -1908,6 +1914,11 @@ SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { |
const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); |
ArgumentsDescriptor desc(args_desc); |
ASSERT(desc.Count() > 0); |
+ if (desc.TypeArgsLen() > 0) { |
+ ASSERT(func.IsGeneric()); |
+ // TODO(regis): Pass type argument vector. Not clear when this code is used. |
rmacnak
2017/06/14 00:14:20
Something like this:
func<X, Y, X>(w) => null;
c
regis
2017/06/14 21:02:05
Thanks! This example causes an assert fault in ker
Vyacheslav Egorov (Google)
2017/06/15 14:05:44
Is this even legal? I thought the consensus was th
regis
2017/06/15 21:38:26
Yes, the first version required you to pass the ty
|
+ UNIMPLEMENTED(); |
+ } |
// Set up scope for this function. |
BuildDispatcherScope(func, desc); |
@@ -5734,7 +5745,11 @@ RawTypeArguments* Parser::ParseTypeArguments( |
ReportError("right angle bracket expected"); |
} |
if (finalization != ClassFinalizer::kIgnore) { |
- return NewTypeArguments(types); |
+ TypeArguments& type_args = TypeArguments::Handle(NewTypeArguments(types)); |
+ if (finalization == ClassFinalizer::kCanonicalize) { |
+ type_args = type_args.Canonicalize(); |
+ } |
+ return type_args.raw(); |
} |
} |
return TypeArguments::null(); |
@@ -12601,12 +12616,15 @@ void Parser::ResolveType(AbstractType* type) { |
if (type->arguments() != TypeArguments::null()) { |
const TypeArguments& arguments = |
TypeArguments::Handle(Z, type->arguments()); |
- const intptr_t num_arguments = arguments.Length(); |
- AbstractType& type_argument = AbstractType::Handle(Z); |
- for (intptr_t i = 0; i < num_arguments; i++) { |
- type_argument = arguments.TypeAt(i); |
- ResolveType(&type_argument); |
- arguments.SetTypeAt(i, type_argument); |
+ // Already resolved if canonical. |
+ if (!arguments.IsCanonical()) { |
+ const intptr_t num_arguments = arguments.Length(); |
+ AbstractType& type_argument = AbstractType::Handle(Z); |
+ for (intptr_t i = 0; i < num_arguments; i++) { |
+ type_argument = arguments.TypeAt(i); |
+ ResolveType(&type_argument); |
+ arguments.SetTypeAt(i, type_argument); |
+ } |
} |
} |
if (type->IsFunctionType()) { |