Flutter Engine
The Flutter Engine
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);
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 for (intptr_t i = 0; i < array.Length(); ++i) {
229 ObjectPtr ptr = array.At(i);
230 visitor.VisitObject(ptr);
231 if (((i + 1) % kSlotsPerInterruptCheck) == 0) {
232 thread->CheckForSafepoint();
233 }
234 }
235 continue;
236 }
237 case kClosureCid:
238 closure ^= raw;
239 // Only context has to be checked.
240 working_set->Add(closure.RawContext());
241 continue;
242
243#define MESSAGE_SNAPSHOT_ILLEGAL(type) \
244 case k##type##Cid: \
245 illegal_object = raw; \
246 exception_message = "is a " #type; \
247 break;
248
250 // TODO(http://dartbug.com/47777): Send and exit support: remove this.
258
259 default:
260 klass = class_table->At(cid);
261 if (klass.is_isolate_unsendable()) {
262 illegal_object = raw;
263 exception_message =
264 "is unsendable object (see restrictions listed at"
265 "`SendPort.send()` documentation for more information)";
266 break;
267 }
268 }
269 raw->untag()->VisitPointers(&visitor);
270 }
271
272 ASSERT((exception_message == nullptr) == illegal_object.IsNull());
273 if (exception_message != nullptr) {
274 working_set->Clear();
275
276 const Array& args = Array::Handle(zone, Array::New(3));
277 args.SetAt(0, illegal_object);
278 args.SetAt(2, String::Handle(
280 "%s%s",
282 zone, isolate, obj, illegal_object,
284 exception_message)));
285 const Object& exception = Object::Handle(
287 return UnhandledException::New(Instance::Cast(exception),
288 StackTrace::Handle(zone));
289 }
290
291 ASSERT(working_set->length() == 0);
292 isolate->set_forward_table_new(nullptr);
293 return obj.ptr();
294}
295
296// TODO(http://dartbug.com/47777): Add support for Finalizers.
297DEFINE_NATIVE_ENTRY(Isolate_exit_, 0, 2) {
298 GET_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
299 if (!port.IsNull()) {
300 GET_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
301
302 const bool same_group = InSameGroup(isolate, port);
303#if defined(DEBUG)
304 if (same_group) {
306 isolate->group()));
307 }
308#endif
309 if (!same_group) {
310 const auto& error =
311 String::Handle(String::New("exit with final message is only allowed "
312 "for isolates in one isolate group."));
314 UNREACHABLE();
315 }
316
317 Object& validated_result = Object::Handle(zone);
318 const Object& msg_obj = Object::Handle(zone, obj.ptr());
319 validated_result = ValidateMessageObject(zone, isolate, msg_obj);
320 // msg_array = [
321 // <message>,
322 // <collection-lib-objects-to-rehash>,
323 // <core-lib-objects-to-rehash>,
324 // ]
325 const Array& msg_array = Array::Handle(zone, Array::New(3));
326 msg_array.SetAt(0, msg_obj);
327 if (validated_result.IsUnhandledException()) {
328 Exceptions::PropagateError(Error::Cast(validated_result));
329 UNREACHABLE();
330 }
331 PersistentHandle* handle =
332 isolate->group()->api_state()->AllocatePersistentHandle();
333 handle->set_ptr(msg_array);
334 isolate->bequeath(std::unique_ptr<Bequest>(new Bequest(handle, port.Id())));
335 }
336
338 const String& msg =
339 String::Handle(String::New("isolate terminated by Isolate.exit"));
341 error.set_is_user_initiated(true);
343 UNREACHABLE();
344 // We will never execute dart code again in this isolate.
345 return Object::null();
346}
347
349 public:
352 const char* script_url,
354 SerializedObjectBuffer* message_buffer,
355 const char* package_config,
356 bool paused,
357 bool errorsAreFatal,
358 Dart_Port onExit,
359 Dart_Port onError,
360 const char* debug_name,
363 const char* script_url,
364 const char* package_config,
365 SerializedObjectBuffer* args_buffer,
366 SerializedObjectBuffer* message_buffer,
367 bool paused,
368 bool errorsAreFatal,
369 Dart_Port onExit,
370 Dart_Port onError,
371 const char* debug_name,
374
375 Isolate* isolate() const { return isolate_; }
376 void set_isolate(Isolate* value) { isolate_ = value; }
377
378 Dart_Port parent_port() const { return parent_port_; }
379 Dart_Port origin_id() const { return origin_id_; }
380 Dart_Port on_exit_port() const { return on_exit_port_; }
381 Dart_Port on_error_port() const { return on_error_port_; }
382 const char* script_url() const { return script_url_; }
383 const char* package_config() const { return package_config_; }
384 const char* debug_name() const { return debug_name_; }
385 bool is_spawn_uri() const {
386 return closure_tuple_handle_ == nullptr; // No closure entrypoint.
387 }
388 bool paused() const { return paused_; }
389 bool errors_are_fatal() const { return errors_are_fatal_; }
390 Dart_IsolateFlags* isolate_flags() { return &isolate_flags_; }
392 return closure_tuple_handle_;
393 }
394
396 ObjectPtr BuildArgs(Thread* thread);
398
399 IsolateGroup* isolate_group() const { return isolate_group_; }
400
401 private:
402 Isolate* isolate_ = nullptr;
403 Dart_Port parent_port_;
404 Dart_Port origin_id_ = ILLEGAL_PORT;
405 Dart_Port on_exit_port_;
406 Dart_Port on_error_port_;
407 const char* script_url_;
408 const char* package_config_;
409 const char* debug_name_;
410 PersistentHandle* closure_tuple_handle_ = nullptr;
411 IsolateGroup* isolate_group_;
412 std::unique_ptr<Message> serialized_args_;
413 std::unique_ptr<Message> serialized_message_;
414
415 Dart_IsolateFlags isolate_flags_;
416 bool paused_;
417 bool errors_are_fatal_;
418};
419
420static const char* NewConstChar(const char* chars) {
421 size_t len = strlen(chars);
422 char* mem = new char[len + 1];
423 memmove(mem, chars, len + 1);
424 return mem;
425}
426
428 Dart_Port origin_id,
429 const char* script_url,
430 PersistentHandle* closure_tuple_handle,
431 SerializedObjectBuffer* message_buffer,
432 const char* package_config,
433 bool paused,
434 bool errors_are_fatal,
435 Dart_Port on_exit_port,
436 Dart_Port on_error_port,
437 const char* debug_name,
438 IsolateGroup* isolate_group)
439 : parent_port_(parent_port),
440 origin_id_(origin_id),
441 on_exit_port_(on_exit_port),
442 on_error_port_(on_error_port),
443 script_url_(script_url),
444 package_config_(package_config),
445 debug_name_(debug_name),
446 closure_tuple_handle_(closure_tuple_handle),
447 isolate_group_(isolate_group),
448 serialized_args_(nullptr),
449 serialized_message_(message_buffer->StealMessage()),
450 paused_(paused),
451 errors_are_fatal_(errors_are_fatal) {
452 ASSERT(closure_tuple_handle_ != nullptr);
453
454 auto thread = Thread::Current();
455 auto isolate = thread->isolate();
456
457 // Inherit flags from spawning isolate.
459}
460
462 const char* script_url,
463 const char* package_config,
464 SerializedObjectBuffer* args_buffer,
465 SerializedObjectBuffer* message_buffer,
466 bool paused,
467 bool errors_are_fatal,
468 Dart_Port on_exit_port,
469 Dart_Port on_error_port,
470 const char* debug_name,
471 IsolateGroup* isolate_group)
472 : parent_port_(parent_port),
473 on_exit_port_(on_exit_port),
474 on_error_port_(on_error_port),
475 script_url_(script_url),
476 package_config_(package_config),
477 debug_name_(debug_name),
478 isolate_group_(isolate_group),
479 serialized_args_(args_buffer->StealMessage()),
480 serialized_message_(message_buffer->StealMessage()),
481 isolate_flags_(),
482 paused_(paused),
483 errors_are_fatal_(errors_are_fatal) {
484 if (debug_name_ == nullptr) {
485 debug_name_ = NewConstChar("main");
486 }
487
488 // By default inherit flags from spawning isolate. These can be overridden
489 // from the calling code.
491}
492
494 delete[] script_url_;
495 delete[] package_config_;
496 delete[] debug_name_;
497}
498
500 Thread* thread = Thread::Current();
501 auto IG = thread->isolate_group();
502 Zone* zone = thread->zone();
503
504 // Handle spawnUri lookup rules.
505 // Check whether the root library defines a main function.
506 const Library& lib =
507 Library::Handle(zone, IG->object_store()->root_library());
508 const String& main = String::Handle(zone, String::New("main"));
510 if (func.IsNull()) {
511 // Check whether main is reexported from the root library.
512 const Object& obj = Object::Handle(zone, lib.LookupReExport(main));
513 if (obj.IsFunction()) {
514 func ^= obj.ptr();
515 }
516 }
517 if (func.IsNull()) {
518 const String& msg = String::Handle(
519 zone,
521 "Unable to resolve function 'main' in script '%s'.", script_url()));
522 return LanguageError::New(msg);
523 }
524 return func.ptr();
525}
526
528 if (message == nullptr) {
529 return Object::null();
530 }
531 if (message->IsRaw()) {
532 return Object::RawCast(message->raw_obj());
533 } else {
534 return ReadMessage(thread, message);
535 }
536}
537
539 const Object& result =
540 Object::Handle(DeserializeMessage(thread, serialized_args_.get()));
541 serialized_args_.reset();
542 return result.ptr();
543}
544
546 const Object& result =
547 Object::Handle(DeserializeMessage(thread, serialized_message_.get()));
548 serialized_message_.reset();
549 return result.ptr();
550}
551
553 const Array& args = Array::Handle(Array::New(1));
554 args.SetAt(0, message);
556}
557
559 public:
560 SpawnIsolateTask(Isolate* parent_isolate,
561 std::unique_ptr<IsolateSpawnState> state)
562 : parent_isolate_(parent_isolate), state_(std::move(state)) {
563 parent_isolate->IncrementSpawnCount();
564 }
565
566 ~SpawnIsolateTask() override {
567 if (parent_isolate_ != nullptr) {
568 parent_isolate_->DecrementSpawnCount();
569 }
570 }
571
572 void Run() override {
573 const char* name = state_->debug_name();
574 ASSERT(name != nullptr);
575
576 auto group = state_->isolate_group();
577 if (group == nullptr) {
579 } else {
581 }
582 }
583
584 void RunHeavyweight(const char* name) {
585 // The create isolate group callback is mandatory. If not provided we
586 // cannot spawn isolates.
587 auto create_group_callback = Isolate::CreateGroupCallback();
588 if (create_group_callback == nullptr) {
589 FailedSpawn("Isolate spawn is not supported by this Dart embedder\n");
590 return;
591 }
592
593 char* error = nullptr;
594
595 // Make a copy of the state's isolate flags and hand it to the callback.
596 Dart_IsolateFlags api_flags = *(state_->isolate_flags());
597
598 // Inherit the system isolate property to work around issues with
599 // --pause-isolates-on-start and --pause-isolates-on-exit impacting macro
600 // generation isolates which are spawned by the kernel-service
601 // (see https://github.com/dart-lang/sdk/issues/54729 for details).
602 //
603 // This flag isn't inherited in the case that the main isolate is marked as
604 // a system isolate in the standalone VM using the
605 // --mark-main-isolate-as-system-isolate flag as it's currently used to
606 // hide test runner implementation details and spawns isolates that should
607 // be debuggable as non-system isolates.
608 //
609 // TODO(bkonyi): revisit this decision, see
610 // https://github.com/dart-lang/sdk/issues/54736 for the tracking issue.
611 const bool is_parent_main_isolate =
612 strcmp(parent_isolate_->name(), "main") == 0;
613 api_flags.is_system_isolate =
614 api_flags.is_system_isolate && !is_parent_main_isolate;
615 Dart_Isolate isolate =
616 (create_group_callback)(state_->script_url(), name, nullptr,
617 state_->package_config(), &api_flags,
618 parent_isolate_->init_callback_data(), &error);
619 parent_isolate_->DecrementSpawnCount();
620 parent_isolate_ = nullptr;
621
622 if (isolate == nullptr) {
623 FailedSpawn(error, /*has_current_isolate=*/false);
624 free(error);
625 return;
626 }
627 Dart_EnterIsolate(isolate);
628 Run(reinterpret_cast<Isolate*>(isolate));
629 }
630
631 void RunLightweight(const char* name) {
632 // The create isolate initialize callback is mandatory.
633 auto initialize_callback = Isolate::InitializeCallback();
634 if (initialize_callback == nullptr) {
635 FailedSpawn(
636 "Lightweight isolate spawn is not supported by this Dart embedder\n",
637 /*has_current_isolate=*/false);
638 return;
639 }
640
641 char* error = nullptr;
642
643 auto group = state_->isolate_group();
645 parent_isolate_->DecrementSpawnCount();
646 parent_isolate_ = nullptr;
647
648 if (isolate == nullptr) {
649 FailedSpawn(error, /*has_current_isolate=*/false);
650 free(error);
651 return;
652 }
653
654 void* child_isolate_data = nullptr;
655 const bool success = initialize_callback(&child_isolate_data, &error);
656 if (!success) {
657 FailedSpawn(error);
659 free(error);
660 return;
661 }
662
663 isolate->set_init_callback_data(child_isolate_data);
664 Run(isolate);
665 }
666
667 private:
668 void Run(Isolate* child) {
669 if (!EnsureIsRunnable(child)) {
671 return;
672 }
673
674 state_->set_isolate(child);
675 if (state_->origin_id() != ILLEGAL_PORT) {
676 // origin_id is set to parent isolate main port id when spawning via
677 // spawnFunction.
678 child->set_origin_id(state_->origin_id());
679 }
680
681 bool success = true;
682 {
683 auto thread = Thread::Current();
684 TransitionNativeToVM transition(thread);
685 StackZone zone(thread);
686 HandleScope hs(thread);
687
688 success = EnqueueEntrypointInvocationAndNotifySpawner(thread);
689 }
690
691 if (!success) {
692 state_ = nullptr;
694 return;
695 }
696
697 // All preconditions are met for this to always succeed.
698 char* error = nullptr;
699 if (!Dart_RunLoopAsync(state_->errors_are_fatal(), state_->on_error_port(),
700 state_->on_exit_port(), &error)) {
701 FATAL("Dart_RunLoopAsync() failed: %s. Please file a Dart VM bug report.",
702 error);
703 }
704 }
705
706 bool EnsureIsRunnable(Isolate* child) {
707 // We called out to the embedder to create/initialize a new isolate. The
708 // embedder callback successfully did so. It is now our responsibility to
709 // run the isolate.
710 // If the isolate was not marked as runnable, we'll do so here and run it.
711 if (!child->is_runnable()) {
712 const char* error = child->MakeRunnable();
713 if (error != nullptr) {
714 FailedSpawn(error);
715 return false;
716 }
717 }
718 ASSERT(child->is_runnable());
719 return true;
720 }
721
722 bool EnqueueEntrypointInvocationAndNotifySpawner(Thread* thread) {
723 auto isolate = thread->isolate();
724 auto zone = thread->zone();
725 const bool is_spawn_uri = state_->is_spawn_uri();
726
727 // Step 1) Resolve the entrypoint function.
728 auto& entrypoint_closure = Closure::Handle(zone);
729 if (state_->closure_tuple_handle() != nullptr) {
730 const auto& result = Object::Handle(
731 zone,
732 ReadObjectGraphCopyMessage(thread, state_->closure_tuple_handle()));
733 if (result.IsError()) {
734 ReportError(
735 "Failed to deserialize the passed entrypoint to the new isolate.");
736 return false;
737 }
738 entrypoint_closure = Closure::RawCast(result.ptr());
739 } else {
740 const auto& result = Object::Handle(zone, state_->ResolveFunction());
741 if (result.IsError()) {
742 ASSERT(is_spawn_uri);
743 ReportError("Failed to resolve entrypoint function.");
744 return false;
745 }
746 ASSERT(result.IsFunction());
747 auto& func = Function::Handle(zone, Function::Cast(result).ptr());
748 func = func.ImplicitClosureFunction();
749 entrypoint_closure = func.ImplicitStaticClosure();
750 }
751
752 // Step 2) Enqueue delayed invocation of entrypoint callback.
753 const auto& args_obj = Object::Handle(zone, state_->BuildArgs(thread));
754 if (args_obj.IsError()) {
755 ReportError(
756 "Failed to deserialize the passed arguments to the new isolate.");
757 return false;
758 }
759 ASSERT(args_obj.IsNull() || args_obj.IsInstance());
760 const auto& message_obj =
761 Object::Handle(zone, state_->BuildMessage(thread));
762 if (message_obj.IsError()) {
763 ReportError(
764 "Failed to deserialize the passed arguments to the new isolate.");
765 return false;
766 }
767 ASSERT(message_obj.IsNull() || message_obj.IsInstance());
768 const Array& args = Array::Handle(zone, Array::New(4));
769 args.SetAt(0, entrypoint_closure);
770 args.SetAt(1, args_obj);
771 args.SetAt(2, message_obj);
772 args.SetAt(3, is_spawn_uri ? Bool::True() : Bool::False());
773
774 const auto& lib = Library::Handle(zone, Library::IsolateLibrary());
775 const auto& entry_name = String::Handle(zone, String::New("_startIsolate"));
776 const auto& entry_point =
777 Function::Handle(zone, lib.LookupFunctionAllowPrivate(entry_name));
778 ASSERT(entry_point.IsFunction() && !entry_point.IsNull());
779 const auto& result =
780 Object::Handle(zone, DartEntry::InvokeFunction(entry_point, args));
781 if (result.IsError()) {
782 ReportError("Failed to enqueue delayed entrypoint invocation.");
783 return false;
784 }
785
786 // Step 3) Pause the isolate if required & Notify parent isolate about
787 // isolate creation.
788 const auto& capabilities = Array::Handle(zone, Array::New(2));
789 auto& capability = Capability::Handle(zone);
790 capability = Capability::New(isolate->pause_capability());
791 capabilities.SetAt(0, capability);
792 capability = Capability::New(isolate->terminate_capability());
793 capabilities.SetAt(1, capability);
794 const auto& send_port =
795 SendPort::Handle(zone, SendPort::New(isolate->main_port()));
796 const auto& message = Array::Handle(zone, Array::New(2));
797 message.SetAt(0, send_port);
798 message.SetAt(1, capabilities);
799 if (state_->paused()) {
800 capability ^= capabilities.At(0);
801 const bool added = isolate->AddResumeCapability(capability);
802 ASSERT(added);
803 isolate->message_handler()->increment_paused();
804 }
805 {
806 // If parent isolate died, we ignore the fact that we cannot notify it.
807 PortMap::PostMessage(WriteMessage(/*same_group=*/false, message,
808 state_->parent_port(),
810 }
811
812 return true;
813 }
814
815 void FailedSpawn(const char* error, bool has_current_isolate = true) {
816 ReportError(error != nullptr
817 ? error
818 : "Unknown error occurred during Isolate spawning.");
819 // Destruction of [IsolateSpawnState] may cause destruction of [Message]
820 // which make need to delete persistent handles (which requires a current
821 // isolate group).
822 if (has_current_isolate) {
823 ASSERT(IsolateGroup::Current() == state_->isolate_group());
824 state_ = nullptr;
825 } else if (state_->isolate_group() != nullptr) {
826 ASSERT(IsolateGroup::Current() == nullptr);
827 const bool kBypassSafepoint = false;
829 state_->isolate_group(), Thread::kUnknownTask, kBypassSafepoint);
830 ASSERT(result);
831 state_ = nullptr;
832 Thread::ExitIsolateGroupAsHelper(kBypassSafepoint);
833 } else {
834 // The state won't need a current isolate group, because it belongs to a
835 // [Isolate.spawnUri] call.
836 state_ = nullptr;
837 }
838 }
839
840 void ReportError(const char* error) {
841 Dart_CObject error_cobj;
842 error_cobj.type = Dart_CObject_kString;
843 error_cobj.value.as_string = const_cast<char*>(error);
844 if (!Dart_PostCObject(state_->parent_port(), &error_cobj)) {
845 // Perhaps the parent isolate died or closed the port before we
846 // could report the error. Ignore.
847 }
848 }
849
850 Isolate* parent_isolate_;
851 std::unique_ptr<IsolateSpawnState> state_;
852
853 DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask);
854};
855
856static const char* String2UTF8(const String& str) {
857 intptr_t len = Utf8::Length(str);
858 char* result = new char[len + 1];
859 str.ToUTF8(reinterpret_cast<uint8_t*>(result), len);
860 result[len] = 0;
861
862 return result;
863}
864
865DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 10) {
866 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
867 GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1));
868 GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(2));
869 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
870 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
871 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(5));
872 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(6));
873 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(7));
874 GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(8));
875 GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(9));
876
877 PersistentHandle* closure_tuple_handle = nullptr;
878 // We have a non-toplevel closure that we might need to copy.
879 // Result will be [<closure-copy>, <objects-in-msg-to-rehash>]
880 const auto& closure_copy_tuple = Object::Handle(
881 zone, CopyMutableObjectGraph(closure)); // Throws if it fails.
882 ASSERT(closure_copy_tuple.IsArray());
883 ASSERT(
884 Object::Handle(zone, Array::Cast(closure_copy_tuple).At(0)).IsClosure());
885 closure_tuple_handle =
886 isolate->group()->api_state()->AllocatePersistentHandle();
887 closure_tuple_handle->set_ptr(closure_copy_tuple.ptr());
888
889 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
890 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
891 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id();
892
893 // We first try to serialize the message. In case the message is not
894 // serializable this will throw an exception.
895 SerializedObjectBuffer message_buffer;
896 message_buffer.set_message(WriteMessage(
897 /*same_group=*/true, message, ILLEGAL_PORT, Message::kNormalPriority));
898
899 const char* utf8_package_config =
900 packageConfig.IsNull() ? nullptr : String2UTF8(packageConfig);
901 const char* utf8_debug_name =
902 debugName.IsNull() ? nullptr : String2UTF8(debugName);
903 if (closure_tuple_handle != nullptr && utf8_debug_name == nullptr) {
904 const auto& closure_function = Function::Handle(zone, closure.function());
905 utf8_debug_name =
906 NewConstChar(closure_function.QualifiedUserVisibleNameCString());
907 }
908
909 std::unique_ptr<IsolateSpawnState> state(new IsolateSpawnState(
910 port.Id(), isolate->origin_id(), String2UTF8(script_uri),
911 closure_tuple_handle, &message_buffer, utf8_package_config,
912 paused.value(), fatal_errors, on_exit_port, on_error_port,
913 utf8_debug_name, isolate->group()));
914
915 isolate->group()->thread_pool()->Run<SpawnIsolateTask>(isolate,
916 std::move(state));
917 return Object::null();
918}
919
920static const char* CanonicalizeUri(Thread* thread,
921 const Library& library,
922 const String& uri,
923 char** error) {
924 const char* result = nullptr;
925 Zone* zone = thread->zone();
926 auto isolate_group = thread->isolate_group();
927 if (isolate_group->HasTagHandler()) {
928 const Object& obj = Object::Handle(
929 isolate_group->CallTagHandler(Dart_kCanonicalizeUrl, library, uri));
930 if (obj.IsString()) {
931 result = String2UTF8(String::Cast(obj));
932 } else if (obj.IsError()) {
933 Error& error_obj = Error::Handle();
934 error_obj ^= obj.ptr();
935 *error = zone->PrintToString("Unable to canonicalize uri '%s': %s",
936 uri.ToCString(), error_obj.ToErrorCString());
937 } else {
938 *error = zone->PrintToString(
939 "Unable to canonicalize uri '%s': "
940 "library tag handler returned wrong type",
941 uri.ToCString());
942 }
943 } else {
944 *error = zone->PrintToString(
945 "Unable to canonicalize uri '%s': no library tag handler found.",
946 uri.ToCString());
947 }
948 return result;
949}
950
951DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 12) {
952 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
953 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1));
954 GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2));
955 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
956 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
957 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5));
958 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6));
959 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7));
960 GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8));
961 GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9));
962 GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(10));
963 GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(11));
964
965 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
966 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id();
967 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id();
968
969 // We first try to serialize the arguments and the message. In case the
970 // arguments or the message are not serializable this will throw an exception.
971 SerializedObjectBuffer arguments_buffer;
972 SerializedObjectBuffer message_buffer;
973 {
974 arguments_buffer.set_message(WriteMessage(
975 /*same_group=*/false, args, ILLEGAL_PORT, Message::kNormalPriority));
976 }
977 {
978 message_buffer.set_message(WriteMessage(
979 /*same_group=*/false, message, ILLEGAL_PORT, Message::kNormalPriority));
980 }
981
982 // Canonicalize the uri with respect to the current isolate.
983 const Library& root_lib =
984 Library::Handle(isolate->group()->object_store()->root_library());
985 char* error = nullptr;
986 const char* canonical_uri = CanonicalizeUri(thread, root_lib, uri, &error);
987 if (canonical_uri == nullptr) {
988 const String& msg = String::Handle(String::New(error));
990 }
991
992 const char* utf8_package_config =
993 packageConfig.IsNull() ? nullptr : String2UTF8(packageConfig);
994 const char* utf8_debug_name =
995 debugName.IsNull() ? nullptr : String2UTF8(debugName);
996
997 std::unique_ptr<IsolateSpawnState> state(new IsolateSpawnState(
998 port.Id(), canonical_uri, utf8_package_config, &arguments_buffer,
999 &message_buffer, paused.value(), fatal_errors, on_exit_port,
1000 on_error_port, utf8_debug_name, /*group=*/nullptr));
1001
1002 // If we were passed a value then override the default flags state for
1003 // checked mode.
1004 if (!checked.IsNull()) {
1005 Dart_IsolateFlags* flags = state->isolate_flags();
1006 flags->enable_asserts = checked.value();
1007 }
1008
1009 isolate->group()->thread_pool()->Run<SpawnIsolateTask>(isolate,
1010 std::move(state));
1011 return Object::null();
1012}
1013
1014DEFINE_NATIVE_ENTRY(Isolate_getDebugName, 0, 1) {
1015 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
1017 if (name == nullptr) {
1018 return String::null();
1019 }
1020 return String::New(name.get());
1021}
1022
1023DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0, 0) {
1024 const Array& result = Array::Handle(Array::New(3));
1025 result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port())));
1026 result.SetAt(
1027 1, Capability::Handle(Capability::New(isolate->pause_capability())));
1028 result.SetAt(
1029 2, Capability::Handle(Capability::New(isolate->terminate_capability())));
1030 return result.ptr();
1031}
1032
1033DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0, 0) {
1034 const Library& root_lib =
1035 Library::Handle(zone, isolate->group()->object_store()->root_library());
1036 return root_lib.url();
1037}
1038
1039DEFINE_NATIVE_ENTRY(Isolate_registerKernelBlob, 0, 1) {
1041 arguments->NativeArgAt(0));
1042 auto register_kernel_blob_callback = Isolate::RegisterKernelBlobCallback();
1043 if (register_kernel_blob_callback == nullptr) {
1045 "Registration of kernel blobs is not supported by this Dart embedder.");
1046 }
1047 bool is_kernel = false;
1048 {
1049 NoSafepointScope no_safepoint;
1050 is_kernel =
1051 Dart_IsKernel(reinterpret_cast<uint8_t*>(kernel_blob.DataAddr(0)),
1052 kernel_blob.LengthInBytes());
1053 }
1054 if (!is_kernel) {
1055 const auto& error = String::Handle(
1056 zone, String::New("kernelBlob doesn\'t contain a valid kernel.\n"));
1058 UNREACHABLE();
1059 }
1060 const char* uri = nullptr;
1061 {
1062 NoSafepointScope no_safepoint;
1063 uri = register_kernel_blob_callback(
1064 reinterpret_cast<uint8_t*>(kernel_blob.DataAddr(0)),
1065 kernel_blob.LengthInBytes());
1066 }
1067 if (uri == nullptr) {
1069 }
1070 return String::New(uri);
1071}
1072
1073DEFINE_NATIVE_ENTRY(Isolate_unregisterKernelBlob, 0, 1) {
1074 GET_NON_NULL_NATIVE_ARGUMENT(String, kernel_blob_uri,
1075 arguments->NativeArgAt(0));
1076 auto unregister_kernel_blob_callback =
1078 if (unregister_kernel_blob_callback == nullptr) {
1080 "Registration of kernel blobs is not supported by this Dart embedder.");
1081 }
1082 unregister_kernel_blob_callback(kernel_blob_uri.ToCString());
1083 return Object::null();
1084}
1085
1086DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 0, 2) {
1087 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
1088 GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1));
1089
1090 // Make sure to route this request to the isolate library OOB message handler.
1092
1093 // Ensure message writer (and it's resources, e.g. forwarding tables) are
1094 // cleaned up before handling interrupts.
1095 {
1096 PortMap::PostMessage(WriteMessage(/*same_group=*/false, msg, port.Id(),
1098 }
1099
1100 // Drain interrupts before running so any IMMEDIATE operations on the current
1101 // isolate happen synchronously.
1102 const Error& error = Error::Handle(thread->HandleInterrupts());
1103 if (!error.IsNull()) {
1105 UNREACHABLE();
1106 }
1107
1108 return Object::null();
1109}
1110
1111static void ExternalTypedDataFinalizer(void* isolate_callback_data,
1112 void* peer) {
1113 free(peer);
1114}
1115
1117 // From the Dart side we are guaranteed that the type of [instance] is a
1118 // subtype of TypedData.
1119 if (instance.IsTypedDataBase()) {
1120 return TypedDataBase::Cast(instance).LengthInBytes();
1121 }
1122
1123 // This can happen if [instance] is `null` or an instance of a 3rd party class
1124 // which implements [TypedData].
1126}
1127
1128DEFINE_NATIVE_ENTRY(TransferableTypedData_factory, 0, 2) {
1129 ASSERT(
1130 TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
1131
1132 GET_NON_NULL_NATIVE_ARGUMENT(Instance, array_instance,
1133 arguments->NativeArgAt(1));
1134
1135 Array& array = Array::Handle();
1136 intptr_t array_length;
1137 if (array_instance.IsGrowableObjectArray()) {
1138 const auto& growable_array = GrowableObjectArray::Cast(array_instance);
1139 array ^= growable_array.data();
1140 array_length = growable_array.Length();
1141 } else if (array_instance.IsArray()) {
1142 array ^= Array::Cast(array_instance).ptr();
1143 array_length = array.Length();
1144 } else {
1145 Exceptions::ThrowArgumentError(array_instance);
1146 UNREACHABLE();
1147 }
1149 uint64_t total_bytes = 0;
1150 const uint64_t kMaxBytes = TypedData::MaxElements(kTypedDataUint8ArrayCid);
1151 for (intptr_t i = 0; i < array_length; i++) {
1152 instance ^= array.At(i);
1153 total_bytes += static_cast<uintptr_t>(GetTypedDataSizeOrThrow(instance));
1154 if (total_bytes > kMaxBytes) {
1155 const Array& error_args = Array::Handle(Array::New(3));
1156 error_args.SetAt(0, array);
1157 error_args.SetAt(1, String::Handle(String::New("data")));
1158 error_args.SetAt(
1160 "Aggregated list exceeds max size %" Pu64 "", kMaxBytes)));
1162 UNREACHABLE();
1163 }
1164 }
1165
1166 uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(total_bytes));
1167 if (data == nullptr) {
1168 const Instance& exception = Instance::Handle(
1169 thread->isolate_group()->object_store()->out_of_memory());
1170 Exceptions::Throw(thread, exception);
1171 UNREACHABLE();
1172 }
1173 intptr_t offset = 0;
1174 for (intptr_t i = 0; i < array_length; i++) {
1175 instance ^= array.At(i);
1176
1177 {
1178 NoSafepointScope no_safepoint;
1179 const auto& typed_data = TypedDataBase::Cast(instance);
1180 const intptr_t length_in_bytes = typed_data.LengthInBytes();
1181
1182 void* source = typed_data.DataAddr(0);
1183 // The memory does not overlap.
1184 memcpy(data + offset, source, length_in_bytes); // NOLINT
1185 offset += length_in_bytes;
1186 }
1187 }
1188 ASSERT(static_cast<uintptr_t>(offset) == total_bytes);
1189 return TransferableTypedData::New(data, total_bytes);
1190}
1191
1192DEFINE_NATIVE_ENTRY(TransferableTypedData_materialize, 0, 1) {
1194 arguments->NativeArgAt(0));
1195
1196 void* peer;
1197 {
1198 NoSafepointScope no_safepoint;
1199 peer = thread->heap()->GetPeer(t.ptr());
1200 // Assume that object's Peer is only used to track transferability state.
1201 ASSERT(peer != nullptr);
1202 }
1203
1205 reinterpret_cast<TransferableTypedDataPeer*>(peer);
1206 const intptr_t length = tpeer->length();
1207 uint8_t* data = tpeer->data();
1208 if (data == nullptr) {
1209 const auto& error = String::Handle(String::New(
1210 "Attempt to materialize object that was transferred already."));
1212 UNREACHABLE();
1213 }
1215 tpeer->ClearData();
1216
1217 const ExternalTypedData& typed_data = ExternalTypedData::Handle(
1218 ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, length,
1219 thread->heap()->SpaceForExternal(length)));
1220 FinalizablePersistentHandle* finalizable_ref =
1221 FinalizablePersistentHandle::New(thread->isolate_group(), typed_data,
1222 /* peer= */ data,
1224 /*auto_delete=*/true);
1225 ASSERT(finalizable_ref != nullptr);
1226 return typed_data.ptr();
1227}
1228
1229} // namespace dart
static uint32_t hash(const SkShaderBase::GradientInfo &v)
#define UNREACHABLE()
Definition: assert.h:248
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.h:10959
virtual TypeArgumentsPtr GetTypeArguments() const
Definition: object.h:10905
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
void Add(const T &value)
intptr_t length() const
static const Bool & False()
Definition: object.h:10799
static const Bool & Get(bool value)
Definition: object.h:10801
static const Bool & True()
Definition: object.h:10797
static CapabilityPtr New(uint64_t id, Heap::Space space=Heap::kNew)
Definition: object.cc:25773
ClassPtr At(intptr_t cid) const
Definition: class_table.h:362
bool is_isolate_unsendable() const
Definition: object.h:2163
static ObjectPtr InvokeFunction(const Function &function, const Array &arguments)
Definition: dart_entry.cc:31
virtual const char * ToErrorCString() const
Definition: object.cc:19780
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
Definition: exceptions.cc:1052
static DART_NORETURN void ThrowOOM()
Definition: exceptions.cc:1066
static DART_NORETURN void ThrowUnsupportedError(const char *msg)
Definition: exceptions.cc:1106
static DART_NORETURN void Throw(Thread *thread, const Instance &exception)
Definition: exceptions.cc:979
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
Definition: exceptions.cc:1082
static ObjectPtr Create(ExceptionType type, const Array &arguments)
Definition: exceptions.cc:1132
static DART_NORETURN void PropagateError(const Error &error)
Definition: exceptions.cc:1003
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:25626
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:22984
static IsolateGroup * Current()
Definition: isolate.h:539
ClassTable * class_table() const
Definition: isolate.h:496
const char * script_url() const
Definition: isolate.cc:382
bool paused() const
Definition: isolate.cc:388
Dart_Port parent_port() const
Definition: isolate.cc:378
void set_isolate(Isolate *value)
Definition: isolate.cc:376
const char * debug_name() const
Definition: isolate.cc:384
PersistentHandle * closure_tuple_handle() const
Definition: isolate.cc:391
Dart_Port on_error_port() const
Definition: isolate.cc:381
const char * package_config() const
Definition: isolate.cc:383
bool is_spawn_uri() const
Definition: isolate.cc:385
ObjectPtr ResolveFunction()
Definition: isolate.cc:499
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:427
IsolateGroup * isolate_group() const
Definition: isolate.cc:399
ObjectPtr BuildArgs(Thread *thread)
Definition: isolate.cc:538
Dart_IsolateFlags * isolate_flags()
Definition: isolate.cc:390
Dart_Port origin_id() const
Definition: isolate.cc:379
ObjectPtr BuildMessage(Thread *thread)
Definition: isolate.cc:545
bool errors_are_fatal() const
Definition: isolate.cc:389
Isolate * isolate() const
Definition: isolate.cc:375
Dart_Port on_exit_port() const
Definition: isolate.cc:380
static Isolate * Current()
Definition: isolate.h:986
void FlagsCopyTo(Dart_IsolateFlags *api_flags) const
Definition: isolate.cc:1661
MallocGrowableArray< ObjectPtr > * pointers_to_verify_at_exit()
Definition: isolate.h:1479
void DecrementSpawnCount()
Definition: isolate.cc:3716
static std::unique_ptr< char[]> LookupIsolateNameByPort(Dart_Port port)
Definition: isolate.cc:3561
void * init_callback_data() const
Definition: isolate.h:1068
void set_forward_table_new(WeakTable *table)
Definition: isolate.cc:2548
IsolateGroup * group() const
Definition: isolate.h:1037
static Dart_IsolateGroupCreateCallback CreateGroupCallback()
Definition: isolate.h:1203
void set_init_callback_data(void *value)
Definition: isolate.h:1067
static Dart_UnregisterKernelBlobCallback UnregisterKernelBlobCallback()
Definition: isolate.h:1245
static Dart_InitializeIsolateCallback InitializeCallback()
Definition: isolate.h:1210
Dart_Port origin_id()
Definition: isolate.cc:1990
void IncrementSpawnCount()
Definition: isolate.cc:3711
void set_origin_id(Dart_Port id)
Definition: isolate.cc:1995
static Dart_RegisterKernelBlobCallback RegisterKernelBlobCallback()
Definition: isolate.h:1238
const char * name() const
Definition: isolate.h:1043
ObjectPtr LookupReExport(const String &name, ZoneGrowableArray< intptr_t > *visited=nullptr) const
Definition: object.cc:13855
static LibraryPtr IsolateLibrary()
Definition: object.cc:14807
FunctionPtr LookupFunctionAllowPrivate(const String &name) const
Definition: object.cc:14084
StringPtr url() const
Definition: object.h:5097
@ kIsolateLibOOBMsg
Definition: message.h:42
@ kNormalPriority
Definition: message.h:28
@ kOOBPriority
Definition: message.h:29
UntaggedObject * untag() const
intptr_t GetClassId() const
Definition: raw_object.h:885
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:25812
Dart_Port origin_id() const
Definition: object.h:12492
void set_message(std::unique_ptr< Message > message)
Definition: snapshot.h:122
static SmiPtr New(intptr_t value)
Definition: object.h:10006
SpawnIsolateTask(Isolate *parent_isolate, std::unique_ptr< IsolateSpawnState > state)
Definition: isolate.cc:560
~SpawnIsolateTask() override
Definition: isolate.cc:566
void Run() override
Definition: isolate.cc:572
void RunLightweight(const char *name)
Definition: isolate.cc:631
void RunHeavyweight(const char *name)
Definition: isolate.cc:584
static StringPtr NewFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition: object.cc:24004
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
void ToUTF8(uint8_t *utf8_array, intptr_t array_len) const
Definition: object.cc:24146
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition: object.cc:24126
Zone * zone() const
Definition: thread_state.h:37
void StartUnwindError()
Definition: thread.h:645
@ kUnknownTask
Definition: thread.h:346
static Thread * Current()
Definition: thread.h:362
void CheckForSafepoint()
Definition: thread.h:1104
static void ExitIsolateGroupAsHelper(bool bypass_safepoint)
Definition: thread.cc:499
IsolateGroup * isolate_group() const
Definition: thread.h:541
static bool EnterIsolateGroupAsHelper(IsolateGroup *isolate_group, TaskKind kind, bool bypass_safepoint)
Definition: thread.cc:481
FinalizablePersistentHandle * handle() const
Definition: object.h:12523
uint8_t * data() const
Definition: object.h:12521
static TransferableTypedDataPtr New(uint8_t *data, intptr_t len)
Definition: object.cc:25835
static intptr_t MaxElements(intptr_t class_id)
Definition: object.h:11684
static UnhandledExceptionPtr New(const Instance &exception, const Instance &stacktrace, Heap::Space space=Heap::kNew)
Definition: object.cc:19939
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:447
bool IsCanonical() const
Definition: raw_object.h:350
static UnwindErrorPtr New(const String &message, Heap::Space space=Heap::kNew)
Definition: object.cc:20005
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:1535
int64_t Dart_Port
Definition: dart_api.h:1525
struct _Dart_Isolate * Dart_Isolate
Definition: dart_api.h:88
@ Dart_kCanonicalizeUrl
Definition: dart_api.h:3420
@ 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 dart::SimpleHashMap * environment
Definition: gen_snapshot.cc:59
Definition: dart_vm.cc:33
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:420
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:527
ObjectPtr CopyMutableObjectGraph(const Object &object)
static void ThrowIsolateSpawnException(const String &message)
Definition: isolate.cc:552
uintptr_t uword
Definition: globals.h:501
static const char * String2UTF8(const String &str)
Definition: isolate.cc:856
static constexpr intptr_t kSlotsPerInterruptCheck
Definition: page.h:359
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)
DEFINE_NATIVE_ENTRY(List_allocate, 0, 2)
Definition: array.cc:13
static const char * CanonicalizeUri(Thread *thread, const Library &library, const String &uri, char **error)
Definition: isolate.cc:920
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:1111
static intptr_t GetTypedDataSizeOrThrow(const Instance &instance)
Definition: isolate.cc:1116
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 port
Definition: switches.h:87
std::function< void()> closure
Definition: closure.h:14
Definition: main.py:1
Definition: ref_ptr.h:256
#define GET_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:84
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:74
#define Pu64
Definition: globals.h:417
SeparatedVector2 offset
bool is_system_isolate
Definition: dart_api.h:592
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
#define IG
Definition: isolate.cc:104