Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define UNREACHABLE()
Definition assert.h:248
intptr_t PositionalCount() const
bool MatchesNameAt(intptr_t i, const String &other) const
intptr_t NamedCount() const
Definition dart_entry.h:43
ArgumentsDescriptor(const Array &array)
const char * ToCString() const
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)
intptr_t Count() const
void PrintTo(BaseTextBuffer *buffer, bool show_named_positions=false) const
ArrayPtr GetArgumentNames() const
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
intptr_t TypeArgsLen() const
intptr_t PositionAt(intptr_t i) const
StringPtr NameAt(intptr_t i) const
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
void MakeImmutable() const
Definition object.cc:24916
ObjectPtr At(intptr_t index) const
Definition object.h:10854
intptr_t Length() const
Definition object.h:10808
void SetAt(intptr_t index, const Object &value) const
Definition object.h:10858
char * buffer() const
Definition text_buffer.h:35
static const Bool & False()
Definition object.h:10778
FunctionPtr LookupConstructorAllowPrivate(const String &name) const
Definition object.cc:6208
FunctionPtr LookupStaticFunction(const String &name) const
Definition object.cc:6192
ErrorPtr EnsureIsFinalized(Thread *thread) const
Definition object.cc:4979
static ObjectPtr CompileFunction(Thread *thread, const Function &function)
Definition compiler.cc:825
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)
static ObjectPtr InvokeClosure(Thread *thread, const Array &arguments)
static ObjectPtr InvokeFunction(const Function &function, const Array &arguments)
Definition dart_entry.cc:31
static ObjectPtr HashCode(const Instance &receiver)
static ObjectPtr HandleMessage(Dart_Port port_id, const Instance &message)
static ObjectPtr RehashObjectsInDartCollection(Thread *thread, const Object &array_or_growable_array)
static ObjectPtr LookupHandler(Dart_Port port_id)
static ObjectPtr EnsureScheduleImmediate()
static ObjectPtr HandleFinalizerMessage(const FinalizerBase &finalizer)
static ObjectPtr RehashObjectsInDartCore(Thread *thread, const Object &array_or_growable_array)
static ObjectPtr InstanceCreate(const Library &library, const String &exception_name, const String &constructor_name, const Array &arguments)
static ObjectPtr LookupOpenPorts()
static ObjectPtr Equals(const Instance &left, const Instance &right)
static ObjectPtr ToString(const Instance &receiver)
static ObjectPtr DrainMicrotaskQueue()
bool IsStepping() const
Definition debugger.h:710
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)
Isolate * isolate() const
Definition object.h:13014
@ kOld
Definition heap.h:39
InstancePtr Canonicalize(Thread *thread) const
Definition object.cc:20485
static InstancePtr New(const Class &cls, Heap::Space space=Heap::kNew)
Definition object.cc:20976
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition object.cc:23063
ObjectStore * object_store() const
Definition isolate.h:505
IsolateObjectStore * isolate_object_store() const
Definition isolate.h:960
Debugger * debugger() const
Definition isolate.h:1061
static LibraryPtr CoreLibrary()
Definition object.cc:14834
StringPtr PrivateName(const String &name) const
Definition object.cc:14751
static LibraryPtr IsolateLibrary()
Definition object.cc:14854
ClassPtr LookupClassAllowPrivate(const String &name) const
Definition object.cc:14160
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition object.cc:14131
static LibraryPtr CollectionLibrary()
Definition object.cc:14838
static LibraryPtr AsyncLibrary()
Definition object.cc:14826
ClassPtr LookupClass(const String &name) const
Definition object.cc:14152
static OSThread * Current()
Definition os_thread.h:175
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=true)
Definition resolver.cc:198
static Simulator * Current()
static SmiPtr New(intptr_t value)
Definition object.h:9985
intptr_t Value() const
Definition object.h:9969
static StringPtr Concat(const String &str1, const String &str2, Heap::Space space=Heap::kNew)
Definition object.cc:24116
Zone * zone() const
void set_long_jump_base(LongJumpScope *value)
LongJumpScope * long_jump_base() const
int32_t no_callback_scope_depth() const
Definition thread.h:618
static Thread * Current()
Definition thread.h:361
bool IsDartMutatorThread() const
Definition thread.h:546
Isolate * isolate() const
Definition thread.h:533
uword heap_base() const
Definition thread.h:428
IsolateGroup * isolate_group() const
Definition thread.h:540
static UnhandledExceptionPtr New(const Instance &exception, const Instance &stacktrace, Heap::Space space=Heap::kNew)
Definition object.cc:19989
#define THR_Print(format,...)
Definition log.h:20
int64_t Dart_Port
Definition dart_api.h:1524
#define ASSERT(E)
VkInstance instance
Definition main.cc:48
#define FATAL(error)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
#define DECLARE_FLAG(type, name)
Definition flags.h:14
Dart_NativeFunction function
Definition fuchsia.cc:51
Win32Message message
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)
static ObjectPtr RehashObjects(Zone *zone, const Library &library, const Object &array_or_growable_array)
#define Pd
Definition globals.h:408
#define NO_SANITIZE_SAFE_STACK
Definition safe_stack.h:17
Point offset