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

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: address review comments 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
« no previous file with comments | « runtime/vm/dart_entry.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/dart_entry.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698