| Index: runtime/vm/dart_entry.cc
|
| diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
|
| index 397db9e17f794686bd5f0566e619d4e7ebea941c..97851a024eeeea02e1c3e85a408d9d2a5a75d4ef 100644
|
| --- a/runtime/vm/dart_entry.cc
|
| +++ b/runtime/vm/dart_entry.cc
|
| @@ -96,6 +96,11 @@ RawObject* DartEntry::InvokeFunction(const Function& function,
|
| Zone* zone = thread->zone();
|
| ASSERT(thread->IsMutatorThread());
|
| ScopedIsolateStackLimits stack_limit(thread, current_sp);
|
| + if (ArgumentsDescriptor(arguments_descriptor).TypeArgsLen() > 0) {
|
| + const String& message = String::Handle(String::New(
|
| + "Unsupported invocation of Dart generic function with type arguments"));
|
| + return ApiError::New(message);
|
| + }
|
| if (!function.HasCode()) {
|
| const Object& result =
|
| Object::Handle(zone, Compiler::CompileFunction(thread, function));
|
| @@ -140,15 +145,16 @@ RawObject* DartEntry::InvokeClosure(const Array& arguments,
|
| const Array& arguments_descriptor) {
|
| Thread* thread = Thread::Current();
|
| Zone* zone = thread->zone();
|
| + const ArgumentsDescriptor args_desc(arguments_descriptor);
|
| + const intptr_t instance_index = args_desc.TypeArgsLen() == 0 ? 0 : 1;
|
| Instance& instance = Instance::Handle(zone);
|
| - instance ^= arguments.At(0);
|
| + instance ^= arguments.At(instance_index);
|
| // Get the entrypoint corresponding to the closure function or to the call
|
| // method of the instance. This will result in a compilation of the function
|
| // if it is not already compiled.
|
| Function& function = Function::Handle(zone);
|
| if (instance.IsCallable(&function)) {
|
| // Only invoke the function if its arguments are compatible.
|
| - const ArgumentsDescriptor args_desc(arguments_descriptor);
|
| if (function.AreValidArgumentCounts(args_desc.TypeArgsLen(),
|
| args_desc.Count(),
|
| args_desc.NamedCount(), NULL)) {
|
| @@ -391,16 +397,17 @@ RawArray* ArgumentsDescriptor::New(intptr_t type_args_len,
|
| intptr_t num_arguments) {
|
| ASSERT(type_args_len >= 0);
|
| ASSERT(num_arguments >= 0);
|
| - if (num_arguments < kCachedDescriptorCount) {
|
| + if ((type_args_len == 0) && (num_arguments < kCachedDescriptorCount)) {
|
| return cached_args_descriptors_[num_arguments];
|
| }
|
| - return NewNonCached(num_arguments);
|
| + return NewNonCached(type_args_len, num_arguments);
|
| }
|
|
|
|
|
| -RawArray* ArgumentsDescriptor::NewNonCached(intptr_t num_arguments,
|
| +RawArray* ArgumentsDescriptor::NewNonCached(intptr_t type_args_len,
|
| + intptr_t num_arguments,
|
| bool canonicalize) {
|
| - // Build the arguments descriptor array, which consists of the zero length
|
| + // Build the arguments descriptor array, which consists of the length of the
|
| // type argument vector, total argument count; the positional argument count;
|
| // and a terminating null to simplify iterating in generated code.
|
| Thread* thread = Thread::Current();
|
| @@ -410,8 +417,9 @@ RawArray* ArgumentsDescriptor::NewNonCached(intptr_t num_arguments,
|
| Array::Handle(zone, Array::New(descriptor_len, Heap::kOld));
|
| const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments));
|
|
|
| - // Set zero length type argument vector.
|
| - descriptor.SetAt(kTypeArgsLenIndex, Smi::Handle(zone, Smi::New(0)));
|
| + // Set type argument vector length.
|
| + descriptor.SetAt(kTypeArgsLenIndex,
|
| + Smi::Handle(zone, Smi::New(type_args_len)));
|
|
|
| // Set total number of passed arguments.
|
| descriptor.SetAt(kCountIndex, arg_count);
|
| @@ -434,7 +442,8 @@ RawArray* ArgumentsDescriptor::NewNonCached(intptr_t num_arguments,
|
|
|
| void ArgumentsDescriptor::InitOnce() {
|
| for (int i = 0; i < kCachedDescriptorCount; i++) {
|
| - cached_args_descriptors_[i] = ArgumentsDescriptor::NewNonCached(i, false);
|
| + cached_args_descriptors_[i] =
|
| + ArgumentsDescriptor::NewNonCached(/*type_args_len=*/0, i, false);
|
| }
|
| }
|
|
|
|
|