OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/dart_entry.h" | 5 #include "vm/dart_entry.h" |
6 | 6 |
7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
9 #include "vm/debugger.h" | 9 #include "vm/debugger.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 const Array& arguments, | 89 const Array& arguments, |
90 const Array& arguments_descriptor, | 90 const Array& arguments_descriptor, |
91 uword current_sp) { | 91 uword current_sp) { |
92 // Get the entrypoint corresponding to the function specified, this | 92 // Get the entrypoint corresponding to the function specified, this |
93 // will result in a compilation of the function if it is not already | 93 // will result in a compilation of the function if it is not already |
94 // compiled. | 94 // compiled. |
95 Thread* thread = Thread::Current(); | 95 Thread* thread = Thread::Current(); |
96 Zone* zone = thread->zone(); | 96 Zone* zone = thread->zone(); |
97 ASSERT(thread->IsMutatorThread()); | 97 ASSERT(thread->IsMutatorThread()); |
98 ScopedIsolateStackLimits stack_limit(thread, current_sp); | 98 ScopedIsolateStackLimits stack_limit(thread, current_sp); |
| 99 if (ArgumentsDescriptor(arguments_descriptor).TypeArgsLen() > 0) { |
| 100 const String& message = String::Handle(String::New( |
| 101 "Unsupported invocation of Dart generic function with type arguments")); |
| 102 return ApiError::New(message); |
| 103 } |
99 if (!function.HasCode()) { | 104 if (!function.HasCode()) { |
100 const Object& result = | 105 const Object& result = |
101 Object::Handle(zone, Compiler::CompileFunction(thread, function)); | 106 Object::Handle(zone, Compiler::CompileFunction(thread, function)); |
102 if (result.IsError()) { | 107 if (result.IsError()) { |
103 return Error::Cast(result).raw(); | 108 return Error::Cast(result).raw(); |
104 } | 109 } |
105 } | 110 } |
106 // Now Call the invoke stub which will invoke the dart function. | 111 // Now Call the invoke stub which will invoke the dart function. |
107 #if !defined(TARGET_ARCH_DBC) | 112 #if !defined(TARGET_ARCH_DBC) |
108 invokestub entrypoint = reinterpret_cast<invokestub>( | 113 invokestub entrypoint = reinterpret_cast<invokestub>( |
(...skipping 24 matching lines...) Expand all Loading... |
133 const Array& arguments_descriptor = | 138 const Array& arguments_descriptor = |
134 Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length())); | 139 Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length())); |
135 return InvokeClosure(arguments, arguments_descriptor); | 140 return InvokeClosure(arguments, arguments_descriptor); |
136 } | 141 } |
137 | 142 |
138 | 143 |
139 RawObject* DartEntry::InvokeClosure(const Array& arguments, | 144 RawObject* DartEntry::InvokeClosure(const Array& arguments, |
140 const Array& arguments_descriptor) { | 145 const Array& arguments_descriptor) { |
141 Thread* thread = Thread::Current(); | 146 Thread* thread = Thread::Current(); |
142 Zone* zone = thread->zone(); | 147 Zone* zone = thread->zone(); |
| 148 const ArgumentsDescriptor args_desc(arguments_descriptor); |
| 149 const intptr_t instance_index = args_desc.TypeArgsLen() == 0 ? 0 : 1; |
143 Instance& instance = Instance::Handle(zone); | 150 Instance& instance = Instance::Handle(zone); |
144 instance ^= arguments.At(0); | 151 instance ^= arguments.At(instance_index); |
145 // Get the entrypoint corresponding to the closure function or to the call | 152 // Get the entrypoint corresponding to the closure function or to the call |
146 // method of the instance. This will result in a compilation of the function | 153 // method of the instance. This will result in a compilation of the function |
147 // if it is not already compiled. | 154 // if it is not already compiled. |
148 Function& function = Function::Handle(zone); | 155 Function& function = Function::Handle(zone); |
149 if (instance.IsCallable(&function)) { | 156 if (instance.IsCallable(&function)) { |
150 // Only invoke the function if its arguments are compatible. | 157 // Only invoke the function if its arguments are compatible. |
151 const ArgumentsDescriptor args_desc(arguments_descriptor); | |
152 if (function.AreValidArgumentCounts(args_desc.TypeArgsLen(), | 158 if (function.AreValidArgumentCounts(args_desc.TypeArgsLen(), |
153 args_desc.Count(), | 159 args_desc.Count(), |
154 args_desc.NamedCount(), NULL)) { | 160 args_desc.NamedCount(), NULL)) { |
155 // The closure or non-closure object (receiver) is passed as implicit | 161 // The closure or non-closure object (receiver) is passed as implicit |
156 // first argument. It is already included in the arguments array. | 162 // first argument. It is already included in the arguments array. |
157 return InvokeFunction(function, arguments, arguments_descriptor); | 163 return InvokeFunction(function, arguments, arguments_descriptor); |
158 } | 164 } |
159 } | 165 } |
160 | 166 |
161 // There is no compatible 'call' method, see if there's a getter. | 167 // There is no compatible 'call' method, see if there's a getter. |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 descriptor ^= descriptor.CheckAndCanonicalize(thread, NULL); | 390 descriptor ^= descriptor.CheckAndCanonicalize(thread, NULL); |
385 ASSERT(!descriptor.IsNull()); | 391 ASSERT(!descriptor.IsNull()); |
386 return descriptor.raw(); | 392 return descriptor.raw(); |
387 } | 393 } |
388 | 394 |
389 | 395 |
390 RawArray* ArgumentsDescriptor::New(intptr_t type_args_len, | 396 RawArray* ArgumentsDescriptor::New(intptr_t type_args_len, |
391 intptr_t num_arguments) { | 397 intptr_t num_arguments) { |
392 ASSERT(type_args_len >= 0); | 398 ASSERT(type_args_len >= 0); |
393 ASSERT(num_arguments >= 0); | 399 ASSERT(num_arguments >= 0); |
394 if (num_arguments < kCachedDescriptorCount) { | 400 if ((type_args_len == 0) && (num_arguments < kCachedDescriptorCount)) { |
395 return cached_args_descriptors_[num_arguments]; | 401 return cached_args_descriptors_[num_arguments]; |
396 } | 402 } |
397 return NewNonCached(num_arguments); | 403 return NewNonCached(type_args_len, num_arguments); |
398 } | 404 } |
399 | 405 |
400 | 406 |
401 RawArray* ArgumentsDescriptor::NewNonCached(intptr_t num_arguments, | 407 RawArray* ArgumentsDescriptor::NewNonCached(intptr_t type_args_len, |
| 408 intptr_t num_arguments, |
402 bool canonicalize) { | 409 bool canonicalize) { |
403 // Build the arguments descriptor array, which consists of the zero length | 410 // Build the arguments descriptor array, which consists of the length of the |
404 // type argument vector, total argument count; the positional argument count; | 411 // type argument vector, total argument count; the positional argument count; |
405 // and a terminating null to simplify iterating in generated code. | 412 // and a terminating null to simplify iterating in generated code. |
406 Thread* thread = Thread::Current(); | 413 Thread* thread = Thread::Current(); |
407 Zone* zone = thread->zone(); | 414 Zone* zone = thread->zone(); |
408 const intptr_t descriptor_len = LengthFor(0); | 415 const intptr_t descriptor_len = LengthFor(0); |
409 Array& descriptor = | 416 Array& descriptor = |
410 Array::Handle(zone, Array::New(descriptor_len, Heap::kOld)); | 417 Array::Handle(zone, Array::New(descriptor_len, Heap::kOld)); |
411 const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments)); | 418 const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments)); |
412 | 419 |
413 // Set zero length type argument vector. | 420 // Set type argument vector length. |
414 descriptor.SetAt(kTypeArgsLenIndex, Smi::Handle(zone, Smi::New(0))); | 421 descriptor.SetAt(kTypeArgsLenIndex, |
| 422 Smi::Handle(zone, Smi::New(type_args_len))); |
415 | 423 |
416 // Set total number of passed arguments. | 424 // Set total number of passed arguments. |
417 descriptor.SetAt(kCountIndex, arg_count); | 425 descriptor.SetAt(kCountIndex, arg_count); |
418 | 426 |
419 // Set number of positional arguments. | 427 // Set number of positional arguments. |
420 descriptor.SetAt(kPositionalCountIndex, arg_count); | 428 descriptor.SetAt(kPositionalCountIndex, arg_count); |
421 | 429 |
422 // Set terminating null. | 430 // Set terminating null. |
423 descriptor.SetAt((descriptor_len - 1), Object::null_object()); | 431 descriptor.SetAt((descriptor_len - 1), Object::null_object()); |
424 | 432 |
425 // Share the immutable descriptor when possible by canonicalizing it. | 433 // Share the immutable descriptor when possible by canonicalizing it. |
426 descriptor.MakeImmutable(); | 434 descriptor.MakeImmutable(); |
427 if (canonicalize) { | 435 if (canonicalize) { |
428 descriptor ^= descriptor.CheckAndCanonicalize(thread, NULL); | 436 descriptor ^= descriptor.CheckAndCanonicalize(thread, NULL); |
429 } | 437 } |
430 ASSERT(!descriptor.IsNull()); | 438 ASSERT(!descriptor.IsNull()); |
431 return descriptor.raw(); | 439 return descriptor.raw(); |
432 } | 440 } |
433 | 441 |
434 | 442 |
435 void ArgumentsDescriptor::InitOnce() { | 443 void ArgumentsDescriptor::InitOnce() { |
436 for (int i = 0; i < kCachedDescriptorCount; i++) { | 444 for (int i = 0; i < kCachedDescriptorCount; i++) { |
437 cached_args_descriptors_[i] = ArgumentsDescriptor::NewNonCached(i, false); | 445 cached_args_descriptors_[i] = |
| 446 ArgumentsDescriptor::NewNonCached(/*type_args_len=*/0, i, false); |
438 } | 447 } |
439 } | 448 } |
440 | 449 |
441 | 450 |
442 RawObject* DartLibraryCalls::InstanceCreate(const Library& lib, | 451 RawObject* DartLibraryCalls::InstanceCreate(const Library& lib, |
443 const String& class_name, | 452 const String& class_name, |
444 const String& constructor_name, | 453 const String& constructor_name, |
445 const Array& arguments) { | 454 const Array& arguments) { |
446 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); | 455 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); |
447 ASSERT(!cls.IsNull()); | 456 ASSERT(!cls.IsNull()); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 const Array& args = Array::Handle(Array::New(kNumArguments)); | 628 const Array& args = Array::Handle(Array::New(kNumArguments)); |
620 args.SetAt(0, map); | 629 args.SetAt(0, map); |
621 args.SetAt(1, key); | 630 args.SetAt(1, key); |
622 args.SetAt(2, value); | 631 args.SetAt(2, value); |
623 const Object& result = | 632 const Object& result = |
624 Object::Handle(DartEntry::InvokeFunction(function, args)); | 633 Object::Handle(DartEntry::InvokeFunction(function, args)); |
625 return result.raw(); | 634 return result.raw(); |
626 } | 635 } |
627 | 636 |
628 } // namespace dart | 637 } // namespace dart |
OLD | NEW |