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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 const Array& arguments_descriptor = | 133 const Array& arguments_descriptor = |
134 Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length())); | 134 Array::Handle(ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length())); |
135 return InvokeClosure(arguments, arguments_descriptor); | 135 return InvokeClosure(arguments, arguments_descriptor); |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 RawObject* DartEntry::InvokeClosure(const Array& arguments, | 139 RawObject* DartEntry::InvokeClosure(const Array& arguments, |
140 const Array& arguments_descriptor) { | 140 const Array& arguments_descriptor) { |
141 Thread* thread = Thread::Current(); | 141 Thread* thread = Thread::Current(); |
142 Zone* zone = thread->zone(); | 142 Zone* zone = thread->zone(); |
| 143 const ArgumentsDescriptor args_desc(arguments_descriptor); |
| 144 const intptr_t instance_index = args_desc.TypeArgsLen() == 0 ? 0 : 1; |
143 Instance& instance = Instance::Handle(zone); | 145 Instance& instance = Instance::Handle(zone); |
144 instance ^= arguments.At(0); | 146 instance ^= arguments.At(instance_index); |
145 // Get the entrypoint corresponding to the closure function or to the call | 147 // 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 | 148 // method of the instance. This will result in a compilation of the function |
147 // if it is not already compiled. | 149 // if it is not already compiled. |
148 Function& function = Function::Handle(zone); | 150 Function& function = Function::Handle(zone); |
149 if (instance.IsCallable(&function)) { | 151 if (instance.IsCallable(&function)) { |
150 // Only invoke the function if its arguments are compatible. | 152 // Only invoke the function if its arguments are compatible. |
151 const ArgumentsDescriptor args_desc(arguments_descriptor); | |
152 if (function.AreValidArgumentCounts(args_desc.TypeArgsLen(), | 153 if (function.AreValidArgumentCounts(args_desc.TypeArgsLen(), |
153 args_desc.Count(), | 154 args_desc.Count(), |
154 args_desc.NamedCount(), NULL)) { | 155 args_desc.NamedCount(), NULL)) { |
155 // The closure or non-closure object (receiver) is passed as implicit | 156 // The closure or non-closure object (receiver) is passed as implicit |
156 // first argument. It is already included in the arguments array. | 157 // first argument. It is already included in the arguments array. |
157 return InvokeFunction(function, arguments, arguments_descriptor); | 158 return InvokeFunction(function, arguments, arguments_descriptor); |
158 } | 159 } |
159 } | 160 } |
160 | 161 |
161 // There is no compatible 'call' method, see if there's a getter. | 162 // 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); | 385 descriptor ^= descriptor.CheckAndCanonicalize(thread, NULL); |
385 ASSERT(!descriptor.IsNull()); | 386 ASSERT(!descriptor.IsNull()); |
386 return descriptor.raw(); | 387 return descriptor.raw(); |
387 } | 388 } |
388 | 389 |
389 | 390 |
390 RawArray* ArgumentsDescriptor::New(intptr_t type_args_len, | 391 RawArray* ArgumentsDescriptor::New(intptr_t type_args_len, |
391 intptr_t num_arguments) { | 392 intptr_t num_arguments) { |
392 ASSERT(type_args_len >= 0); | 393 ASSERT(type_args_len >= 0); |
393 ASSERT(num_arguments >= 0); | 394 ASSERT(num_arguments >= 0); |
394 if (num_arguments < kCachedDescriptorCount) { | 395 if ((type_args_len == 0) && (num_arguments < kCachedDescriptorCount)) { |
395 return cached_args_descriptors_[num_arguments]; | 396 return cached_args_descriptors_[num_arguments]; |
396 } | 397 } |
397 return NewNonCached(num_arguments); | 398 return NewNonCached(type_args_len, num_arguments); |
398 } | 399 } |
399 | 400 |
400 | 401 |
401 RawArray* ArgumentsDescriptor::NewNonCached(intptr_t num_arguments, | 402 RawArray* ArgumentsDescriptor::NewNonCached(intptr_t type_args_len, |
| 403 intptr_t num_arguments, |
402 bool canonicalize) { | 404 bool canonicalize) { |
403 // Build the arguments descriptor array, which consists of the zero length | 405 // Build the arguments descriptor array, which consists of the length of the |
404 // type argument vector, total argument count; the positional argument count; | 406 // type argument vector, total argument count; the positional argument count; |
405 // and a terminating null to simplify iterating in generated code. | 407 // and a terminating null to simplify iterating in generated code. |
406 Thread* thread = Thread::Current(); | 408 Thread* thread = Thread::Current(); |
407 Zone* zone = thread->zone(); | 409 Zone* zone = thread->zone(); |
408 const intptr_t descriptor_len = LengthFor(0); | 410 const intptr_t descriptor_len = LengthFor(0); |
409 Array& descriptor = | 411 Array& descriptor = |
410 Array::Handle(zone, Array::New(descriptor_len, Heap::kOld)); | 412 Array::Handle(zone, Array::New(descriptor_len, Heap::kOld)); |
411 const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments)); | 413 const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments)); |
412 | 414 |
413 // Set zero length type argument vector. | 415 // Set type argument vector length. |
414 descriptor.SetAt(kTypeArgsLenIndex, Smi::Handle(zone, Smi::New(0))); | 416 descriptor.SetAt(kTypeArgsLenIndex, |
| 417 Smi::Handle(zone, Smi::New(type_args_len))); |
415 | 418 |
416 // Set total number of passed arguments. | 419 // Set total number of passed arguments. |
417 descriptor.SetAt(kCountIndex, arg_count); | 420 descriptor.SetAt(kCountIndex, arg_count); |
418 | 421 |
419 // Set number of positional arguments. | 422 // Set number of positional arguments. |
420 descriptor.SetAt(kPositionalCountIndex, arg_count); | 423 descriptor.SetAt(kPositionalCountIndex, arg_count); |
421 | 424 |
422 // Set terminating null. | 425 // Set terminating null. |
423 descriptor.SetAt((descriptor_len - 1), Object::null_object()); | 426 descriptor.SetAt((descriptor_len - 1), Object::null_object()); |
424 | 427 |
425 // Share the immutable descriptor when possible by canonicalizing it. | 428 // Share the immutable descriptor when possible by canonicalizing it. |
426 descriptor.MakeImmutable(); | 429 descriptor.MakeImmutable(); |
427 if (canonicalize) { | 430 if (canonicalize) { |
428 descriptor ^= descriptor.CheckAndCanonicalize(thread, NULL); | 431 descriptor ^= descriptor.CheckAndCanonicalize(thread, NULL); |
429 } | 432 } |
430 ASSERT(!descriptor.IsNull()); | 433 ASSERT(!descriptor.IsNull()); |
431 return descriptor.raw(); | 434 return descriptor.raw(); |
432 } | 435 } |
433 | 436 |
434 | 437 |
435 void ArgumentsDescriptor::InitOnce() { | 438 void ArgumentsDescriptor::InitOnce() { |
436 for (int i = 0; i < kCachedDescriptorCount; i++) { | 439 for (int i = 0; i < kCachedDescriptorCount; i++) { |
437 cached_args_descriptors_[i] = ArgumentsDescriptor::NewNonCached(i, false); | 440 cached_args_descriptors_[i] = |
| 441 ArgumentsDescriptor::NewNonCached(0, i, false); |
438 } | 442 } |
439 } | 443 } |
440 | 444 |
441 | 445 |
442 RawObject* DartLibraryCalls::InstanceCreate(const Library& lib, | 446 RawObject* DartLibraryCalls::InstanceCreate(const Library& lib, |
443 const String& class_name, | 447 const String& class_name, |
444 const String& constructor_name, | 448 const String& constructor_name, |
445 const Array& arguments) { | 449 const Array& arguments) { |
446 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); | 450 const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); |
447 ASSERT(!cls.IsNull()); | 451 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)); | 623 const Array& args = Array::Handle(Array::New(kNumArguments)); |
620 args.SetAt(0, map); | 624 args.SetAt(0, map); |
621 args.SetAt(1, key); | 625 args.SetAt(1, key); |
622 args.SetAt(2, value); | 626 args.SetAt(2, value); |
623 const Object& result = | 627 const Object& result = |
624 Object::Handle(DartEntry::InvokeFunction(function, args)); | 628 Object::Handle(DartEntry::InvokeFunction(function, args)); |
625 return result.raw(); | 629 return result.raw(); |
626 } | 630 } |
627 | 631 |
628 } // namespace dart | 632 } // namespace dart |
OLD | NEW |