Flutter Engine
The Flutter Engine
dart_entry.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/dart_entry.h"
6
9#include "vm/debugger.h"
10#include "vm/dispatch_table.h"
11#include "vm/heap/safepoint.h"
12#include "vm/object_store.h"
13#include "vm/resolver.h"
14#include "vm/runtime_entry.h"
15#include "vm/simulator.h"
16#include "vm/stub_code.h"
17#include "vm/symbols.h"
18#include "vm/zone_text_buffer.h"
19
20#if !defined(DART_PRECOMPILED_RUNTIME)
22#endif // !defined(DART_PRECOMPILED_RUNTIME)
23
24namespace dart {
25
26DECLARE_FLAG(bool, precompiled_mode);
27
28// A cache of VM heap allocated arguments descriptors.
29ArrayPtr ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount];
30
32 const Array& arguments) {
33 ASSERT(Thread::Current()->IsDartMutatorThread());
34 const int kTypeArgsLen = 0; // No support to pass type args to generic func.
35 const Array& arguments_descriptor = Array::Handle(
36 ArgumentsDescriptor::NewBoxed(kTypeArgsLen, arguments.Length()));
37 return InvokeFunction(function, arguments, arguments_descriptor);
38}
39
41 public:
44 // Ensure we do not attempt to long jump across Dart frames.
45 saved_long_jump_base_ = thread->long_jump_base();
46 thread->set_long_jump_base(nullptr);
47
48#if defined(USING_SAFE_STACK)
49 // Remember the safestack pointer at entry so it can be restored in
50 // Exceptions::JumpToFrame when a Dart exception jumps over C++ frames.
51 saved_safestack_limit_ = OSThread::GetCurrentSafestackPointer();
52 thread->set_saved_safestack_limit(saved_safestack_limit_);
53#endif
54 }
55
57#if defined(USING_SAFE_STACK)
58 thread()->set_saved_safestack_limit(saved_safestack_limit_);
59#endif
60
61 ASSERT(thread()->long_jump_base() == nullptr);
62 thread()->set_long_jump_base(saved_long_jump_base_);
63 }
64
65 private:
66 LongJumpScope* saved_long_jump_base_;
67#if defined(USING_SAFE_STACK)
68 uword saved_safestack_limit_ = 0;
69#endif
70};
71
72// Note: The invocation stub follows the C ABI, so we cannot pass C++ struct
73// values like ObjectPtr. In some calling conventions (IA32), ObjectPtr is
74// passed/returned different from a pointer.
75extern "C" typedef uword /*ObjectPtr*/ (*invokestub)(
76#if defined(DART_PRECOMPILED_RUNTIME)
77 uword entry_point,
78#else
79 uword /*CodePtr*/ target_code,
80#endif
81 uword /*ArrayPtr*/ arguments_descriptor,
82 uword /*ArrayPtr*/ arguments,
83 Thread* thread);
84
86 const Array& arguments,
87 const Array& arguments_descriptor) {
88#if defined(DART_PRECOMPILER)
89 if (FLAG_precompiled_mode) {
90 FATAL("Should never invoke Dart code during AOT compilation");
91 }
92#endif
93
94 Thread* thread = Thread::Current();
95 ASSERT(thread->IsDartMutatorThread());
96 ASSERT(!function.IsNull());
97
98#if !defined(DART_PRECOMPILED_RUNTIME)
99 if (!function.HasCode()) {
101 thread->zone(), Compiler::CompileFunction(thread, function));
102 if (result.IsError()) {
103 return Error::Cast(result).ptr();
104 }
105 }
106#endif // defined(DART_PRECOMPILED_RUNTIME)
107
108 ASSERT(function.HasCode());
109
110 DartEntryScope dart_entry_scope(thread);
111
112 const uword stub = StubCode::InvokeDartCode().EntryPoint();
113#if defined(USING_SIMULATOR)
114 return bit_copy<ObjectPtr, int64_t>(Simulator::Current()->Call(
115 static_cast<intptr_t>(stub),
116#if defined(DART_PRECOMPILED_RUNTIME)
117 static_cast<intptr_t>(function.entry_point()),
118#else
119 static_cast<intptr_t>(function.CurrentCode()),
120#endif
121 static_cast<intptr_t>(arguments_descriptor.ptr()),
122 static_cast<intptr_t>(arguments.ptr()),
123 reinterpret_cast<intptr_t>(thread)));
124#else // USING_SIMULATOR
125 return static_cast<ObjectPtr>((reinterpret_cast<invokestub>(stub))(
126#if defined(DART_PRECOMPILED_RUNTIME)
127 function.entry_point(),
128#else
129 static_cast<uword>(function.CurrentCode()),
130#endif
131 static_cast<uword>(arguments_descriptor.ptr()),
132 static_cast<uword>(arguments.ptr()), thread));
133#endif
134}
135
136#if defined(TESTING)
138ObjectPtr DartEntry::InvokeCode(const Code& code,
139 const Array& arguments_descriptor,
140 const Array& arguments,
141 Thread* thread) {
142#if defined(DART_PRECOMPILER)
143 if (FLAG_precompiled_mode) {
144 FATAL("Should never invoke Dart code during AOT compilation");
145 }
146#endif
147
148 ASSERT(!code.IsNull());
149 ASSERT(thread->no_callback_scope_depth() == 0);
150
151 DartEntryScope dart_entry_scope(thread);
152
153 const uword stub = StubCode::InvokeDartCode().EntryPoint();
154#if defined(DART_PRECOMPILED_RUNTIME)
155#if defined(USING_SIMULATOR)
156 return bit_copy<ObjectPtr, int64_t>(Simulator::Current()->Call(
157 static_cast<intptr_t>(stub), static_cast<intptr_t>(code.EntryPoint()),
158 static_cast<intptr_t>(arguments_descriptor.ptr()),
159 static_cast<intptr_t>(arguments.ptr()),
160 reinterpret_cast<intptr_t>(thread)));
161#else
162 return static_cast<ObjectPtr>((reinterpret_cast<invokestub>(stub))(
163 code.EntryPoint(), arguments_descriptor.ptr(), arguments.ptr(), thread));
164#endif
165#else // defined(DART_PRECOMPILED_RUNTIME)
166#if defined(USING_SIMULATOR)
167 return bit_copy<ObjectPtr, int64_t>(Simulator::Current()->Call(
168 static_cast<intptr_t>(stub), static_cast<intptr_t>(code.ptr()),
169 static_cast<intptr_t>(arguments_descriptor.ptr()),
170 static_cast<intptr_t>(arguments.ptr()),
171 reinterpret_cast<intptr_t>(thread)));
172#else
173 return static_cast<ObjectPtr>((reinterpret_cast<invokestub>(stub))(
174 static_cast<uword>(code.ptr()),
175 static_cast<uword>(arguments_descriptor.ptr()),
176 static_cast<uword>(arguments.ptr()), thread));
177#endif
178#endif
179}
180#endif // defined(TESTING)
181
182ObjectPtr DartEntry::ResolveCallable(Thread* thread,
183 const Array& arguments,
184 const Array& arguments_descriptor) {
185 auto isolate_group = thread->isolate_group();
186 auto zone = thread->zone();
187
188 const ArgumentsDescriptor args_desc(arguments_descriptor);
189 const intptr_t receiver_index = args_desc.FirstArgIndex();
190 const intptr_t type_args_len = args_desc.TypeArgsLen();
191 const auto& getter_name = Symbols::GetCall();
192
193 auto& instance = Instance::Handle(zone);
194 auto& function = Function::Handle(zone);
195 auto& cls = Class::Handle(zone);
196
197 // The null instance cannot resolve to a callable, so we can stop there.
198 for (instance ^= arguments.At(receiver_index); !instance.IsNull();
199 instance ^= arguments.At(receiver_index)) {
200 // The instance is a callable, so check that its function is compatible.
201 if (instance.IsCallable(&function)) {
202 bool matches = function.AreValidArguments(args_desc, nullptr);
203
204 if (matches && type_args_len > 0 && function.IsClosureFunction()) {
205 // Though the closure function is generic, the closure itself may
206 // not be because it closes over delayed function type arguments.
207 matches = Closure::Cast(instance).IsGeneric();
208 }
209
210 if (matches) {
211 return function.ptr();
212 }
213 }
214
215 // Special case: closures are implemented with a call getter instead of a
216 // call method, so checking for a call getter would cause an infinite loop.
217 if (instance.IsClosure()) {
218 break;
219 }
220
221 cls = instance.clazz();
222 // Find a call getter, if any, in the class hierarchy.
223 function = Resolver::ResolveDynamicAnyArgs(zone, cls, getter_name,
224 /*allow_add=*/false);
225 if (function.IsNull()) {
226 break;
227 }
228 if (!OSThread::Current()->HasStackHeadroom()) {
229 const Instance& exception = Instance::Handle(
230 zone, isolate_group->object_store()->stack_overflow());
231 return UnhandledException::New(exception, StackTrace::Handle(zone));
232 }
233
234 const Array& getter_arguments = Array::Handle(zone, Array::New(1));
235 getter_arguments.SetAt(0, instance);
236 const Object& getter_result = Object::Handle(
237 zone, DartEntry::InvokeFunction(function, getter_arguments));
238 if (getter_result.IsError()) {
239 return getter_result.ptr();
240 }
241 ASSERT(getter_result.IsNull() || getter_result.IsInstance());
242
243 // We have a new possibly compatible callable, so set the first argument
244 // accordingly so it gets picked up in the main loop.
245 arguments.SetAt(receiver_index, getter_result);
246 }
247
248 // No compatible callable was found.
249 return Function::null();
250}
251
252ObjectPtr DartEntry::InvokeCallable(Thread* thread,
253 const Function& callable_function,
254 const Array& arguments,
255 const Array& arguments_descriptor) {
256 auto const zone = thread->zone();
257 const ArgumentsDescriptor args_desc(arguments_descriptor);
258 if (callable_function.IsNull()) {
259 // No compatible callable was found, so invoke noSuchMethod.
260 auto& instance =
261 Instance::CheckedHandle(zone, arguments.At(args_desc.FirstArgIndex()));
262 // For closures, use the name of the closure, not 'call'.
263 const String* target_name = &Symbols::call();
264 if (instance.IsClosure()) {
265 auto const& function =
266 Function::Handle(zone, Closure::Cast(instance).function());
267 target_name = &String::Handle(function.QualifiedUserVisibleName());
268 }
269 return InvokeNoSuchMethod(thread, instance, *target_name, arguments,
270 arguments_descriptor);
271 }
272
273 const auto& result = Object::Handle(
274 zone, callable_function.DoArgumentTypesMatch(arguments, args_desc));
275 if (result.IsError()) {
276 return result.ptr();
277 }
278
279 return InvokeFunction(callable_function, arguments, arguments_descriptor);
280}
281
282ObjectPtr DartEntry::InvokeClosure(Thread* thread, const Array& arguments) {
283 auto const zone = thread->zone();
284 const int kTypeArgsLen = 0; // No support to pass type args to generic func.
285
286 // Closures always have boxed parameters
287 const Array& arguments_descriptor = Array::Handle(
288 zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, arguments.Length()));
289 return InvokeClosure(thread, arguments, arguments_descriptor);
290}
291
293 const Array& arguments,
294 const Array& arguments_descriptor) {
295 auto const zone = thread->zone();
296 const Object& resolved_result = Object::Handle(
297 zone, ResolveCallable(thread, arguments, arguments_descriptor));
298 if (resolved_result.IsError()) {
299 return resolved_result.ptr();
300 }
301
302 const auto& function =
303 Function::Handle(zone, Function::RawCast(resolved_result.ptr()));
304 return InvokeCallable(thread, function, arguments, arguments_descriptor);
305}
306
308 const Instance& receiver,
309 const String& target_name,
310 const Array& arguments,
311 const Array& arguments_descriptor) {
312 auto const zone = thread->zone();
313 const ArgumentsDescriptor args_desc(arguments_descriptor);
314 ASSERT(
315 CompressedInstancePtr(receiver.ptr()).Decompress(thread->heap_base()) ==
316 arguments.At(args_desc.FirstArgIndex()));
317 // Allocate an Invocation object.
318 const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
319
320 Class& invocation_mirror_class = Class::Handle(
321 zone, core_lib.LookupClass(String::Handle(
322 zone, core_lib.PrivateName(Symbols::InvocationMirror()))));
323 ASSERT(!invocation_mirror_class.IsNull());
324 const auto& error = invocation_mirror_class.EnsureIsFinalized(thread);
327 zone, core_lib.PrivateName(Symbols::AllocateInvocationMirror()));
328 const Function& allocation_function = Function::Handle(
329 zone, invocation_mirror_class.LookupStaticFunction(function_name));
330 ASSERT(!allocation_function.IsNull());
331 const int kNumAllocationArgs = 4;
332 const Array& allocation_args =
333 Array::Handle(zone, Array::New(kNumAllocationArgs));
334 allocation_args.SetAt(0, target_name);
335 allocation_args.SetAt(1, arguments_descriptor);
336 allocation_args.SetAt(2, arguments);
337 allocation_args.SetAt(3, Bool::False()); // Not a super invocation.
338 const Object& invocation_mirror = Object::Handle(
339 zone, InvokeFunction(allocation_function, allocation_args));
340 if (invocation_mirror.IsError()) {
341 Exceptions::PropagateError(Error::Cast(invocation_mirror));
342 UNREACHABLE();
343 }
344
345 // Now use the invocation mirror object and invoke NoSuchMethod.
346 const int kNumArguments = 2;
348 zone,
349 core_lib.LookupFunctionAllowPrivate(Symbols::_objectNoSuchMethod()));
350 ASSERT(!function.IsNull());
351 const Array& args = Array::Handle(zone, Array::New(kNumArguments));
352 args.SetAt(0, receiver);
353 args.SetAt(1, invocation_mirror);
355}
356
357ArgumentsDescriptor::ArgumentsDescriptor(const Array& array) : array_(array) {}
358
360 return Smi::Value(Smi::RawCast(array_.At(kTypeArgsLenIndex)));
361}
362
364 return Smi::Value(Smi::RawCast(array_.At(kCountIndex)));
365}
366
368 return Smi::Value(Smi::RawCast(array_.At(kSizeIndex)));
369}
370
372 return Smi::Value(Smi::RawCast(array_.At(kPositionalCountIndex)));
373}
374
375StringPtr ArgumentsDescriptor::NameAt(intptr_t index) const {
376 const intptr_t offset =
377 kFirstNamedEntryIndex + (index * kNamedEntrySize) + kNameOffset;
379 result ^= array_.At(offset);
380 return result.ptr();
381}
382
383intptr_t ArgumentsDescriptor::PositionAt(intptr_t index) const {
384 const intptr_t offset =
385 kFirstNamedEntryIndex + (index * kNamedEntrySize) + kPositionOffset;
386 return Smi::Value(Smi::RawCast(array_.At(offset)));
387}
388
390 const String& other) const {
391 return NameAt(index) == other.ptr();
392}
393
395 const intptr_t num_named_args = NamedCount();
396 if (num_named_args == 0) {
397 return Array::null();
398 }
399
400 Zone* zone = Thread::Current()->zone();
401 const Array& names =
402 Array::Handle(zone, Array::New(num_named_args, Heap::kOld));
403 String& name = String::Handle(zone);
404 const intptr_t num_pos_args = PositionalCount();
405 for (intptr_t i = 0; i < num_named_args; ++i) {
406 const intptr_t index = PositionAt(i) - num_pos_args;
407 name = NameAt(i);
408 ASSERT(names.At(index) == Object::null());
409 names.SetAt(index, name);
410 }
411 return names.ptr();
412}
413
415 bool show_named_positions) const {
416 if (TypeArgsLen() > 0) {
417 buffer->Printf("<%" Pd ">", TypeArgsLen());
418 }
419 buffer->Printf("(%" Pd "", Count());
420 if (NamedCount() > 0) {
421 buffer->AddString(" {");
422 auto& str = String::Handle();
423 for (intptr_t i = 0; i < NamedCount(); i++) {
424 if (i != 0) {
425 buffer->AddString(", ");
426 }
427 str = NameAt(i);
428 buffer->Printf("%s", str.ToCString());
429 if (show_named_positions) {
430 buffer->Printf(" (%" Pd ")", PositionAt(i));
431 }
432 }
433 buffer->Printf("}");
434 }
435 buffer->Printf(")");
436}
437
439 ZoneTextBuffer buf(Thread::Current()->zone());
440 PrintTo(&buf);
441 return buf.buffer();
442}
443
444ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
445 intptr_t num_arguments,
446 intptr_t size_arguments,
447 const Array& optional_arguments_names,
448 Heap::Space space) {
449 const intptr_t num_named_args =
450 optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length();
451 if (num_named_args == 0) {
452 return ArgumentsDescriptor::New(type_args_len, num_arguments,
453 size_arguments, space);
454 }
455 ASSERT(type_args_len >= 0);
456 ASSERT(num_arguments >= 0);
457 const intptr_t num_pos_args = num_arguments - num_named_args;
458
459 // Build the arguments descriptor array, which consists of the type
460 // argument vector length (0 if none); total argument count; the positional
461 // argument count; a sequence of (name, position) pairs, sorted by name, for
462 // each named optional argument; and a terminating null to simplify iterating
463 // in generated code.
464 Thread* thread = Thread::Current();
465 Zone* zone = thread->zone();
466 const intptr_t descriptor_len = LengthFor(num_named_args);
467 Array& descriptor = Array::Handle(zone, Array::New(descriptor_len, space));
468
469 // Set length of type argument vector.
470 descriptor.SetAt(kTypeArgsLenIndex, Smi::Handle(Smi::New(type_args_len)));
471 // Set total number of passed arguments.
472 descriptor.SetAt(kCountIndex, Smi::Handle(Smi::New(num_arguments)));
473 // Set total number of passed arguments.
474 descriptor.SetAt(kSizeIndex, Smi::Handle(Smi::New(size_arguments)));
475
476 // Set number of positional arguments.
477 descriptor.SetAt(kPositionalCountIndex, Smi::Handle(Smi::New(num_pos_args)));
478
479 // Set alphabetically sorted entries for named arguments.
480 String& name = String::Handle(zone);
481 Smi& pos = Smi::Handle(zone);
482 String& previous_name = String::Handle(zone);
483 Smi& previous_pos = Smi::Handle(zone);
484 for (intptr_t i = 0; i < num_named_args; i++) {
485 name ^= optional_arguments_names.At(i);
486 pos = Smi::New(num_pos_args + i);
487 intptr_t insert_index = kFirstNamedEntryIndex + (kNamedEntrySize * i);
488 // Shift already inserted pairs with "larger" names.
489 while (insert_index > kFirstNamedEntryIndex) {
490 intptr_t previous_index = insert_index - kNamedEntrySize;
491 previous_name ^= descriptor.At(previous_index + kNameOffset);
492 intptr_t result = name.CompareTo(previous_name);
493 ASSERT(result != 0); // Duplicate argument names checked in parser.
494 if (result > 0) break;
495 previous_pos ^= descriptor.At(previous_index + kPositionOffset);
496 descriptor.SetAt(insert_index + kNameOffset, previous_name);
497 descriptor.SetAt(insert_index + kPositionOffset, previous_pos);
498 insert_index = previous_index;
499 }
500 // Insert pair in descriptor array.
501 descriptor.SetAt(insert_index + kNameOffset, name);
502 descriptor.SetAt(insert_index + kPositionOffset, pos);
503 }
504 // Set terminating null.
505 descriptor.SetAt(descriptor_len - 1, Object::null_object());
506
507 // Share the immutable descriptor when possible by canonicalizing it.
508 descriptor.MakeImmutable();
509 descriptor ^= descriptor.Canonicalize(thread);
510 ASSERT(!descriptor.IsNull());
511 return descriptor.ptr();
512}
513
514ArrayPtr ArgumentsDescriptor::New(intptr_t type_args_len,
515 intptr_t num_arguments,
516 intptr_t size_arguments,
517 Heap::Space space) {
518 ASSERT(type_args_len >= 0);
519 ASSERT(num_arguments >= 0);
520
521 if ((type_args_len == 0) && (num_arguments < kCachedDescriptorCount) &&
522 (num_arguments == size_arguments)) {
523 return cached_args_descriptors_[num_arguments];
524 }
525 return NewNonCached(type_args_len, num_arguments, size_arguments, true,
526 space);
527}
528
529ArrayPtr ArgumentsDescriptor::NewNonCached(intptr_t type_args_len,
530 intptr_t num_arguments,
531 intptr_t size_arguments,
532 bool canonicalize,
533 Heap::Space space) {
534 // Build the arguments descriptor array, which consists of the length of the
535 // type argument vector, total argument count; the positional argument count;
536 // and a terminating null to simplify iterating in generated code.
537 Thread* thread = Thread::Current();
538 Zone* zone = thread->zone();
539 const intptr_t descriptor_len = LengthFor(0);
540 Array& descriptor = Array::Handle(zone, Array::New(descriptor_len, space));
541 const Smi& arg_count = Smi::Handle(zone, Smi::New(num_arguments));
542 const Smi& arg_size = Smi::Handle(zone, Smi::New(size_arguments));
543
544 // Set type argument vector length.
545 descriptor.SetAt(kTypeArgsLenIndex,
546 Smi::Handle(zone, Smi::New(type_args_len)));
547
548 // Set total number of passed arguments.
549 descriptor.SetAt(kCountIndex, arg_count);
550
551 // Set total size of passed arguments.
552 descriptor.SetAt(kSizeIndex, arg_size);
553
554 // Set number of positional arguments.
555 descriptor.SetAt(kPositionalCountIndex, arg_count);
556
557 // Set terminating null.
558 descriptor.SetAt((descriptor_len - 1), Object::null_object());
559
560 // Share the immutable descriptor when possible by canonicalizing it.
561 descriptor.MakeImmutable();
562 if (canonicalize) {
563 descriptor ^= descriptor.Canonicalize(thread);
564 }
565 ASSERT(!descriptor.IsNull());
566 return descriptor.ptr();
567}
568
570 for (int i = 0; i < kCachedDescriptorCount; i++) {
571 cached_args_descriptors_[i] =
572 NewNonCached(/*type_args_len=*/0, i, i, false, Heap::kOld);
573 }
574}
575
577 for (int i = 0; i < kCachedDescriptorCount; i++) {
578 // Don't free pointers to RawArray objects managed by the VM.
579 cached_args_descriptors_[i] = nullptr;
580 }
581}
582
584 const String& class_name,
585 const String& constructor_name,
586 const Array& arguments) {
588 ASSERT(!cls.IsNull());
589 // For now, we only support a non-parameterized or raw type.
590 const int kNumExtraArgs = 1; // implicit rcvr arg.
591 const Instance& exception_object = Instance::Handle(Instance::New(cls));
592 const Array& constructor_arguments =
593 Array::Handle(Array::New(arguments.Length() + kNumExtraArgs));
594 constructor_arguments.SetAt(0, exception_object);
595 Object& obj = Object::Handle();
596 for (intptr_t i = 0; i < arguments.Length(); i++) {
597 obj = arguments.At(i);
598 constructor_arguments.SetAt((i + kNumExtraArgs), obj);
599 }
600
601 const String& function_name =
602 String::Handle(String::Concat(class_name, constructor_name));
603 const Function& constructor =
605 ASSERT(!constructor.IsNull());
606 const Object& retval = Object::Handle(
607 DartEntry::InvokeFunction(constructor, constructor_arguments));
608 ASSERT(retval.IsNull() || retval.IsError());
609 if (retval.IsError()) {
610 return retval.ptr();
611 }
612 return exception_object.ptr();
613}
614
616 Thread* thread = Thread::Current();
617 Zone* zone = thread->zone();
618 const auto& function = Function::Handle(
619 zone,
620 thread->isolate_group()->object_store()->_object_to_string_function());
621 ASSERT(!function.IsNull());
622 const int kNumArguments = 1;
623 const Array& args = Array::Handle(zone, Array::New(kNumArguments));
624 args.SetAt(0, receiver);
625 const Object& result =
627 ASSERT(result.IsInstance() || result.IsError());
628 return result.ptr();
629}
630
632 Thread* thread = Thread::Current();
633 Zone* zone = thread->zone();
634 const auto& function = Function::Handle(
635 zone,
636 thread->isolate_group()->object_store()->_object_hash_code_function());
637 ASSERT(!function.IsNull());
638 const int kNumArguments = 1;
639 const Array& args = Array::Handle(zone, Array::New(kNumArguments));
640 args.SetAt(0, receiver);
641 const Object& result =
643 ASSERT(result.IsInstance() || result.IsError());
644 return result.ptr();
645}
646
648 const Instance& right) {
649 Thread* thread = Thread::Current();
650 Zone* zone = thread->zone();
651 const auto& function = Function::Handle(
652 zone, thread->isolate_group()->object_store()->_object_equals_function());
653 ASSERT(!function.IsNull());
654 const int kNumArguments = 2;
655 const Array& args = Array::Handle(zone, Array::New(kNumArguments));
656 args.SetAt(0, left);
657 args.SetAt(1, right);
658 const Object& result =
660 ASSERT(result.IsInstance() || result.IsError());
661 return result.ptr();
662}
663
665 Thread* const thread = Thread::Current();
666 Zone* const zone = thread->zone();
667 const auto& function = Function::Handle(
668 zone, thread->isolate_group()->object_store()->lookup_port_handler());
669 ASSERT(!function.IsNull());
671 zone, thread->isolate()->isolate_object_store()->dart_args_1());
672 ASSERT(!args.IsNull());
673 args.SetAt(0, Integer::Handle(zone, Integer::New(port_id)));
674 const Object& result =
676 return result.ptr();
677}
678
680 Thread* thread = Thread::Current();
681 Zone* zone = thread->zone();
683 zone, thread->isolate_group()->object_store()->lookup_open_ports());
684 ASSERT(!function.IsNull());
686 zone, DartEntry::InvokeFunction(function, Object::empty_array()));
687 return result.ptr();
688}
689
691#if !defined(PRODUCT)
692 if (isolate->debugger()->IsStepping()) {
693 // If the isolate is being debugged and the debugger was stepping
694 // through code, enable single stepping so debugger will stop
695 // at the first location the user is interested in.
697 }
698#endif
699}
700
702 const Instance& message) {
703 auto* const thread = Thread::Current();
704 auto* const zone = thread->zone();
705 auto* const isolate = thread->isolate();
706 auto* const object_store = thread->isolate_group()->object_store();
707 const auto& function =
708 Function::Handle(zone, object_store->handle_message_function());
709 ASSERT(!function.IsNull());
710 Array& args =
711 Array::Handle(zone, isolate->isolate_object_store()->dart_args_2());
712 ASSERT(!args.IsNull());
713 args.SetAt(0, Integer::Handle(zone, Integer::New(port_id)));
714 args.SetAt(1, message);
716 const Object& handler =
718 return handler.ptr();
719}
720
722 const FinalizerBase& finalizer) {
723 if (FLAG_trace_finalizers) {
724 THR_Print("Running finalizer %p callback on isolate %p\n",
725 finalizer.ptr()->untag(), finalizer.isolate());
726 }
727
728 auto* const thread = Thread::Current();
729 auto* const zone = thread->zone();
730 auto* const isolate = thread->isolate();
731 auto* const object_store = thread->isolate_group()->object_store();
732 auto& function = Function::Handle(zone);
733 if (finalizer.IsFinalizer()) {
734 function ^= object_store->handle_finalizer_message_function();
735 } else {
736 ASSERT(finalizer.IsNativeFinalizer());
737 function ^= object_store->handle_native_finalizer_message_function();
738 }
739 ASSERT(!function.IsNull());
740 Array& args =
741 Array::Handle(zone, isolate->isolate_object_store()->dart_args_1());
742 ASSERT(!args.IsNull());
743 args.SetAt(0, finalizer);
745 const Object& handler =
747 return handler.ptr();
748}
749
751 Zone* zone = Thread::Current()->zone();
752 Library& isolate_lib = Library::Handle(zone, Library::IsolateLibrary());
753 ASSERT(!isolate_lib.IsNull());
756 Symbols::_runPendingImmediateCallback()));
758 zone, DartEntry::InvokeFunction(function, Object::empty_array()));
759 ASSERT(result.IsNull() || result.IsError());
760 return result.ptr();
761}
762
764 Zone* zone = Thread::Current()->zone();
765 const Library& async_lib = Library::Handle(zone, Library::AsyncLibrary());
766 ASSERT(!async_lib.IsNull());
767 const Function& function =
769 Symbols::_ensureScheduleImmediate()));
770 ASSERT(!function.IsNull());
772 zone, DartEntry::InvokeFunction(function, Object::empty_array()));
773 ASSERT(result.IsNull() || result.IsError());
774 return result.ptr();
775}
776
778 const Library& library,
779 const Object& array_or_growable_array) {
780 ASSERT(array_or_growable_array.IsArray() ||
781 array_or_growable_array.IsGrowableObjectArray());
782 const auto& rehashing_function = Function::Handle(
783 zone, library.LookupFunctionAllowPrivate(Symbols::_rehashObjects()));
784 ASSERT(!rehashing_function.IsNull());
785
786 const auto& arguments = Array::Handle(zone, Array::New(1));
787 arguments.SetAt(0, array_or_growable_array);
788
789 return DartEntry::InvokeFunction(rehashing_function, arguments);
790}
791
793 Thread* thread,
794 const Object& array_or_growable_array) {
795 auto zone = thread->zone();
796 const auto& collections_lib =
798 return RehashObjects(zone, collections_lib, array_or_growable_array);
799}
800
802 Thread* thread,
803 const Object& array_or_growable_array) {
804 auto zone = thread->zone();
805 const auto& core_lib = Library::Handle(zone, Library::CoreLibrary());
806 return RehashObjects(zone, core_lib, array_or_growable_array);
807}
808
809} // namespace dart
SkPoint pos
#define UNREACHABLE()
Definition: assert.h:248
intptr_t PositionalCount() const
Definition: dart_entry.cc:371
bool MatchesNameAt(intptr_t i, const String &other) const
Definition: dart_entry.cc:389
intptr_t NamedCount() const
Definition: dart_entry.h:43
ArgumentsDescriptor(const Array &array)
Definition: dart_entry.cc:357
const char * ToCString() const
Definition: dart_entry.cc:438
static ArrayPtr New(intptr_t type_args_len, intptr_t num_arguments, intptr_t size_arguments, const Array &optional_arguments_names, Heap::Space space=Heap::kOld)
Definition: dart_entry.cc:444
intptr_t Count() const
Definition: dart_entry.cc:363
void PrintTo(BaseTextBuffer *buffer, bool show_named_positions=false) const
Definition: dart_entry.cc:414
ArrayPtr GetArgumentNames() const
Definition: dart_entry.cc:394
static ArrayPtr NewBoxed(intptr_t type_args_len, intptr_t num_arguments, const Array &optional_arguments_names, Heap::Space space=Heap::kOld)
Definition: dart_entry.h:83
intptr_t FirstArgIndex() const
Definition: dart_entry.h:37
intptr_t Size() const
Definition: dart_entry.cc:367
intptr_t TypeArgsLen() const
Definition: dart_entry.cc:359
intptr_t PositionAt(intptr_t i) const
Definition: dart_entry.cc:383
StringPtr NameAt(intptr_t i) const
Definition: dart_entry.cc:375
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
void MakeImmutable() const
Definition: object.cc:24837
ObjectPtr At(intptr_t index) const
Definition: object.h:10875
intptr_t Length() const
Definition: object.h:10829
void SetAt(intptr_t index, const Object &value) const
Definition: object.h:10880
char * buffer() const
Definition: text_buffer.h:35
static const Bool & False()
Definition: object.h:10799
FunctionPtr LookupConstructorAllowPrivate(const String &name) const
Definition: object.cc:6153
FunctionPtr LookupStaticFunction(const String &name) const
Definition: object.cc:6137
ErrorPtr EnsureIsFinalized(Thread *thread) const
Definition: object.cc:4924
static ObjectPtr CompileFunction(Thread *thread, const Function &function)
Definition: compiler.cc:824
NO_SANITIZE_SAFE_STACK DartEntryScope(Thread *thread)
Definition: dart_entry.cc:43
static ObjectPtr InvokeNoSuchMethod(Thread *thread, const Instance &receiver, const String &target_name, const Array &arguments, const Array &arguments_descriptor)
Definition: dart_entry.cc:307
static ObjectPtr InvokeClosure(Thread *thread, const Array &arguments)
Definition: dart_entry.cc:282
static ObjectPtr InvokeFunction(const Function &function, const Array &arguments)
Definition: dart_entry.cc:31
static ObjectPtr HashCode(const Instance &receiver)
Definition: dart_entry.cc:631
static ObjectPtr HandleMessage(Dart_Port port_id, const Instance &message)
Definition: dart_entry.cc:701
static ObjectPtr RehashObjectsInDartCollection(Thread *thread, const Object &array_or_growable_array)
Definition: dart_entry.cc:792
static ObjectPtr LookupHandler(Dart_Port port_id)
Definition: dart_entry.cc:664
static ObjectPtr EnsureScheduleImmediate()
Definition: dart_entry.cc:763
static ObjectPtr HandleFinalizerMessage(const FinalizerBase &finalizer)
Definition: dart_entry.cc:721
static ObjectPtr RehashObjectsInDartCore(Thread *thread, const Object &array_or_growable_array)
Definition: dart_entry.cc:801
static ObjectPtr InstanceCreate(const Library &library, const String &exception_name, const String &constructor_name, const Array &arguments)
Definition: dart_entry.cc:583
static ObjectPtr LookupOpenPorts()
Definition: dart_entry.cc:679
static ObjectPtr Equals(const Instance &left, const Instance &right)
Definition: dart_entry.cc:647
static ObjectPtr ToString(const Instance &receiver)
Definition: dart_entry.cc:615
static ObjectPtr DrainMicrotaskQueue()
Definition: dart_entry.cc:750
bool IsStepping() const
Definition: debugger.h:712
bool SetResumeAction(ResumeAction action, intptr_t frame_index=1, const char **error=nullptr)
Definition: debugger.cc:1486
static DART_NORETURN void PropagateError(const Error &error)
Definition: exceptions.cc:1003
Isolate * isolate() const
Definition: object.h:13040
@ kOld
Definition: heap.h:39
InstancePtr Canonicalize(Thread *thread) const
Definition: object.cc:20444
static InstancePtr New(const Class &cls, Heap::Space space=Heap::kNew)
Definition: object.cc:20935
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition: object.cc:22984
ObjectStore * object_store() const
Definition: isolate.h:510
IsolateObjectStore * isolate_object_store() const
Definition: isolate.h:1007
Debugger * debugger() const
Definition: isolate.h:1108
static LibraryPtr CoreLibrary()
Definition: object.cc:14787
StringPtr PrivateName(const String &name) const
Definition: object.cc:14704
static LibraryPtr IsolateLibrary()
Definition: object.cc:14807
ClassPtr LookupClassAllowPrivate(const String &name) const
Definition: object.cc:14113
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition: object.cc:14084
static LibraryPtr CollectionLibrary()
Definition: object.cc:14791
static LibraryPtr AsyncLibrary()
Definition: object.cc:14779
ClassPtr LookupClass(const String &name) const
Definition: object.cc:14105
static OSThread * Current()
Definition: os_thread.h:179
UntaggedObject * untag() const
static ObjectPtr null()
Definition: object.h:433
ObjectPtr ptr() const
Definition: object.h:332
bool IsNull() const
Definition: object.h:363
static Object & Handle()
Definition: object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition: object.h:325
static FunctionPtr ResolveDynamicAnyArgs(Zone *zone, const Class &receiver_class, const String &function_name, bool allow_add)
Definition: resolver.cc:185
static Simulator * Current()
static SmiPtr New(intptr_t value)
Definition: object.h:10006
intptr_t Value() const
Definition: object.h:9990
static StringPtr Concat(const String &str1, const String &str2, Heap::Space space=Heap::kNew)
Definition: object.cc:24037
Zone * zone() const
Definition: thread_state.h:37
void set_long_jump_base(LongJumpScope *value)
Definition: thread_state.h:48
LongJumpScope * long_jump_base() const
Definition: thread_state.h:47
int32_t no_callback_scope_depth() const
Definition: thread.h:623
static Thread * Current()
Definition: thread.h:362
bool IsDartMutatorThread() const
Definition: thread.h:551
Isolate * isolate() const
Definition: thread.h:534
uword heap_base() const
Definition: thread.h:429
IsolateGroup * isolate_group() const
Definition: thread.h:541
static UnhandledExceptionPtr New(const Instance &exception, const Instance &stacktrace, Heap::Space space=Heap::kNew)
Definition: object.cc:19939
#define THR_Print(format,...)
Definition: log.h:20
int64_t Dart_Port
Definition: dart_api.h:1525
#define ASSERT(E)
VkInstance instance
Definition: main.cc:48
#define FATAL(error)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
Dart_NativeFunction function
Definition: fuchsia.cc:51
Win32Message message
Definition: dart_vm.cc:33
static const char *const names[]
Definition: symbols.cc:24
const char *const name
const char *const class_name
uintptr_t uword
Definition: globals.h:501
uword(* invokestub)(uword target_code, uword arguments_descriptor, uword arguments, Thread *thread)
Definition: dart_entry.cc:75
const char *const function_name
static void DebuggerSetResumeIfStepping(Isolate *isolate)
Definition: dart_entry.cc:690
static ObjectPtr RehashObjects(Zone *zone, const Library &library, const Object &array_or_growable_array)
Definition: dart_entry.cc:777
DECLARE_FLAG(bool, show_invisible_frames)
def call(args)
Definition: dom.py:159
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
def matches(file)
Definition: gen_manifest.py:38
#define Pd
Definition: globals.h:408
#define NO_SANITIZE_SAFE_STACK
Definition: safe_stack.h:17
SeparatedVector2 offset