Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
isolate.cc
Go to the documentation of this file.
1// Copyright (c) 2012, 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 <memory>
6#include <utility>
7
9#include "platform/assert.h"
10#include "platform/unicode.h"
12#include "vm/class_finalizer.h"
13#include "vm/dart.h"
14#include "vm/dart_api_impl.h"
15#include "vm/dart_api_message.h"
16#include "vm/dart_entry.h"
17#include "vm/exceptions.h"
18#include "vm/hash_table.h"
19#include "vm/lockers.h"
20#include "vm/longjump.h"
21#include "vm/message_handler.h"
22#include "vm/message_snapshot.h"
23#include "vm/object.h"
25#include "vm/object_store.h"
26#include "vm/port.h"
27#include "vm/resolver.h"
28#include "vm/service.h"
29#include "vm/snapshot.h"
30#include "vm/symbols.h"
31
32namespace dart {
33
34DEFINE_NATIVE_ENTRY(Capability_factory, 0, 1) {
35 ASSERT(
36 TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
37 // Keep capability IDs less than 2^53 so web clients of the service
38 // protocol can process it properly.
39 //
40 // See https://github.com/dart-lang/sdk/issues/53081.
41 uint64_t id = isolate->random()->NextJSInt();
42 return Capability::New(id);
43}
44
45DEFINE_NATIVE_ENTRY(Capability_equals, 0, 2) {
46 GET_NON_NULL_NATIVE_ARGUMENT(Capability, recv, arguments->NativeArgAt(0));
47 GET_NON_NULL_NATIVE_ARGUMENT(Capability, other, arguments->NativeArgAt(1));
48 return (recv.Id() == other.Id()) ? Bool::True().ptr() : Bool::False().ptr();
49}
50
51DEFINE_NATIVE_ENTRY(Capability_get_hashcode, 0, 1) {
52 GET_NON_NULL_NATIVE_ARGUMENT(Capability, cap, arguments->NativeArgAt(0));
53 int64_t id = cap.Id();
54 int32_t hi = static_cast<int32_t>(id >> 32);
55 int32_t lo = static_cast<int32_t>(id);
56 int32_t hash = (hi ^ lo) & kSmiMax;
57 return Smi::New(hash);
58}
59
60DEFINE_NATIVE_ENTRY(RawReceivePort_factory, 0, 2) {
61 ASSERT(
62 TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
63 GET_NON_NULL_NATIVE_ARGUMENT(String, debug_name, arguments->NativeArgAt(1));
64 return isolate->CreateReceivePort(debug_name);
65}
66
67DEFINE_NATIVE_ENTRY(RawReceivePort_get_id, 0, 1) {
68 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0));
69 return Integer::New(port.Id());
70}
71
72DEFINE_NATIVE_ENTRY(RawReceivePort_closeInternal, 0, 1) {
73 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0));
74 Dart_Port id = port.Id();
75 isolate->CloseReceivePort(port);
76 return Integer::New(id);
77}
78
79DEFINE_NATIVE_ENTRY(RawReceivePort_setActive, 0, 2) {
80 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0));
81 GET_NON_NULL_NATIVE_ARGUMENT(Bool, active, arguments->NativeArgAt(1));
82 isolate->SetReceivePortKeepAliveState(port, active.value());
83 return Object::null();
84}
85
86DEFINE_NATIVE_ENTRY(RawReceivePort_getActive, 0, 1) {
87 GET_NON_NULL_NATIVE_ARGUMENT(ReceivePort, port, arguments->NativeArgAt(0));
88 return Bool::Get(port.keep_isolate_alive()).ptr();
89}
90
91DEFINE_NATIVE_ENTRY(SendPort_get_id, 0, 1) {
92 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
93 return Integer::New(port.Id());
94}
95
96DEFINE_NATIVE_ENTRY(SendPort_get_hashcode, 0, 1) {
97 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
98 int64_t id = port.Id();
99 int32_t hi = static_cast<int32_t>(id >> 32);
100 int32_t lo = static_cast<int32_t>(id);
101 int32_t hash = (hi ^ lo) & kSmiMax;
102 return Smi::New(hash);
103}
104
105static bool InSameGroup(Isolate* sender, const SendPort& receiver) {
106 // Cannot determine whether sender is in same group (yet).
107 if (sender->origin_id() == ILLEGAL_PORT) return false;
108
109 // Only allow arbitrary messages between isolates of the same IG.
110 return sender->origin_id() == receiver.origin_id();
111}
112
113DEFINE_NATIVE_ENTRY(SendPort_sendInternal_, 0, 2) {
114 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
115 GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
116
117 const Dart_Port destination_port_id = port.Id();
118 const bool same_group = InSameGroup(isolate, port);
119#if defined(DEBUG)
120 if (same_group) {
122 isolate->group()));
123 }
124#endif
125
126 // TODO(turnidge): Throw an exception when the return value is false?
127 PortMap::PostMessage(WriteMessage(same_group, obj, destination_port_id,
129 return Object::null();
130}
131
133 public:
134 static bool ReportStats() { return false; }
135 static const char* Name() { return "UntaggedObjectPtrSetTraits"; }
136
137 static bool IsMatch(const ObjectPtr a, const ObjectPtr b) { return a == b; }
138
139 static uword Hash(const ObjectPtr obj) { return static_cast<uword>(obj); }
140};
141
143 Isolate* isolate,
144 const Object& obj) {
145 TIMELINE_DURATION(Thread::Current(), Isolate, "ValidateMessageObject");
146
147 class SendMessageValidator : public ObjectPointerVisitor {
148 public:
149 SendMessageValidator(IsolateGroup* isolate_group,
150 WeakTable* visited,
151 MallocGrowableArray<ObjectPtr>* const working_set)
152 : ObjectPointerVisitor(isolate_group),
153 visited_(visited),
154 working_set_(working_set) {}
155
156 void VisitObject(ObjectPtr obj) {
157 if (!obj->IsHeapObject() || obj->untag()->IsCanonical()) {
158 return;
159 }
160 if (visited_->GetValueExclusive(obj) == 1) {
161 return;
162 }
163 visited_->SetValueExclusive(obj, 1);
164 working_set_->Add(obj);
165 }
166
167 private:
168 void VisitPointers(ObjectPtr* from, ObjectPtr* to) override {
169 for (ObjectPtr* ptr = from; ptr <= to; ptr++) {
170 VisitObject(*ptr);
171 }
172 }
173
174#if defined(DART_COMPRESSED_POINTERS)
175 void VisitCompressedPointers(uword heap_base,
177 CompressedObjectPtr* to) override {
178 for (CompressedObjectPtr* ptr = from; ptr <= to; ptr++) {
179 VisitObject(ptr->Decompress(heap_base));
180 }
181 }
182#endif
183
184 WeakTable* visited_;
185 MallocGrowableArray<ObjectPtr>* const working_set_;
186 };
187 if (!obj.ptr()->IsHeapObject() || obj.ptr()->untag()->IsCanonical()) {
188 return obj.ptr();
189 }
190 ClassTable* class_table = isolate->group()->class_table();
191
192 Class& klass = Class::Handle(zone);
193 Closure& closure = Closure::Handle(zone);
194 Array& array = Array::Handle(zone);
195 Object& illegal_object = Object::Handle(zone);
196 const char* exception_message = nullptr;
197 Thread* thread = Thread::Current();
198
199 // working_set contains only elements that have not been visited yet that
200 // need to be processed.
201 // So before adding elements to working_set ensure to check visited flag,
202 // set visited flag at the same time as the element is added.
203
204 // This working set of raw pointers is visited by GC, only one for a given
205 // isolate should be in use.
206 MallocGrowableArray<ObjectPtr>* const working_set =
208 ASSERT(working_set->length() == 0);
209 std::unique_ptr<WeakTable> visited(new WeakTable());
210
211 SendMessageValidator visitor(isolate->group(), visited.get(), working_set);
212
213 visited->SetValueExclusive(obj.ptr(), 1);
214 working_set->Add(obj.ptr());
215
216 while (!working_set->is_empty() && (exception_message == nullptr)) {
217 thread->CheckForSafepoint();
218
219 ObjectPtr raw = working_set->RemoveLast();
221 continue;
222 }
223 const intptr_t cid = raw->GetClassId();
224 switch (cid) {
225 case kArrayCid: {
226 array ^= Array::RawCast(raw);
227 visitor.VisitObject(array.GetTypeArguments());
228 const intptr_t batch_size = (2 << 14) - 1;
229 for (intptr_t i = 0; i < array.Length(); ++i) {
230 ObjectPtr ptr = array.At(i);
231 visitor.VisitObject(ptr);
232 if ((i & batch_size) == batch_size) {
233 thread->CheckForSafepoint();
234 }
235 }
236 continue;
237 }
238 case kClosureCid:
239 closure ^= raw;
240 // Only context has to be checked.
241 working_set->Add(closure.RawContext());
242 continue;
243
244#define MESSAGE_SNAPSHOT_ILLEGAL(type) \
245 case k##type##Cid: \
246 illegal_object = raw; \
247 exception_message = "is a " #type; \
248 break;
249
251 // TODO(http://dartbug.com/47777): Send and exit support: remove this.
259
260 default:
261 klass = class_table->At(cid);
262 if (klass.is_isolate_unsendable()) {
263 illegal_object = raw;
264 exception_message =
265 "is unsendable object (see restrictions listed at"
266 "`SendPort.send()` documentation for more information)";
267 break;
268 }
269 }
270 raw->untag()->VisitPointers(&visitor);
271 }
272
273 ASSERT((exception_message == nullptr) == illegal_object.IsNull());
274 if (exception_message != nullptr) {
275 working_set->Clear();
276
277 const Array& args = Array::Handle(zone, Array::New(3));
278 args.SetAt(0, illegal_object);
279 args.SetAt(2, String::Handle(
281 "%s%s",
283 zone, isolate, obj, illegal_object,
285 exception_message)));
286 const Object& exception = Object::Handle(
288 return UnhandledException::New(Instance::Cast(exception),
289 StackTrace::Handle(zone));
290 }
291
292 ASSERT(working_set->length() == 0);
293 isolate->set_forward_table_new(nullptr);
294 return obj.ptr();
295}
296
297// TODO(http://dartbug.com/47777): Add support for Finalizers.
298DEFINE_NATIVE_ENTRY(Isolate_exit_, 0, 2) {
299 GET_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
300 if (!port.IsNull()) {
301 GET_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
302
303 const bool same_group = InSameGroup(isolate, port);
304#if defined(DEBUG)
305 if (same_group) {
307 isolate->group()));
308 }
309#endif
310 if (!same_group) {
311 const auto& error =
312 String::Handle(String::New("exit with final message is only allowed "
313 "for isolates in one isolate group."));
315 UNREACHABLE();
316 }
317
318 Object& validated_result = Object::Handle(zone);
319 const Object& msg_obj = Object::Handle(zone, obj.ptr());
320 validated_result = ValidateMessageObject(zone, isolate, msg_obj);
321 // msg_array = [
322 // <message>,
323 // <collection-lib-objects-to-rehash>,
324 // <core-lib-objects-to-rehash>,
325 // ]
326 const Array& msg_array = Array::Handle(zone, Array::New(3));
327 msg_array.SetAt(0, msg_obj);
328 if (validated_result.IsUnhandledException()) {
329 Exceptions::PropagateError(Error::Cast(validated_result));
330 UNREACHABLE();
331 }
332 PersistentHandle* handle =
333 isolate->group()->api_state()->AllocatePersistentHandle();
334 handle->set_ptr(msg_array);
335 isolate->bequeath(std::unique_ptr<Bequest>(new Bequest(handle, port.Id())));
336 }
337
339 const String& msg =
340 String::Handle(String::New("isolate terminated by Isolate.exit"));
342 error.set_is_user_initiated(true);
344 UNREACHABLE();
345 // We will never execute dart code again in this isolate.
346 return Object::null();
347}
348
350 public:
353 const char* script_url,
355 SerializedObjectBuffer* message_buffer,
356 const char* package_config,
357 bool paused,
358 bool errorsAreFatal,
359 Dart_Port onExit,
360 Dart_Port onError,
361 const char* debug_name,
362 IsolateGroup* group);
364 const char* script_url,
365 const char* package_config,
366 SerializedObjectBuffer* args_buffer,
367 SerializedObjectBuffer* message_buffer,
368 bool paused,
369 bool errorsAreFatal,
370 Dart_Port onExit,
371 Dart_Port onError,
372 const char* debug_name,
373 IsolateGroup* group);
375
376 Isolate* isolate() const { return isolate_; }
377 void set_isolate(Isolate* value) { isolate_ = value; }
378
379 Dart_Port parent_port() const { return parent_port_; }
380 Dart_Port origin_id() const { return origin_id_; }
381 Dart_Port on_exit_port() const { return on_exit_port_; }
382 Dart_Port on_error_port() const { return on_error_port_; }
383 const char* script_url() const { return script_url_; }
384 const char* package_config() const { return package_config_; }
385 const char* debug_name() const { return debug_name_; }
386 bool is_spawn_uri() const {
387 return closure_tuple_handle_ == nullptr; // No closure entrypoint.
388 }
389 bool paused() const { return paused_; }
390 bool errors_are_fatal() const { return errors_are_fatal_; }
391 Dart_IsolateFlags* isolate_flags() { return &isolate_flags_; }
393 return closure_tuple_handle_;
394 }
395
397 ObjectPtr BuildArgs(Thread* thread);
399
400 IsolateGroup* isolate_group() const { return isolate_group_; }
401
402 private:
403 Isolate* isolate_ = nullptr;
404 Dart_Port parent_port_;
405 Dart_Port origin_id_ = ILLEGAL_PORT;
406 Dart_Port on_exit_port_;
407 Dart_Port on_error_port_;
408 const char* script_url_;
409 const char* package_config_;
410 const char* debug_name_;
411 PersistentHandle* closure_tuple_handle_ = nullptr;
412 IsolateGroup* isolate_group_;
413 std::unique_ptr<Message> serialized_args_;
414 std::unique_ptr<Message> serialized_message_;
415
416 Dart_IsolateFlags isolate_flags_;
417 bool paused_;
418 bool errors_are_fatal_;
419};
420
421static const char* NewConstChar(const char* chars) {
422 size_t len = strlen(chars);
423 char* mem = new char[len + 1];
424 memmove(mem, chars, len + 1);
425 return mem;
426}
427
429 Dart_Port origin_id,
430 const char* script_url,
431 PersistentHandle* closure_tuple_handle,
432 SerializedObjectBuffer* message_buffer,
433 const char* package_config,
434 bool paused,
435 bool errors_are_fatal,
436 Dart_Port on_exit_port,
437 Dart_Port on_error_port,
438 const char* debug_name,
439 IsolateGroup* isolate_group)
440 : parent_port_(parent_port),
441 origin_id_(origin_id),
442 on_exit_port_(on_exit_port),
443 on_error_port_(on_error_port),
444 script_url_(script_url),
445 package_config_(package_config),
446 debug_name_(debug_name),
447 closure_tuple_handle_(closure_tuple_handle),
448 isolate_group_(isolate_group),
449 serialized_args_(nullptr),
450 serialized_message_(message_buffer->StealMessage()),
451 paused_(paused),
452 errors_are_fatal_(errors_are_fatal) {
453 ASSERT(closure_tuple_handle_ != nullptr);
454
455 auto thread = Thread::Current();
456 auto isolate = thread->isolate();
457
458 // Inherit flags from spawning isolate.
460}
461
463 const char* script_url,
464 const char* package_config,
465 SerializedObjectBuffer* args_buffer,
466 SerializedObjectBuffer* message_buffer,
467 bool paused,
468 bool errors_are_fatal,
469 Dart_Port on_exit_port,
470 Dart_Port on_error_port,
471 const char* debug_name,
472 IsolateGroup* isolate_group)
473 : parent_port_(parent_port),
474 on_exit_port_(on_exit_port),
475 on_error_port_(on_error_port),
476 script_url_(script_url),
477 package_config_(package_config),
478 debug_name_(debug_name),
479 isolate_group_(isolate_group),
480 serialized_args_(args_buffer->StealMessage()),
481 serialized_message_(message_buffer->StealMessage()),
482 isolate_flags_(),
483 paused_(paused),
484 errors_are_fatal_(errors_are_fatal) {
485 if (debug_name_ == nullptr) {
486 debug_name_ = NewConstChar("main");
487 }
488
489 // By default inherit flags from spawning isolate. These can be overridden
490 // from the calling code.
492}
493
495 delete[] script_url_;
496 delete[] package_config_;
497 delete[] debug_name_;
498}
499
501 Thread* thread = Thread::Current();
502 auto IG = thread->isolate_group();
503 Zone* zone = thread->zone();
504
505 // Handle spawnUri lookup rules.
506 // Check whether the root library defines a main function.
507 const Library& lib =
508 Library::Handle(zone, IG->object_store()->root_library());
509 const String& main = String::Handle(zone, String::New("main"));
511 if (func.IsNull()) {
512 // Check whether main is reexported from the root library.
513 const Object& obj = Object::Handle(zone, lib.LookupReExport(main));
514 if (obj.IsFunction()) {
515 func ^= obj.ptr();
516 }
517 }
518 if (func.IsNull()) {
519 const String& msg = String::Handle(
520 zone,
522 "Unable to resolve function 'main' in script '%s'.", script_url()));
523 return LanguageError::New(msg);
524 }
525 return func.ptr();
526}
527
529 if (message == nullptr) {
530 return Object::null();
531 }
532 if (message->IsRaw()) {
533 return Object::RawCast(message->raw_obj());
534 } else {
535 return ReadMessage(thread, message);
536 }
537}
538
540 const Object& result =
541 Object::Handle(DeserializeMessage(thread, serialized_args_.get()));
542 serialized_args_.reset();
543 return result.ptr();
544}
545
547 const Object& result =
548 Object::Handle(DeserializeMessage(thread, serialized_message_.get()));
549 serialized_message_.reset();
550 return result.ptr();
551}
552
558
560 public:
561 SpawnIsolateTask(Isolate* parent_isolate,
562 std::unique_ptr<IsolateSpawnState> state)
563 : parent_isolate_(parent_isolate), state_(std::move(state)) {
564 parent_isolate->IncrementSpawnCount();
565 }
566
567 ~SpawnIsolateTask() override {
568 if (parent_isolate_ != nullptr) {
569 parent_isolate_->DecrementSpawnCount();
570 }
571 }
572
573 void Run() override {
574 const char* name = state_->debug_name();
575 ASSERT(name != nullptr);
576
577 auto group = state_->isolate_group();
578 if (group == nullptr) {
580 } else {
582 }
583 }
584
585 void RunHeavyweight(const char* name) {
586 // The create isolate group callback is mandatory. If not provided we
587 // cannot spawn isolates.
588 auto create_group_callback = Isolate::CreateGroupCallback();
589 if (create_group_callback == nullptr) {
590 FailedSpawn("Isolate spawn is not supported by this Dart embedder\n");
591 return;
592 }
593
594 char* error = nullptr;
595
596 // Make a copy of the state's isolate flags and hand it to the callback.
597 Dart_IsolateFlags api_flags = *(state_->isolate_flags());
598
599 // Inherit the system isolate property to work around issues with
600 // --pause-isolates-on-start and --pause-isolates-on-exit impacting macro
601 // generation isolates which are spawned by the kernel-service
602 // (see https://github.com/dart-lang/sdk/issues/54729 for details).
603 //
604 // This flag isn't inherited in the case that the main isolate is marked as
605 // a system isolate in the standalone VM using the
606 // --mark-main-isolate-as-system-isolate flag as it's currently used to
607 // hide test runner implementation details and spawns isolates that should
608 // be debuggable as non-system isolates.
609 //
610 // TODO(bkonyi): revisit this decision, see
611 // https://github.com/dart-lang/sdk/issues/54736 for the tracking issue.
612 const bool is_parent_main_isolate =
613 strcmp(parent_isolate_->name(), "main") == 0;
614 api_flags.is_system_isolate =
615 api_flags.is_system_isolate && !is_parent_main_isolate;
616 Dart_Isolate isolate =
617 (create_group_callback)(state_->script_url(), name, nullptr,
618 state_->package_config(), &api_flags,
619 parent_isolate_->init_callback_data(), &error);
620 parent_isolate_->DecrementSpawnCount();
621 parent_isolate_ = nullptr;
622
623 if (isolate == nullptr) {
624 FailedSpawn(error, /*has_current_isolate=*/false);
625 free(error);
626 return;
627 }
628 Dart_EnterIsolate(isolate);
629 Run(reinterpret_cast<Isolate*>(isolate));
630 }
631
632 void RunLightweight(const char* name) {
633 // The create isolate initialize callback is mandatory.
634 auto initialize_callback = Isolate::InitializeCallback();
635 if (initialize_callback == nullptr) {
636 FailedSpawn(
637 "Lightweight isolate spawn is not supported by this Dart embedder\n",
638 /*has_current_isolate=*/false);
639 return;
640 }
641
642 char* error = nullptr;
643
644 auto group = state_->isolate_group();
646 parent_isolate_->DecrementSpawnCount();
647 parent_isolate_ = nullptr;
648
649 if (isolate == nullptr) {
650 FailedSpawn(error, /*has_current_isolate=*/false);
651 free(error);
652 return;
653 }
654
655 void* child_isolate_data = nullptr;
656 const bool success = initialize_callback(&child_isolate_data, &error);
657 if (!success) {
658 FailedSpawn(error);
660 free(error);
661 return;
662 }
663
664 isolate->set_init_callback_data(child_isolate_data);
665 Run(isolate);
666 }
667
668 private:
669 void Run(Isolate* child) {
670 if (!EnsureIsRunnable(child)) {
672 return;
673 }
674
675 state_->set_isolate(child);
676 if (state_->origin_id() != ILLEGAL_PORT) {
677 // origin_id is set to parent isolate main port id when spawning via
678 // spawnFunction.
679 child->set_origin_id(state_->origin_id());
680 }
681
682 bool success = true;
683 {
684 auto thread = Thread::Current();
685 TransitionNativeToVM transition(thread);
686 StackZone zone(thread);
687 HandleScope hs(thread);
688
689 success = EnqueueEntrypointInvocationAndNotifySpawner(thread);
690 }
691
692 if (!success) {
693 state_ = nullptr;
695 return;
696 }
697
698 // All preconditions are met for this to always succeed.
699 char* error = nullptr;
700 if (!Dart_RunLoopAsync(state_->errors_are_fatal(), state_->on_error_port(),
701 state_->on_exit_port(), &error)) {
702 FATAL("Dart_RunLoopAsync() failed: %s. Please file a Dart VM bug report.",
703 error);
704 }
705 }
706
707 bool EnsureIsRunnable(Isolate* child) {
708 // We called out to the embedder to create/initialize a new isolate. The
709 // embedder callback successfully did so. It is now our responsibility to
710 // run the isolate.
711 // If the isolate was not marked as runnable, we'll do so here and run it.
712 if (!child->is_runnable()) {
713 const char* error = child->MakeRunnable();
714 if (error != nullptr) {
715 FailedSpawn(error);
716 return false;
717 }
718 }
719 ASSERT(child->is_runnable());
720 return true;
721 }
722
723 bool EnqueueEntrypointInvocationAndNotifySpawner(Thread* thread) {
724 auto isolate = thread->isolate();
725 auto zone = thread->zone();
726 const bool is_spawn_uri = state_->is_spawn_uri();
727
728 // Step 1) Resolve the entrypoint function.
729 auto& entrypoint_closure = Closure::Handle(zone);
730 if (state_->closure_tuple_handle() != nullptr) {
731 const auto& result = Object::Handle(
732 zone,
733 ReadObjectGraphCopyMessage(thread, state_->closure_tuple_handle()));
734 if (result.IsError()) {
735 ReportError(
736 "Failed to deserialize the passed entrypoint to the new isolate.");
737 return false;
738 }
739 entrypoint_closure = Closure::RawCast(result.ptr());
740 } else {
741 const auto& result = Object::Handle(zone, state_->ResolveFunction());
742 if (result.IsError()) {
743 ASSERT(is_spawn_uri);
744 ReportError("Failed to resolve entrypoint function.");
745 return false;
746 }
747 ASSERT(result.IsFunction());
748 auto& func = Function::Handle(zone, Function::Cast(result).ptr());
749 func = func.ImplicitClosureFunction();
750 entrypoint_closure = func.ImplicitStaticClosure();
751 }
752
753 // Step 2) Enqueue delayed invocation of entrypoint callback.
754 const auto& args_obj = Object::Handle(zone, state_->BuildArgs(thread));
755 if (args_obj.IsError()) {
756 ReportError(
757 "Failed to deserialize the passed arguments to the new isolate.");
758 return false;
759 }
760 ASSERT(args_obj.IsNull() || args_obj.IsInstance());
761 const auto& message_obj =
762 Object::Handle(zone, state_->BuildMessage(thread));
763 if (message_obj.IsError()) {
764 ReportError(
765 "Failed to deserialize the passed arguments to the new isolate.");
766 return false;
767 }
768 ASSERT(message_obj.IsNull() || message_obj.IsInstance());
769 const Array& args = Array::Handle(zone, Array::New(4));
770 args.SetAt(0, entrypoint_closure);
771 args.SetAt(1, args_obj);
772 args.SetAt(2, message_obj);
773 args.SetAt(3, is_spawn_uri ? Bool::True() : Bool::False());
774
775 const auto& lib = Library::Handle(zone, Library::IsolateLibrary());
776 const auto& entry_name = String::Handle(zone, String::New("_startIsolate"));
777 const auto& entry_point =
778 Function::Handle(zone, lib.LookupFunctionAllowPrivate(entry_name));
779 ASSERT(entry_point.IsFunction() && !entry_point.IsNull());
780 const auto& result =
781 Object::Handle(zone, DartEntry::InvokeFunction(entry_point, args));
782 if (result.IsError()) {
783 ReportError("Failed to enqueue delayed entrypoint invocation.");
784 return false;
785 }
786
787 // Step 3) Pause the isolate if required & Notify parent isolate about
788 // isolate creation.
789 const auto& capabilities = Array::Handle(zone, Array::New(2));
790 auto& capability = Capability::Handle(zone);
791 capability = Capability::New(isolate->pause_capability());
792 capabilities.SetAt(0, capability);
793 capability = Capability::New(isolate->terminate_capability());
794 capabilities.SetAt(1, capability);
795 const auto& send_port =
796 SendPort::Handle(zone, SendPort::New(isolate->main_port()));
797 const auto& message = Array::Handle(zone, Array::New(2));
798 message.SetAt(0, send_port);
799 message.SetAt(1, capabilities);
800 if (state_->paused()) {
801 capability ^= capabilities.At(0);
802 const bool added = isolate->AddResumeCapability(capability);
803 ASSERT(added);
804 isolate->message_handler()->increment_paused();
805 }
806 {
807 // If parent isolate died, we ignore the fact that we cannot notify it.
808 PortMap::PostMessage(WriteMessage(/*same_group=*/false, message,
809 state_->parent_port(),
811 }
812
813 return true;
814 }
815
816 void FailedSpawn(const char* error, bool has_current_isolate = true) {
817 ReportError(error != nullptr
818 ? error
819 : "Unknown error occurred during Isolate spawning.");
820 // Destruction of [IsolateSpawnState] may cause destruction of [Message]
821 // which make need to delete persistent handles (which requires a current
822 // isolate group).
823 if (has_current_isolate) {
824 ASSERT(IsolateGroup::Current() == state_->isolate_group());
825 state_ = nullptr;
826 } else if (state_->isolate_group() != nullptr) {
827 ASSERT(IsolateGroup::Current() == nullptr);
828 const bool kBypassSafepoint = false;
830 state_->isolate_group(), Thread::kUnknownTask, kBypassSafepoint);
831 ASSERT(result);
832 state_ = nullptr;
833 Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
834 } else {
835 // The state won't need a current isolate group, because it belongs to a
836 // [Isolate.spawnUri] call.
837 state_ = nullptr;
838 }
839 }
840
841 void ReportError(const char* error) {
842 Dart_CObject error_cobj;
843 error_cobj.type = Dart_CObject_kString;
844 error_cobj.value.as_string = const_cast<char*>(error);
845 if (!Dart_PostCObject(state_->parent_port(), &error_cobj)) {
846 // Perhaps the parent isolate died or closed the port before we
847 // could report the error. Ignore.
848 }
849 }
850
851 Isolate* parent_isolate_;
852 std::unique_ptr<IsolateSpawnState> state_;
853
854 DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask);
855};
856
857static const char* String2UTF8(const String& str) {
858 intptr_t len = Utf8::Length(str);
859 char* result = new char[len + 1];
860 str.ToUTF8(reinterpret_cast<uint8_t*>(result), len);
861 result[len] = 0;
862
863 return result;
864}
865
866DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 10) {
867 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
868 GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1));
869 GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(2));
870 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
871 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
872 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(5));
873 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(6));
874 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(7));
875 GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(8));
876 GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(9));
877
878 PersistentHandle* closure_tuple_handle = nullptr;
879 // We have a non-toplevel closure that we might need to copy.
880 // Result will be [<closure-copy>, <objects-in-msg-to-rehash>]
881 const auto& closure_copy_tuple = Object::Handle(
882 zone, CopyMutableObjectGraph(closure)); // Throws if it fails.
883 ASSERT(closure_copy_tuple.IsArray());
884 ASSERT(
885 Object::Handle(zone, Array::Cast(closure_copy_tuple).At(0)).IsClosure());
886 closure_tuple_handle =
887 isolate->group()->api_state()->AllocatePersistentHandle();
888 closure_tuple_handle->set_ptr(closure_copy_tuple.ptr());
889
890 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
891 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
892 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id();
893
894 // We first try to serialize the message. In case the message is not
895 // serializable this will throw an exception.
896 SerializedObjectBuffer message_buffer;
897 message_buffer.set_message(WriteMessage(
898 /*same_group=*/true, message, ILLEGAL_PORT, Message::kNormalPriority));
899
900 const char* utf8_package_config =
901 packageConfig.IsNull() ? nullptr : String2UTF8(packageConfig);
902 const char* utf8_debug_name =
903 debugName.IsNull() ? nullptr : String2UTF8(debugName);
904 if (closure_tuple_handle != nullptr && utf8_debug_name == nullptr) {
905 const auto& closure_function = Function::Handle(zone, closure.function());
906 utf8_debug_name =
907 NewConstChar(closure_function.QualifiedUserVisibleNameCString());
908 }
909
910 std::unique_ptr<IsolateSpawnState> state(new IsolateSpawnState(
911 port.Id(), isolate->origin_id(), String2UTF8(script_uri),
912 closure_tuple_handle, &message_buffer, utf8_package_config,
913 paused.value(), fatal_errors, on_exit_port, on_error_port,
914 utf8_debug_name, isolate->group()));
915
916 isolate->group()->thread_pool()->Run<SpawnIsolateTask>(isolate,
917 std::move(state));
918 return Object::null();
919}
920
921static const char* CanonicalizeUri(Thread* thread,
922 const Library& library,
923 const String& uri,
924 char** error) {
925 const char* result = nullptr;
926 Zone* zone = thread->zone();
927 auto isolate_group = thread->isolate_group();
928 if (isolate_group->HasTagHandler()) {
929 const Object& obj = Object::Handle(
930 isolate_group->CallTagHandler(Dart_kCanonicalizeUrl, library, uri));
931 if (obj.IsString()) {
932 result = String2UTF8(String::Cast(obj));
933 } else if (obj.IsError()) {
934 Error& error_obj = Error::Handle();
935 error_obj ^= obj.ptr();
936 *error = zone->PrintToString("Unable to canonicalize uri '%s': %s",
937 uri.ToCString(), error_obj.ToErrorCString());
938 } else {
939 *error = zone->PrintToString(
940 "Unable to canonicalize uri '%s': "
941 "library tag handler returned wrong type",
942 uri.ToCString());
943 }
944 } else {
945 *error = zone->PrintToString(
946 "Unable to canonicalize uri '%s': no library tag handler found.",
947 uri.ToCString());
948 }
949 return result;
950}
951
952DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 12) {
953 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
954 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1));
955 GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2));
956 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
957 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
958 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5));
959 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6));
960 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7));
961 GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8));
962 GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9));
963 GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(10));
964 GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(11));
965
966 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
967 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
968 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id();
969
970 // We first try to serialize the arguments and the message. In case the
971 // arguments or the message are not serializable this will throw an exception.
972 SerializedObjectBuffer arguments_buffer;
973 SerializedObjectBuffer message_buffer;
974 {
975 arguments_buffer.set_message(WriteMessage(
976 /*same_group=*/false, args, ILLEGAL_PORT, Message::kNormalPriority));
977 }
978 {
979 message_buffer.set_message(WriteMessage(
980 /*same_group=*/false, message, ILLEGAL_PORT, Message::kNormalPriority));
981 }
982
983 // Canonicalize the uri with respect to the current isolate.
984 const Library& root_lib =
985 Library::Handle(isolate->group()->object_store()->root_library());
986 char* error = nullptr;
987 const char* canonical_uri = CanonicalizeUri(thread, root_lib, uri, &error);
988 if (canonical_uri == nullptr) {
989 const String& msg = String::Handle(String::New(error));
991 }
992
993 const char* utf8_package_config =
994 packageConfig.IsNull() ? nullptr : String2UTF8(packageConfig);
995 const char* utf8_debug_name =
996 debugName.IsNull() ? nullptr : String2UTF8(debugName);
997
998 std::unique_ptr<IsolateSpawnState> state(new IsolateSpawnState(
999 port.Id(), canonical_uri, utf8_package_config, &arguments_buffer,
1000 &message_buffer, paused.value(), fatal_errors, on_exit_port,
1001 on_error_port, utf8_debug_name, /*group=*/nullptr));
1002
1003 // If we were passed a value then override the default flags state for
1004 // checked mode.
1005 if (!checked.IsNull()) {
1006 Dart_IsolateFlags* flags = state->isolate_flags();
1007 flags->enable_asserts = checked.value();
1008 }
1009
1010 isolate->group()->thread_pool()->Run<SpawnIsolateTask>(isolate,
1011 std::move(state));
1012 return Object::null();
1013}
1014
1015DEFINE_NATIVE_ENTRY(Isolate_getDebugName, 0, 1) {
1016 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
1017 auto name = Isolate::LookupIsolateNameByPort(port.Id());
1018 if (name == nullptr) {
1019 return String::null();
1020 }
1021 return String::New(name.get());
1022}
1023
1024DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0, 0) {
1025 const Array& result = Array::Handle(Array::New(3));
1026 result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port())));
1027 result.SetAt(
1028 1, Capability::Handle(Capability::New(isolate->pause_capability())));
1029 result.SetAt(
1030 2, Capability::Handle(Capability::New(isolate->terminate_capability())));
1031 return result.ptr();
1032}
1033
1034DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0, 0) {
1035 const Library& root_lib =
1036 Library::Handle(zone, isolate->group()->object_store()->root_library());
1037 return root_lib.url();
1038}
1039
1040DEFINE_NATIVE_ENTRY(Isolate_registerKernelBlob, 0, 1) {
1042 arguments->NativeArgAt(0));
1043 auto register_kernel_blob_callback = Isolate::RegisterKernelBlobCallback();
1044 if (register_kernel_blob_callback == nullptr) {
1046 "Registration of kernel blobs is not supported by this Dart embedder.");
1047 }
1048 bool is_kernel = false;
1049 {
1050 NoSafepointScope no_safepoint;
1051 is_kernel =
1052 Dart_IsKernel(reinterpret_cast<uint8_t*>(kernel_blob.DataAddr(0)),
1053 kernel_blob.LengthInBytes());
1054 }
1055 if (!is_kernel) {
1056 const auto& error = String::Handle(
1057 zone, String::New("kernelBlob doesn\'t contain a valid kernel.\n"));
1059 UNREACHABLE();
1060 }
1061 const char* uri = nullptr;
1062 {
1063 NoSafepointScope no_safepoint;
1064 uri = register_kernel_blob_callback(
1065 reinterpret_cast<uint8_t*>(kernel_blob.DataAddr(0)),
1066 kernel_blob.LengthInBytes());
1067 }
1068 if (uri == nullptr) {
1070 }
1071 return String::New(uri);
1072}
1073
1074DEFINE_NATIVE_ENTRY(Isolate_unregisterKernelBlob, 0, 1) {
1075 GET_NON_NULL_NATIVE_ARGUMENT(String, kernel_blob_uri,
1076 arguments->NativeArgAt(0));
1077 auto unregister_kernel_blob_callback =
1079 if (unregister_kernel_blob_callback == nullptr) {
1081 "Registration of kernel blobs is not supported by this Dart embedder.");
1082 }
1083 unregister_kernel_blob_callback(kernel_blob_uri.ToCString());
1084 return Object::null();
1085}
1086
1087DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 0, 2) {
1088 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
1089 GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1));
1090
1091 // Make sure to route this request to the isolate library OOB message handler.
1093
1094 // Ensure message writer (and it's resources, e.g. forwarding tables) are
1095 // cleaned up before handling interrupts.
1096 {
1097 PortMap::PostMessage(WriteMessage(/*same_group=*/false, msg, port.Id(),
1099 }
1100
1101 // Drain interrupts before running so any IMMEDIATE operations on the current
1102 // isolate happen synchronously.
1103 const Error& error = Error::Handle(thread->HandleInterrupts());
1104 if (!error.IsNull()) {
1106 UNREACHABLE();
1107 }
1108
1109 return Object::null();
1110}
1111
1112static void ExternalTypedDataFinalizer(void* isolate_callback_data,
1113 void* peer) {
1114 free(peer);
1115}
1116
1118 // From the Dart side we are guaranteed that the type of [instance] is a
1119 // subtype of TypedData.
1120 if (instance.IsTypedDataBase()) {
1121 return TypedDataBase::Cast(instance).LengthInBytes();
1122 }
1123
1124 // This can happen if [instance] is `null` or an instance of a 3rd party class
1125 // which implements [TypedData].
1127}
1128
1129DEFINE_NATIVE_ENTRY(TransferableTypedData_factory, 0, 2) {
1130 ASSERT(
1131 TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
1132
1133 GET_NON_NULL_NATIVE_ARGUMENT(Instance, array_instance,
1134 arguments->NativeArgAt(1));
1135
1136 Array& array = Array::Handle();
1137 intptr_t array_length;
1138 if (array_instance.IsGrowableObjectArray()) {
1139 const auto& growable_array = GrowableObjectArray::Cast(array_instance);
1140 array ^= growable_array.data();
1141 array_length = growable_array.Length();
1142 } else if (array_instance.IsArray()) {
1143 array ^= Array::Cast(array_instance).ptr();
1144 array_length = array.Length();
1145 } else {
1146 Exceptions::ThrowArgumentError(array_instance);
1147 UNREACHABLE();
1148 }
1150 uint64_t total_bytes = 0;
1151 const uint64_t kMaxBytes = TypedData::MaxElements(kTypedDataUint8ArrayCid);
1152 for (intptr_t i = 0; i < array_length; i++) {
1153 instance ^= array.At(i);
1154 total_bytes += static_cast<uintptr_t>(GetTypedDataSizeOrThrow(instance));
1155 if (total_bytes > kMaxBytes) {
1156 const Array& error_args = Array::Handle(Array::New(3));
1157 error_args.SetAt(0, array);
1158 error_args.SetAt(1, String::Handle(String::New("data")));
1159 error_args.SetAt(
1161 "Aggregated list exceeds max size %" Pu64 "", kMaxBytes)));
1163 UNREACHABLE();
1164 }
1165 }
1166
1167 uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(total_bytes));
1168 if (data == nullptr) {
1169 const Instance& exception = Instance::Handle(
1170 thread->isolate_group()->object_store()->out_of_memory());
1171 Exceptions::Throw(thread, exception);
1172 UNREACHABLE();
1173 }
1174 intptr_t offset = 0;
1175 for (intptr_t i = 0; i < array_length; i++) {
1176 instance ^= array.At(i);
1177
1178 {
1179 NoSafepointScope no_safepoint;
1180 const auto& typed_data = TypedDataBase::Cast(instance);
1181 const intptr_t length_in_bytes = typed_data.LengthInBytes();
1182
1183 void* source = typed_data.DataAddr(0);
1184 // The memory does not overlap.
1185 memcpy(data + offset, source, length_in_bytes); // NOLINT
1186 offset += length_in_bytes;
1187 }
1188 }
1189 ASSERT(static_cast<uintptr_t>(offset) == total_bytes);
1190 return TransferableTypedData::New(data, total_bytes);
1191}
1192
1193DEFINE_NATIVE_ENTRY(TransferableTypedData_materialize, 0, 1) {
1195 arguments->NativeArgAt(0));
1196
1197 void* peer;
1198 {
1199 NoSafepointScope no_safepoint;
1200 peer = thread->heap()->GetPeer(t.ptr());
1201 // Assume that object's Peer is only used to track transferability state.
1202 ASSERT(peer != nullptr);
1203 }
1204
1206 reinterpret_cast<TransferableTypedDataPeer*>(peer);
1207 const intptr_t length = tpeer->length();
1208 uint8_t* data = tpeer->data();
1209 if (data == nullptr) {
1210 const auto& error = String::Handle(String::New(
1211 "Attempt to materialize object that was transferred already."));
1213 UNREACHABLE();
1214 }
1216 tpeer->ClearData();
1217
1218 const ExternalTypedData& typed_data = ExternalTypedData::Handle(
1219 ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, length,
1220 thread->heap()->SpaceForExternal(length)));
1221 FinalizablePersistentHandle* finalizable_ref =
1222 FinalizablePersistentHandle::New(thread->isolate_group(), typed_data,
1223 /* peer= */ data,
1225 /*auto_delete=*/true);
1226 ASSERT(finalizable_ref != nullptr);
1227 return typed_data.ptr();
1228}
1229
1230} // namespace dart
static uint32_t hash(const SkShaderBase::GradientInfo &v)
#define IG
#define UNREACHABLE()
Definition assert.h:248
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition object.h:10933
virtual TypeArgumentsPtr GetTypeArguments() const
Definition object.h:10879
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
void Add(const T &value)
intptr_t length() const
static const Bool & False()
Definition object.h:10778
static const Bool & Get(bool value)
Definition object.h:10780
static const Bool & True()
Definition object.h:10776
static CapabilityPtr New(uint64_t id, Heap::Space space=Heap::kNew)
Definition object.cc:25852
ClassPtr At(intptr_t cid) const
bool is_isolate_unsendable() const
Definition object.h:2153
static ObjectPtr InvokeFunction(const Function &function, const Array &arguments)
Definition dart_entry.cc:31
virtual const char * ToErrorCString() const
Definition object.cc:19830
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
static DART_NORETURN void ThrowOOM()
static DART_NORETURN void ThrowUnsupportedError(const char *msg)
static DART_NORETURN void Throw(Thread *thread, const Instance &exception)
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
static ObjectPtr Create(ExceptionType type, const Array &arguments)
static DART_NORETURN void PropagateError(const Error &error)
static ExternalTypedDataPtr New(intptr_t class_id, uint8_t *data, intptr_t len, Heap::Space space=Heap::kNew, bool perform_eager_msan_initialization_check=true)
Definition object.cc:25705
static FinalizablePersistentHandle * New(IsolateGroup *isolate_group, const Object &object, void *peer, Dart_HandleFinalizer callback, intptr_t external_size, bool auto_delete)
void EnsureFreedExternal(IsolateGroup *isolate_group)
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
Definition object.cc:23063
static IsolateGroup * Current()
Definition isolate.h:534
ClassTable * class_table() const
Definition isolate.h:491
const char * script_url() const
Definition isolate.cc:383
bool paused() const
Definition isolate.cc:389
Dart_Port parent_port() const
Definition isolate.cc:379
void set_isolate(Isolate *value)
Definition isolate.cc:377
const char * debug_name() const
Definition isolate.cc:385
PersistentHandle * closure_tuple_handle() const
Definition isolate.cc:392
Dart_Port on_error_port() const
Definition isolate.cc:382
const char * package_config() const
Definition isolate.cc:384
bool is_spawn_uri() const
Definition isolate.cc:386
ObjectPtr ResolveFunction()
Definition isolate.cc:500
IsolateSpawnState(Dart_Port parent_port, Dart_Port origin_id, const char *script_url, PersistentHandle *closure_tuple_handle, SerializedObjectBuffer *message_buffer, const char *package_config, bool paused, bool errorsAreFatal, Dart_Port onExit, Dart_Port onError, const char *debug_name, IsolateGroup *group)
Definition isolate.cc:428
IsolateGroup * isolate_group() const
Definition isolate.cc:400
ObjectPtr BuildArgs(Thread *thread)
Definition isolate.cc:539
Dart_IsolateFlags * isolate_flags()
Definition isolate.cc:391
Dart_Port origin_id() const
Definition isolate.cc:380
ObjectPtr BuildMessage(Thread *thread)
Definition isolate.cc:546
bool errors_are_fatal() const
Definition isolate.cc:390
Isolate * isolate() const
Definition isolate.cc:376
Dart_Port on_exit_port() const
Definition isolate.cc:381
static Isolate * Current()
Definition isolate.h:939
void FlagsCopyTo(Dart_IsolateFlags *api_flags) const
Definition isolate.cc:1625
MallocGrowableArray< ObjectPtr > * pointers_to_verify_at_exit()
Definition isolate.h:1432
void DecrementSpawnCount()
Definition isolate.cc:3670
static std::unique_ptr< char[]> LookupIsolateNameByPort(Dart_Port port)
Definition isolate.cc:3515
void * init_callback_data() const
Definition isolate.h:1021
void set_forward_table_new(WeakTable *table)
Definition isolate.cc:2512
IsolateGroup * group() const
Definition isolate.h:990
static Dart_IsolateGroupCreateCallback CreateGroupCallback()
Definition isolate.h:1156
void set_init_callback_data(void *value)
Definition isolate.h:1020
static Dart_UnregisterKernelBlobCallback UnregisterKernelBlobCallback()
Definition isolate.h:1198
static Dart_InitializeIsolateCallback InitializeCallback()
Definition isolate.h:1163
Dart_Port origin_id()
Definition isolate.cc:1954
void IncrementSpawnCount()
Definition isolate.cc:3665
void set_origin_id(Dart_Port id)
Definition isolate.cc:1959
static Dart_RegisterKernelBlobCallback RegisterKernelBlobCallback()
Definition isolate.h:1191
const char * name() const
Definition isolate.h:996
ObjectPtr LookupReExport(const String &name, ZoneGrowableArray< intptr_t > *visited=nullptr) const
Definition object.cc:13902
static LibraryPtr IsolateLibrary()
Definition object.cc:14854
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition object.cc:14131
StringPtr url() const
Definition object.h:5068
@ kIsolateLibOOBMsg
Definition message.h:42
@ kNormalPriority
Definition message.h:28
UntaggedObject * untag() const
intptr_t GetClassId() const
Definition raw_object.h:864
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
void set_ptr(ObjectPtr ref)
static bool PostMessage(std::unique_ptr< Message > message, bool before_events=false)
Definition port.cc:152
static bool IsReceiverInThisIsolateGroupOrClosed(Dart_Port receiver, IsolateGroup *group)
Definition port.cc:228
static SendPortPtr New(Dart_Port id, Heap::Space space=Heap::kNew)
Definition object.cc:25891
Dart_Port origin_id() const
Definition object.h:12466
void set_message(std::unique_ptr< Message > message)
Definition snapshot.h:122
static SmiPtr New(intptr_t value)
Definition object.h:9985
SpawnIsolateTask(Isolate *parent_isolate, std::unique_ptr< IsolateSpawnState > state)
Definition isolate.cc:561
~SpawnIsolateTask() override
Definition isolate.cc:567
void Run() override
Definition isolate.cc:573
void RunLightweight(const char *name)
Definition isolate.cc:632
void RunHeavyweight(const char *name)
Definition isolate.cc:585
static StringPtr NewFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition object.cc:24083
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
void ToUTF8(uint8_t *utf8_array, intptr_t array_len) const
Definition object.cc:24225
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition object.cc:24205
Zone * zone() const
void StartUnwindError()
Definition thread.h:640
static Thread * Current()
Definition thread.h:361
void CheckForSafepoint()
Definition thread.h:1091
static void ExitIsolateGroupAsHelper(bool bypass_safepoint)
Definition thread.cc:494
IsolateGroup * isolate_group() const
Definition thread.h:540
static bool EnterIsolateGroupAsHelper(IsolateGroup *isolate_group, TaskKind kind, bool bypass_safepoint)
Definition thread.cc:476
FinalizablePersistentHandle * handle() const
Definition object.h:12497
static TransferableTypedDataPtr New(uint8_t *data, intptr_t len)
Definition object.cc:25914
static intptr_t MaxElements(intptr_t class_id)
Definition object.h:11658
static UnhandledExceptionPtr New(const Instance &exception, const Instance &stacktrace, Heap::Space space=Heap::kNew)
Definition object.cc:19989
static bool IsMatch(const ObjectPtr a, const ObjectPtr b)
Definition isolate.cc:137
static const char * Name()
Definition isolate.cc:135
static uword Hash(const ObjectPtr obj)
Definition isolate.cc:139
intptr_t VisitPointers(ObjectPointerVisitor *visitor)
Definition raw_object.h:426
bool IsCanonical() const
Definition raw_object.h:329
static UnwindErrorPtr New(const String &message, Heap::Space space=Heap::kNew)
Definition object.cc:20055
static intptr_t Length(int32_t ch)
Definition unicode.cc:98
char * PrintToString(const char *format,...) PRINTF_ATTRIBUTE(2
Definition zone.cc:313
#define ILLEGAL_PORT
Definition dart_api.h:1530
int64_t Dart_Port
Definition dart_api.h:1524
struct _Dart_Isolate * Dart_Isolate
Definition dart_api.h:88
@ Dart_kCanonicalizeUrl
Definition dart_api.h:3340
@ Dart_CObject_kString
#define ASSERT(E)
VkInstance instance
Definition main.cc:48
SkBitmap source
Definition examples.cpp:28
static bool b
struct MyStruct a[10]
#define FATAL(error)
AtkStateType state
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
size_t length
Win32Message message
#define MESSAGE_SNAPSHOT_ILLEGAL(type)
static ObjectPtr ValidateMessageObject(Zone *zone, Isolate *isolate, const Object &obj)
Definition isolate.cc:142
@ kInternalToIsolateGroup
ObjectPtr ReadMessage(Thread *thread, Message *message)
const char *const name
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
const intptr_t kSmiMax
Definition globals.h:28
bool CanShareObjectAcrossIsolates(ObjectPtr obj)
static const char * NewConstChar(const char *chars)
Definition isolate.cc:421
DART_EXPORT bool Dart_IsKernel(const uint8_t *buffer, intptr_t buffer_size)
ObjectPtr ReadObjectGraphCopyMessage(Thread *thread, PersistentHandle *handle)
const char * FindRetainingPath(Zone *zone_, Isolate *isolate, const Object &from, const Object &to, TraversalRules traversal_rules)
static bool InSameGroup(Isolate *sender, const SendPort &receiver)
Definition isolate.cc:105
void * malloc(size_t size)
Definition allocation.cc:19
static ObjectPtr DeserializeMessage(Thread *thread, Message *message)
Definition isolate.cc:528
ObjectPtr CopyMutableObjectGraph(const Object &object)
static void ThrowIsolateSpawnException(const String &message)
Definition isolate.cc:553
uintptr_t uword
Definition globals.h:501
static const char * String2UTF8(const String &str)
Definition isolate.cc:857
DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal, Dart_Port on_error_port, Dart_Port on_exit_port, char **error)
const intptr_t cid
std::unique_ptr< Message > WriteMessage(bool same_group, const Object &obj, Dart_Port dest_port, Message::Priority priority)
static const char * CanonicalizeUri(Thread *thread, const Library &library, const String &uri, char **error)
Definition isolate.cc:921
DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject *message)
Isolate * CreateWithinExistingIsolateGroup(IsolateGroup *group, const char *name, char **error)
static int8_t data[kExtLength]
DART_EXPORT void Dart_ShutdownIsolate()
static void ExternalTypedDataFinalizer(void *isolate_callback_data, void *peer)
Definition isolate.cc:1112
static intptr_t GetTypedDataSizeOrThrow(const Instance &instance)
Definition isolate.cc:1117
Definition main.py:1
Definition ref_ptr.h:256
#define DEFINE_NATIVE_ENTRY(name, type_argument_count, argument_count)
#define GET_NATIVE_ARGUMENT(type, name, value)
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
#define Pu64
Definition globals.h:417
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
Point offset
union _Dart_CObject::@86 value
Dart_CObject_Type type
const char * as_string
const uintptr_t id
#define TIMELINE_DURATION(thread, stream, name)
Definition timeline.h:39