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

Side by Side Diff: runtime/vm/dart_entry.cc

Issue 2941643002: Check for a passed-in type argument vector in the prolog of generic functions. (Closed)
Patch Set: Created 3 years, 6 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 unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698