Flutter Engine
dart_isolate.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/runtime/dart_isolate.h"
6 
7 #include <cstdlib>
8 #include <tuple>
9 
10 #include "flutter/fml/posix_wrappers.h"
11 #include "flutter/fml/trace_event.h"
12 #include "flutter/lib/io/dart_io.h"
13 #include "flutter/lib/ui/dart_runtime_hooks.h"
14 #include "flutter/lib/ui/dart_ui.h"
15 #include "flutter/runtime/dart_isolate_group_data.h"
16 #include "flutter/runtime/dart_service_isolate.h"
17 #include "flutter/runtime/dart_vm.h"
18 #include "flutter/runtime/dart_vm_lifecycle.h"
19 #include "flutter/runtime/isolate_configuration.h"
21 #include "fml/task_source.h"
22 #include "fml/time/time_point.h"
23 #include "third_party/dart/runtime/include/dart_api.h"
24 #include "third_party/dart/runtime/include/dart_tools_api.h"
34 
35 namespace flutter {
36 
37 namespace {
38 
39 constexpr std::string_view kFileUriPrefix = "file://";
40 
41 class DartErrorString {
42  public:
43  DartErrorString() : str_(nullptr) {}
44  ~DartErrorString() {
45  if (str_) {
46  ::free(str_);
47  }
48  }
49  char** error() { return &str_; }
50  const char* str() const { return str_; }
51  explicit operator bool() const { return str_ != nullptr; }
52 
53  private:
54  FML_DISALLOW_COPY_AND_ASSIGN(DartErrorString);
55  char* str_;
56 };
57 
58 } // anonymous namespace
59 
61 
62 DartIsolate::Flags::Flags(const Dart_IsolateFlags* flags) {
63  if (flags) {
64  flags_ = *flags;
65  } else {
66  ::Dart_IsolateFlagsInitialize(&flags_);
67  }
68 }
69 
70 DartIsolate::Flags::~Flags() = default;
71 
73  flags_.null_safety = enabled;
74 }
75 
77  flags_.snapshot_is_dontneed_safe = value;
78 }
79 
80 Dart_IsolateFlags DartIsolate::Flags::Get() const {
81  return flags_;
82 }
83 
84 std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
85  const Settings& settings,
86  fml::RefPtr<const DartSnapshot> isolate_snapshot,
87  std::unique_ptr<PlatformConfiguration> platform_configuration,
88  Flags isolate_flags,
89  fml::closure root_isolate_create_callback,
90  const fml::closure& isolate_create_callback,
91  const fml::closure& isolate_shutdown_callback,
92  std::optional<std::string> dart_entrypoint,
93  std::optional<std::string> dart_entrypoint_library,
94  const std::vector<std::string>& dart_entrypoint_args,
95  std::unique_ptr<IsolateConfiguration> isolate_configuration,
96  const UIDartState::Context& context,
97  const DartIsolate* spawning_isolate) {
98  if (!isolate_snapshot) {
99  FML_LOG(ERROR) << "Invalid isolate snapshot.";
100  return {};
101  }
102 
103  if (!isolate_configuration) {
104  FML_LOG(ERROR) << "Invalid isolate configuration.";
105  return {};
106  }
107 
108  isolate_flags.SetNullSafetyEnabled(
109  isolate_configuration->IsNullSafetyEnabled(*isolate_snapshot));
110  isolate_flags.SetIsDontNeedSafe(isolate_snapshot->IsDontNeedSafe());
111 
112  auto isolate = CreateRootIsolate(settings, //
113  isolate_snapshot, //
114  std::move(platform_configuration), //
115  isolate_flags, //
116  isolate_create_callback, //
117  isolate_shutdown_callback, //
118  context, //
119  spawning_isolate //
120  )
121  .lock();
122 
123  if (!isolate) {
124  FML_LOG(ERROR) << "Could not create root isolate.";
125  return {};
126  }
127 
128  fml::ScopedCleanupClosure shutdown_on_error([isolate]() {
129  if (!isolate->Shutdown()) {
130  FML_DLOG(ERROR) << "Could not shutdown transient isolate.";
131  }
132  });
133 
134  if (isolate->GetPhase() != DartIsolate::Phase::LibrariesSetup) {
135  FML_LOG(ERROR) << "Root isolate was created in an incorrect phase: "
136  << static_cast<int>(isolate->GetPhase());
137  return {};
138  }
139 
140  if (!isolate_configuration->PrepareIsolate(*isolate.get())) {
141  FML_LOG(ERROR) << "Could not prepare isolate.";
142  return {};
143  }
144 
145  if (isolate->GetPhase() != DartIsolate::Phase::Ready) {
146  FML_LOG(ERROR) << "Root isolate not in the ready phase for Dart entrypoint "
147  "invocation.";
148  return {};
149  }
150 
151  if (settings.root_isolate_create_callback) {
152  // Isolate callbacks always occur in isolate scope and before user code has
153  // had a chance to run.
154  tonic::DartState::Scope scope(isolate.get());
155  settings.root_isolate_create_callback(*isolate.get());
156  }
157 
158  if (root_isolate_create_callback) {
159  root_isolate_create_callback();
160  }
161 
162  if (!isolate->RunFromLibrary(dart_entrypoint_library, //
163  dart_entrypoint, //
164  dart_entrypoint_args)) {
165  FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
166  return {};
167  }
168 
169  if (settings.root_isolate_shutdown_callback) {
170  isolate->AddIsolateShutdownCallback(
172  }
173 
174  shutdown_on_error.Release();
175 
176  return isolate;
177 }
178 
179 void DartIsolate::SpawnIsolateShutdownCallback(
180  std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
181  std::shared_ptr<DartIsolate>* isolate_data) {
182  DartIsolate::DartIsolateShutdownCallback(isolate_group_data, isolate_data);
183 }
184 
185 std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
186  const Settings& settings,
187  fml::RefPtr<const DartSnapshot> isolate_snapshot,
188  std::unique_ptr<PlatformConfiguration> platform_configuration,
189  Flags flags,
190  const fml::closure& isolate_create_callback,
191  const fml::closure& isolate_shutdown_callback,
192  const UIDartState::Context& context,
193  const DartIsolate* spawning_isolate) {
194  TRACE_EVENT0("flutter", "DartIsolate::CreateRootIsolate");
195 
196  // The child isolate preparer is null but will be set when the isolate is
197  // being prepared to run.
198  auto isolate_group_data =
199  std::make_unique<std::shared_ptr<DartIsolateGroupData>>(
200  std::shared_ptr<DartIsolateGroupData>(new DartIsolateGroupData(
201  settings, // settings
202  std::move(isolate_snapshot), // isolate snapshot
203  context.advisory_script_uri, // advisory URI
204  context.advisory_script_entrypoint, // advisory entrypoint
205  nullptr, // child isolate preparer
206  isolate_create_callback, // isolate create callback
207  isolate_shutdown_callback // isolate shutdown callback
208  )));
209 
210  auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
211  std::shared_ptr<DartIsolate>(new DartIsolate(
212  settings, // settings
213  true, // is_root_isolate
214  std::move(context) // context
215  )));
216 
217  DartErrorString error;
218  Dart_Isolate vm_isolate = nullptr;
219  auto isolate_flags = flags.Get();
220 
221  IsolateMaker isolate_maker;
222  if (spawning_isolate) {
223  isolate_maker = [spawning_isolate](
224  std::shared_ptr<DartIsolateGroupData>*
225  isolate_group_data,
226  std::shared_ptr<DartIsolate>* isolate_data,
227  Dart_IsolateFlags* flags, char** error) {
228  return Dart_CreateIsolateInGroup(
229  /*group_member=*/spawning_isolate->isolate(),
230  /*name=*/(*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
231  /*shutdown_callback=*/
232  reinterpret_cast<Dart_IsolateShutdownCallback>(
233  DartIsolate::SpawnIsolateShutdownCallback),
234  /*cleanup_callback=*/
235  reinterpret_cast<Dart_IsolateCleanupCallback>(
236  DartIsolateCleanupCallback),
237  /*child_isolate_data=*/isolate_data,
238  /*error=*/error);
239  };
240  } else {
241  isolate_maker = [](std::shared_ptr<DartIsolateGroupData>*
242  isolate_group_data,
243  std::shared_ptr<DartIsolate>* isolate_data,
244  Dart_IsolateFlags* flags, char** error) {
245  return Dart_CreateIsolateGroup(
246  (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
247  (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
248  (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
249  (*isolate_group_data)->GetIsolateSnapshot()->GetInstructionsMapping(),
250  flags, isolate_group_data, isolate_data, error);
251  };
252  }
253 
254  vm_isolate = CreateDartIsolateGroup(std::move(isolate_group_data),
255  std::move(isolate_data), &isolate_flags,
256  error.error(), isolate_maker);
257 
258  if (error) {
259  FML_LOG(ERROR) << "CreateRootIsolate failed: " << error.str();
260  }
261 
262  if (vm_isolate == nullptr) {
263  return {};
264  }
265 
266  std::shared_ptr<DartIsolate>* root_isolate_data =
267  static_cast<std::shared_ptr<DartIsolate>*>(Dart_IsolateData(vm_isolate));
268 
269  (*root_isolate_data)
270  ->SetPlatformConfiguration(std::move(platform_configuration));
271 
272  return (*root_isolate_data)->GetWeakIsolatePtr();
273 }
274 
275 DartIsolate::DartIsolate(const Settings& settings,
276  bool is_root_isolate,
277  const UIDartState::Context& context)
278  : UIDartState(settings.task_observer_add,
279  settings.task_observer_remove,
280  settings.log_tag,
282  settings.log_message_callback,
284  is_root_isolate,
285  settings.enable_skparagraph,
286  settings.enable_display_list,
287  std::move(context)),
288  may_insecurely_connect_to_all_domains_(
290  domain_network_policy_(settings.domain_network_policy) {
291  phase_ = Phase::Uninitialized;
292 }
293 
296  FML_DCHECK(GetMessageHandlingTaskRunner()->RunsTasksOnCurrentThread());
297  }
298 }
299 
301  return phase_;
302 }
303 
305  const char* service_id_buf = Dart_IsolateServiceId(isolate());
306  std::string service_id(service_id_buf);
307  free(const_cast<char*>(service_id_buf));
308  return service_id;
309 }
310 
311 bool DartIsolate::Initialize(Dart_Isolate dart_isolate) {
312  TRACE_EVENT0("flutter", "DartIsolate::Initialize");
313  if (phase_ != Phase::Uninitialized) {
314  return false;
315  }
316 
317  if (dart_isolate == nullptr) {
318  return false;
319  }
320 
321  if (Dart_CurrentIsolate() != dart_isolate) {
322  return false;
323  }
324 
325  // After this point, isolate scopes can be safely used.
326  SetIsolate(dart_isolate);
327 
328  // We are entering a new scope (for the first time since initialization) and
329  // we want to restore the current scope to null when we exit out of this
330  // method. This balances the implicit Dart_EnterIsolate call made by
331  // Dart_CreateIsolateGroup (which calls the Initialize).
332  Dart_ExitIsolate();
333 
335 
336  // For the root isolate set the "AppStartUp" as soon as the root isolate
337  // has been initialized. This is to ensure that all the timeline events
338  // that have the set user-tag will be listed user AppStartUp.
339  if (IsRootIsolate()) {
340  tonic::DartApiScope api_scope;
341  Dart_SetCurrentUserTag(Dart_NewUserTag("AppStartUp"));
342  }
343 
344  SetMessageHandlingTaskRunner(GetTaskRunners().GetUITaskRunner());
345 
346  if (tonic::LogIfError(
347  Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))) {
348  return false;
349  }
350 
351  if (tonic::LogIfError(Dart_SetDeferredLoadHandler(OnDartLoadLibrary))) {
352  return false;
353  }
354 
355  if (!UpdateThreadPoolNames()) {
356  return false;
357  }
358 
359  phase_ = Phase::Initialized;
360  return true;
361 }
362 
364  return message_handling_task_runner_;
365 }
366 
368  intptr_t loading_unit_id,
369  std::unique_ptr<const fml::Mapping> snapshot_data,
370  std::unique_ptr<const fml::Mapping> snapshot_instructions) {
371  tonic::DartState::Scope scope(this);
372 
373  fml::RefPtr<DartSnapshot> dart_snapshot =
375  std::move(snapshot_data), std::move(snapshot_instructions));
376 
377  Dart_Handle result = Dart_DeferredLoadComplete(
378  loading_unit_id, dart_snapshot->GetDataMapping(),
379  dart_snapshot->GetInstructionsMapping());
380  if (tonic::LogIfError(result)) {
381  LoadLoadingUnitError(loading_unit_id, Dart_GetError(result),
382  /*transient*/ true);
383  return false;
384  }
385  loading_unit_snapshots_.insert(dart_snapshot);
386  return true;
387 }
388 
389 void DartIsolate::LoadLoadingUnitError(intptr_t loading_unit_id,
390  const std::string error_message,
391  bool transient) {
392  tonic::DartState::Scope scope(this);
393  Dart_Handle result = Dart_DeferredLoadCompleteError(
394  loading_unit_id, error_message.c_str(), transient);
395  tonic::LogIfError(result);
396 }
397 
398 void DartIsolate::SetMessageHandlingTaskRunner(
400  if (!IsRootIsolate() || !runner) {
401  return;
402  }
403 
404  message_handling_task_runner_ = runner;
405 
406  message_handler().Initialize([runner](std::function<void()> task) {
407 #ifdef OS_FUCHSIA
408  runner->PostTask([task = std::move(task)]() {
409  TRACE_EVENT0("flutter", "DartIsolate::HandleMessage");
410  task();
411  });
412 #else
413  auto task_queues = fml::MessageLoopTaskQueues::GetInstance();
414  task_queues->RegisterTask(
415  runner->GetTaskQueueId(),
416  [task = std::move(task)]() {
417  TRACE_EVENT0("flutter", "DartIsolate::HandleMessage");
418  task();
419  },
421 #endif
422  });
423 }
424 
425 // Updating thread names here does not change the underlying OS thread names.
426 // Instead, this is just additional metadata for the Observatory to show the
427 // thread name of the isolate.
428 bool DartIsolate::UpdateThreadPoolNames() const {
429  // TODO(chinmaygarde): This implementation does not account for multiple
430  // shells sharing the same (or subset of) threads.
431  const auto& task_runners = GetTaskRunners();
432 
433  if (auto task_runner = task_runners.GetRasterTaskRunner()) {
434  task_runner->PostTask(
435  [label = task_runners.GetLabel() + std::string{".raster"}]() {
436  Dart_SetThreadName(label.c_str());
437  });
438  }
439 
440  if (auto task_runner = task_runners.GetUITaskRunner()) {
441  task_runner->PostTask(
442  [label = task_runners.GetLabel() + std::string{".ui"}]() {
443  Dart_SetThreadName(label.c_str());
444  });
445  }
446 
447  if (auto task_runner = task_runners.GetIOTaskRunner()) {
448  task_runner->PostTask(
449  [label = task_runners.GetLabel() + std::string{".io"}]() {
450  Dart_SetThreadName(label.c_str());
451  });
452  }
453 
454  if (auto task_runner = task_runners.GetPlatformTaskRunner()) {
455  task_runner->PostTask(
456  [label = task_runners.GetLabel() + std::string{".platform"}]() {
457  Dart_SetThreadName(label.c_str());
458  });
459  }
460 
461  return true;
462 }
463 
464 bool DartIsolate::LoadLibraries() {
465  TRACE_EVENT0("flutter", "DartIsolate::LoadLibraries");
466  if (phase_ != Phase::Initialized) {
467  return false;
468  }
469 
470  tonic::DartState::Scope scope(this);
471 
472  DartIO::InitForIsolate(may_insecurely_connect_to_all_domains_,
473  domain_network_policy_);
474 
476 
477  const bool is_service_isolate = Dart_IsServiceIsolate(isolate());
478 
479  DartRuntimeHooks::Install(IsRootIsolate() && !is_service_isolate,
481 
482  if (!is_service_isolate) {
484  "ui", std::make_unique<tonic::DartClassProvider>(this, "dart:ui"));
485  }
486 
487  phase_ = Phase::LibrariesSetup;
488  return true;
489 }
490 
492  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromPrecompiledCode");
493  if (phase_ != Phase::LibrariesSetup) {
494  return false;
495  }
496 
497  tonic::DartState::Scope scope(this);
498 
499  if (Dart_IsNull(Dart_RootLibrary())) {
500  return false;
501  }
502 
503  if (!MarkIsolateRunnable()) {
504  return false;
505  }
506 
507  if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
508  GetIsolateGroupData().SetChildIsolatePreparer([](DartIsolate* isolate) {
509  return isolate->PrepareForRunningFromPrecompiledCode();
510  });
511  }
512 
513  const fml::closure& isolate_create_callback =
514  GetIsolateGroupData().GetIsolateCreateCallback();
515  if (isolate_create_callback) {
516  isolate_create_callback();
517  }
518 
519  phase_ = Phase::Ready;
520  return true;
521 }
522 
523 bool DartIsolate::LoadKernel(std::shared_ptr<const fml::Mapping> mapping,
524  bool last_piece) {
525  if (!Dart_IsKernel(mapping->GetMapping(), mapping->GetSize())) {
526  return false;
527  }
528 
529  // Mapping must be retained until isolate shutdown.
530  kernel_buffers_.push_back(mapping);
531 
532  Dart_Handle library =
533  Dart_LoadLibraryFromKernel(mapping->GetMapping(), mapping->GetSize());
534  if (tonic::LogIfError(library)) {
535  return false;
536  }
537 
538  if (!last_piece) {
539  // More to come.
540  return true;
541  }
542 
543  Dart_SetRootLibrary(library);
544  if (tonic::LogIfError(Dart_FinalizeLoading(false))) {
545  return false;
546  }
547  return true;
548 }
549 
551  std::shared_ptr<const fml::Mapping> mapping,
552  bool child_isolate,
553  bool last_piece) {
554  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromKernel");
555  if (phase_ != Phase::LibrariesSetup) {
556  return false;
557  }
558 
560  return false;
561  }
562 
563  if (!mapping || mapping->GetSize() == 0) {
564  return false;
565  }
566 
567  tonic::DartState::Scope scope(this);
568 
569  if (!child_isolate) {
570  // Use root library provided by kernel in favor of one provided by snapshot.
571  Dart_SetRootLibrary(Dart_Null());
572 
573  if (!LoadKernel(mapping, last_piece)) {
574  return false;
575  }
576  }
577 
578  if (!last_piece) {
579  // More to come.
580  return true;
581  }
582 
583  if (Dart_IsNull(Dart_RootLibrary())) {
584  return false;
585  }
586 
587  if (!MarkIsolateRunnable()) {
588  return false;
589  }
590 
591  // Child isolate shares root isolate embedder_isolate (lines 691 and 693
592  // below). Re-initializing child_isolate_preparer_ lambda while it is being
593  // executed leads to crashes.
594  if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
595  GetIsolateGroupData().SetChildIsolatePreparer(
596  [buffers = kernel_buffers_](DartIsolate* isolate) {
597  for (uint64_t i = 0; i < buffers.size(); i++) {
598  bool last_piece = i + 1 == buffers.size();
599  const std::shared_ptr<const fml::Mapping>& buffer = buffers.at(i);
600  if (!isolate->PrepareForRunningFromKernel(buffer,
601  /*child_isolate=*/true,
602  last_piece)) {
603  return false;
604  }
605  }
606  return true;
607  });
608  }
609 
610  const fml::closure& isolate_create_callback =
611  GetIsolateGroupData().GetIsolateCreateCallback();
612  if (isolate_create_callback) {
613  isolate_create_callback();
614  }
615 
616  phase_ = Phase::Ready;
617 
618  return true;
619 }
620 
622  std::vector<std::shared_ptr<const fml::Mapping>> kernels) {
623  const auto count = kernels.size();
624  if (count == 0) {
625  return false;
626  }
627 
628  for (size_t i = 0; i < count; ++i) {
629  bool last = (i == (count - 1));
630  if (!PrepareForRunningFromKernel(kernels[i], /*child_isolate=*/false,
631  last)) {
632  return false;
633  }
634  }
635 
636  return true;
637 }
638 
640  std::vector<std::unique_ptr<const fml::Mapping>> kernels) {
641  std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
642  for (auto& kernel : kernels) {
643  shared_kernels.emplace_back(std::move(kernel));
644  }
645  return PrepareForRunningFromKernels(shared_kernels);
646 }
647 
648 bool DartIsolate::MarkIsolateRunnable() {
649  TRACE_EVENT0("flutter", "DartIsolate::MarkIsolateRunnable");
650  if (phase_ != Phase::LibrariesSetup) {
651  return false;
652  }
653 
654  // This function may only be called from an active isolate scope.
655  if (Dart_CurrentIsolate() != isolate()) {
656  return false;
657  }
658 
659  // There must be no current isolate to mark an isolate as being runnable.
660  Dart_ExitIsolate();
661 
662  char* error = Dart_IsolateMakeRunnable(isolate());
663  if (error) {
664  FML_DLOG(ERROR) << error;
665  ::free(error);
666  // Failed. Restore the isolate.
667  Dart_EnterIsolate(isolate());
668  return false;
669  }
670  // Success. Restore the isolate.
671  Dart_EnterIsolate(isolate());
672  return true;
673 }
674 
675 [[nodiscard]] static bool InvokeMainEntrypoint(
676  Dart_Handle user_entrypoint_function,
677  Dart_Handle args) {
678  if (tonic::LogIfError(user_entrypoint_function)) {
679  FML_LOG(ERROR) << "Could not resolve main entrypoint function.";
680  return false;
681  }
682 
683  Dart_Handle start_main_isolate_function =
684  tonic::DartInvokeField(Dart_LookupLibrary(tonic::ToDart("dart:isolate")),
685  "_getStartMainIsolateFunction", {});
686 
687  if (tonic::LogIfError(start_main_isolate_function)) {
688  FML_LOG(ERROR) << "Could not resolve main entrypoint trampoline.";
689  return false;
690  }
691 
693  Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned",
694  {start_main_isolate_function, user_entrypoint_function, args}))) {
695  FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
696  return false;
697  }
698 
699  return true;
700 }
701 
702 static void InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle) {
703  TRACE_EVENT0("flutter", "InvokeDartPluginRegistrantIfAvailable");
704 
705  // The Dart plugin registrant is a static method with signature `void
706  // register()` within the class `_PluginRegistrant` generated by the Flutter
707  // tool.
708  //
709  // This method binds a plugin implementation to their platform
710  // interface based on the configuration of the app's pubpec.yaml, and the
711  // plugin's pubspec.yaml.
712  //
713  // Since this method may or may not be defined, check if the class is defined
714  // in the default library before calling the method.
715  Dart_Handle plugin_registrant =
716  ::Dart_GetClass(library_handle, tonic::ToDart("_PluginRegistrant"));
717 
718  if (Dart_IsError(plugin_registrant)) {
719  return;
720  }
721  tonic::LogIfError(tonic::DartInvokeField(plugin_registrant, "register", {}));
722 }
723 
724 bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name,
725  std::optional<std::string> entrypoint,
726  const std::vector<std::string>& args) {
727  TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
728  if (phase_ != Phase::Ready) {
729  return false;
730  }
731 
732  tonic::DartState::Scope scope(this);
733 
734  auto library_handle =
735  library_name.has_value() && !library_name.value().empty()
736  ? ::Dart_LookupLibrary(tonic::ToDart(library_name.value().c_str()))
737  : ::Dart_RootLibrary();
738  auto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()
739  ? tonic::ToDart(entrypoint.value().c_str())
740  : tonic::ToDart("main");
741 
743 
744  auto user_entrypoint_function =
745  ::Dart_GetField(library_handle, entrypoint_handle);
746 
747  auto entrypoint_args = tonic::ToDart(args);
748 
749  if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
750  return false;
751  }
752 
753  phase_ = Phase::Running;
754 
755  return true;
756 }
757 
759  TRACE_EVENT0("flutter", "DartIsolate::Shutdown");
760  // This call may be re-entrant since Dart_ShutdownIsolate can invoke the
761  // cleanup callback which deletes the embedder side object of the dart isolate
762  // (a.k.a. this).
763  if (phase_ == Phase::Shutdown) {
764  return false;
765  }
766  phase_ = Phase::Shutdown;
767  Dart_Isolate vm_isolate = isolate();
768  // The isolate can be nullptr if this instance is the stub isolate data used
769  // during root isolate creation.
770  if (vm_isolate != nullptr) {
771  // We need to enter the isolate because Dart_ShutdownIsolate does not take
772  // the isolate to shutdown as a parameter.
773  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
774  Dart_EnterIsolate(vm_isolate);
775  Dart_ShutdownIsolate();
776  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
777  }
778  return true;
779 }
780 
781 Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
782  const char* package_root,
783  const char* package_config,
784  Dart_IsolateFlags* flags,
785  char** error) {
786  auto vm_data = DartVMRef::GetVMData();
787 
788  if (!vm_data) {
789  *error = fml::strdup(
790  "Could not access VM data to initialize isolates. This may be because "
791  "the VM has initialized shutdown on another thread already.");
792  return nullptr;
793  }
794 
795  const auto& settings = vm_data->GetSettings();
796 
797  if (!settings.enable_observatory) {
798  return nullptr;
799  }
800 
801  flags->load_vmservice_library = true;
802 
803 #if (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG)
804  // TODO(68663): The service isolate in debug mode is always launched without
805  // sound null safety. Fix after the isolate snapshot data is created with the
806  // right flags.
807  flags->null_safety = vm_data->GetServiceIsolateSnapshotNullSafety();
808 #endif
809 
810  UIDartState::Context context(
811  TaskRunners("io.flutter." DART_VM_SERVICE_ISOLATE_NAME, nullptr, nullptr,
812  nullptr, nullptr));
813  context.advisory_script_uri = DART_VM_SERVICE_ISOLATE_NAME;
814  context.advisory_script_entrypoint = DART_VM_SERVICE_ISOLATE_NAME;
815  std::weak_ptr<DartIsolate> weak_service_isolate =
816  DartIsolate::CreateRootIsolate(vm_data->GetSettings(), //
817  vm_data->GetServiceIsolateSnapshot(), //
818  nullptr, //
819  DartIsolate::Flags{flags}, //
820  nullptr, //
821  nullptr, //
822  context); //
823 
824  std::shared_ptr<DartIsolate> service_isolate = weak_service_isolate.lock();
825  if (!service_isolate) {
826  *error = fml::strdup("Could not create the service isolate.");
827  FML_DLOG(ERROR) << *error;
828  return nullptr;
829  }
830 
831  tonic::DartState::Scope scope(service_isolate);
833  settings.observatory_host, // server IP address
834  settings.observatory_port, // server observatory port
835  tonic::DartState::HandleLibraryTag, // embedder library tag handler
836  false, // disable websocket origin check
837  settings.disable_service_auth_codes, // disable VM service auth codes
838  settings.enable_service_port_fallback, // enable fallback to port 0
839  // when bind fails.
840  error // error (out)
841  )) {
842  // Error is populated by call to startup.
843  FML_DLOG(ERROR) << *error;
844  return nullptr;
845  }
846 
847  if (auto callback = vm_data->GetSettings().service_isolate_create_callback) {
848  callback();
849  }
850 
851  if (auto service_protocol = DartVMRef::GetServiceProtocol()) {
852  service_protocol->ToggleHooks(true);
853  } else {
854  FML_DLOG(ERROR)
855  << "Could not acquire the service protocol handlers. This might be "
856  "because the VM has already begun teardown on another thread.";
857  }
858 
859  return service_isolate->isolate();
860 }
861 
862 DartIsolateGroupData& DartIsolate::GetIsolateGroupData() {
863  std::shared_ptr<DartIsolateGroupData>* isolate_group_data =
864  static_cast<std::shared_ptr<DartIsolateGroupData>*>(
865  Dart_IsolateGroupData(isolate()));
866  return **isolate_group_data;
867 }
868 
869 const DartIsolateGroupData& DartIsolate::GetIsolateGroupData() const {
870  DartIsolate* non_const_this = const_cast<DartIsolate*>(this);
871  return non_const_this->GetIsolateGroupData();
872 }
873 
874 // |Dart_IsolateGroupCreateCallback|
875 Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
876  const char* advisory_script_uri,
877  const char* advisory_script_entrypoint,
878  const char* package_root,
879  const char* package_config,
880  Dart_IsolateFlags* flags,
881  std::shared_ptr<DartIsolate>* parent_isolate_data,
882  char** error) {
883  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateGroupCreateCallback");
884  if (parent_isolate_data == nullptr &&
885  strcmp(advisory_script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
886  // The VM attempts to start the VM service for us on |Dart_Initialize|. In
887  // such a case, the callback data will be null and the script URI will be
888  // DART_VM_SERVICE_ISOLATE_NAME. In such cases, we just create the service
889  // isolate like normal but dont hold a reference to it at all. We also start
890  // this isolate since we will never again reference it from the engine.
891  return DartCreateAndStartServiceIsolate(package_root, //
892  package_config, //
893  flags, //
894  error //
895  );
896  }
897 
898  if (!parent_isolate_data) {
899  return nullptr;
900  }
901 
902  DartIsolateGroupData& parent_group_data =
903  (*parent_isolate_data)->GetIsolateGroupData();
904 
905  if (strncmp(advisory_script_uri, kFileUriPrefix.data(),
906  kFileUriPrefix.size())) {
907  std::string error_msg =
908  std::string("Unsupported isolate URI: ") + advisory_script_uri;
909  *error = fml::strdup(error_msg.c_str());
910  return nullptr;
911  }
912 
913  auto isolate_group_data =
914  std::make_unique<std::shared_ptr<DartIsolateGroupData>>(
915  std::shared_ptr<DartIsolateGroupData>(new DartIsolateGroupData(
916  parent_group_data.GetSettings(),
917  parent_group_data.GetIsolateSnapshot(), advisory_script_uri,
918  advisory_script_entrypoint,
919  parent_group_data.GetChildIsolatePreparer(),
920  parent_group_data.GetIsolateCreateCallback(),
921  parent_group_data.GetIsolateShutdownCallback())));
922 
923  TaskRunners null_task_runners(advisory_script_uri,
924  /* platform= */ nullptr,
925  /* raster= */ nullptr,
926  /* ui= */ nullptr,
927  /* io= */ nullptr);
928 
929  UIDartState::Context context(null_task_runners);
930  context.advisory_script_uri = advisory_script_uri;
931  context.advisory_script_entrypoint = advisory_script_entrypoint;
932  auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
933  std::shared_ptr<DartIsolate>(
934  new DartIsolate((*isolate_group_data)->GetSettings(), // settings
935  false, // is_root_isolate
936  context))); // context
937 
938  Dart_Isolate vm_isolate = CreateDartIsolateGroup(
939  std::move(isolate_group_data), std::move(isolate_data), flags, error,
940  [](std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
941  std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
942  char** error) {
943  return Dart_CreateIsolateGroup(
944  (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
945  (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
946  (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
947  (*isolate_group_data)
948  ->GetIsolateSnapshot()
949  ->GetInstructionsMapping(),
950  flags, isolate_group_data, isolate_data, error);
951  });
952 
953  if (*error) {
954  FML_LOG(ERROR) << "CreateDartIsolateGroup failed: " << error;
955  }
956 
957  return vm_isolate;
958 }
959 
960 // |Dart_IsolateInitializeCallback|
961 bool DartIsolate::DartIsolateInitializeCallback(void** child_callback_data,
962  char** error) {
963  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateInitializeCallback");
964  Dart_Isolate isolate = Dart_CurrentIsolate();
965  if (isolate == nullptr) {
966  *error = fml::strdup("Isolate should be available in initialize callback.");
967  FML_DLOG(ERROR) << *error;
968  return false;
969  }
970 
971  auto* isolate_group_data =
972  static_cast<std::shared_ptr<DartIsolateGroupData>*>(
973  Dart_CurrentIsolateGroupData());
974 
975  TaskRunners null_task_runners((*isolate_group_data)->GetAdvisoryScriptURI(),
976  /* platform= */ nullptr,
977  /* raster= */ nullptr,
978  /* ui= */ nullptr,
979  /* io= */ nullptr);
980 
981  UIDartState::Context context(null_task_runners);
982  context.advisory_script_uri = (*isolate_group_data)->GetAdvisoryScriptURI();
983  context.advisory_script_entrypoint =
984  (*isolate_group_data)->GetAdvisoryScriptEntrypoint();
985  auto embedder_isolate = std::make_unique<std::shared_ptr<DartIsolate>>(
986  std::shared_ptr<DartIsolate>(
987  new DartIsolate((*isolate_group_data)->GetSettings(), // settings
988  false, // is_root_isolate
989  context))); // context
990 
991  // root isolate should have been created via CreateRootIsolate
992  if (!InitializeIsolate(*embedder_isolate, isolate, error)) {
993  return false;
994  }
995 
996  // The ownership of the embedder object is controlled by the Dart VM. So the
997  // only reference returned to the caller is weak.
998  *child_callback_data = embedder_isolate.release();
999 
1000  Dart_EnterIsolate(isolate);
1001  return true;
1002 }
1003 
1004 Dart_Isolate DartIsolate::CreateDartIsolateGroup(
1005  std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
1006  std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
1007  Dart_IsolateFlags* flags,
1008  char** error,
1009  const DartIsolate::IsolateMaker& make_isolate) {
1010  TRACE_EVENT0("flutter", "DartIsolate::CreateDartIsolateGroup");
1011 
1012  // Create the Dart VM isolate and give it the embedder object as the baton.
1013  Dart_Isolate isolate =
1014  make_isolate(isolate_group_data.get(), isolate_data.get(), flags, error);
1015 
1016  if (isolate == nullptr) {
1017  return nullptr;
1018  }
1019 
1020  // Ownership of the isolate data objects has been transferred to the Dart VM.
1021  std::shared_ptr<DartIsolate> embedder_isolate(*isolate_data);
1022  isolate_group_data.release();
1023  isolate_data.release();
1024 
1025  if (!InitializeIsolate(std::move(embedder_isolate), isolate, error)) {
1026  return nullptr;
1027  }
1028 
1029  return isolate;
1030 }
1031 
1032 bool DartIsolate::InitializeIsolate(
1033  std::shared_ptr<DartIsolate> embedder_isolate,
1034  Dart_Isolate isolate,
1035  char** error) {
1036  TRACE_EVENT0("flutter", "DartIsolate::InitializeIsolate");
1037  if (!embedder_isolate->Initialize(isolate)) {
1038  *error = fml::strdup("Embedder could not initialize the Dart isolate.");
1039  FML_DLOG(ERROR) << *error;
1040  return false;
1041  }
1042 
1043  if (!embedder_isolate->LoadLibraries()) {
1044  *error = fml::strdup(
1045  "Embedder could not load libraries in the new Dart isolate.");
1046  FML_DLOG(ERROR) << *error;
1047  return false;
1048  }
1049 
1050  // Root isolates will be set up by the engine and the service isolate
1051  // (which is also a root isolate) by the utility routines in the VM.
1052  // However, secondary isolates will be run by the VM if they are
1053  // marked as runnable.
1054  if (!embedder_isolate->IsRootIsolate()) {
1055  auto child_isolate_preparer =
1056  embedder_isolate->GetIsolateGroupData().GetChildIsolatePreparer();
1057  FML_DCHECK(child_isolate_preparer);
1058  if (!child_isolate_preparer(embedder_isolate.get())) {
1059  *error = fml::strdup("Could not prepare the child isolate to run.");
1060  FML_DLOG(ERROR) << *error;
1061  return false;
1062  }
1063  }
1064 
1065  return true;
1066 }
1067 
1068 // |Dart_IsolateShutdownCallback|
1069 void DartIsolate::DartIsolateShutdownCallback(
1070  std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1071  std::shared_ptr<DartIsolate>* isolate_data) {
1072  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateShutdownCallback");
1073  isolate_data->get()->OnShutdownCallback();
1074 }
1075 
1076 // |Dart_IsolateGroupCleanupCallback|
1077 void DartIsolate::DartIsolateGroupCleanupCallback(
1078  std::shared_ptr<DartIsolateGroupData>* isolate_data) {
1079  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateGroupCleanupCallback");
1080  delete isolate_data;
1081 }
1082 
1083 // |Dart_IsolateCleanupCallback|
1084 void DartIsolate::DartIsolateCleanupCallback(
1085  std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1086  std::shared_ptr<DartIsolate>* isolate_data) {
1087  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateCleanupCallback");
1088  delete isolate_data;
1089 }
1090 
1091 std::weak_ptr<DartIsolate> DartIsolate::GetWeakIsolatePtr() {
1092  return std::static_pointer_cast<DartIsolate>(shared_from_this());
1093 }
1094 
1096  shutdown_callbacks_.emplace_back(std::make_unique<AutoFireClosure>(closure));
1097 }
1098 
1099 void DartIsolate::OnShutdownCallback() {
1101  if (state != nullptr) {
1102  state->SetIsShuttingDown();
1103  }
1104 
1105  {
1106  tonic::DartApiScope api_scope;
1107  Dart_Handle sticky_error = Dart_GetStickyError();
1108  if (!Dart_IsNull(sticky_error) && !Dart_IsFatalError(sticky_error)) {
1109  FML_LOG(ERROR) << Dart_GetError(sticky_error);
1110  }
1111  }
1112 
1113  shutdown_callbacks_.clear();
1114 
1115  const fml::closure& isolate_shutdown_callback =
1116  GetIsolateGroupData().GetIsolateShutdownCallback();
1117  if (isolate_shutdown_callback) {
1118  isolate_shutdown_callback();
1119  }
1120 }
1121 
1122 Dart_Handle DartIsolate::OnDartLoadLibrary(intptr_t loading_unit_id) {
1123  if (Current()->platform_configuration()) {
1125  loading_unit_id);
1126  return Dart_Null();
1127  }
1128  const std::string error_message =
1129  "Platform Configuration was null. Deferred library load request"
1130  "for loading unit id " +
1131  std::to_string(loading_unit_id) + " was not sent.";
1132  FML_LOG(ERROR) << error_message;
1133  return Dart_NewApiError(error_message.c_str());
1134 }
1135 
1136 DartIsolate::AutoFireClosure::AutoFireClosure(const fml::closure& closure)
1137  : closure_(closure) {}
1138 
1139 DartIsolate::AutoFireClosure::~AutoFireClosure() {
1140  if (closure_) {
1141  closure_();
1142  }
1143 }
1144 
1145 } // namespace flutter
PlatformConfigurationClient * client() const
Access to the platform configuration client (which typically is implemented by the RuntimeController)...
G_BEGIN_DECLS FlValue * args
ChildIsolatePreparer GetChildIsolatePreparer() const
Phase GetPhase() const
The current phase of the isolate. The engine represents all dart isolates as being in one of the know...
Dart_IsolateFlags Get() const
Definition: dart_isolate.cc:80
void SetIsolate(Dart_Isolate isolate)
Definition: dart_state.cc:35
const fml::closure & GetIsolateShutdownCallback() const
virtual TaskQueueId GetTaskQueueId()
Definition: task_runner.cc:38
void add_provider(const std::string &library_name, std::unique_ptr< DartClassProvider > provider)
static bool Startup(std::string server_ip, intptr_t server_port, Dart_LibraryTagHandler embedder_tag_handler, bool disable_origin_check, bool disable_service_auth_codes, bool enable_service_port_fallback, char **error)
Start the service isolate. This call may only be made in the Dart VM initiated isolate creation callb...
LogMessageCallback log_message_callback
Definition: settings.h:248
Dart_Isolate isolate()
Definition: dart_state.h:51
bool RunFromLibrary(std::optional< std::string > library_name, std::optional< std::string > entrypoint, const std::vector< std::string > &args)
Transition the root isolate to the Phase::Running phase and invoke the main entrypoint (the "main" me...
const uint8_t uint32_t uint32_t GError ** error
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
#define FML_DCHECK(condition)
Definition: logging.h:86
Phase
The engine represents all dart isolates as being in one of the known phases. By invoking various meth...
Definition: dart_isolate.h:93
std::function< void(const DartIsolate &)> root_isolate_create_callback
Definition: settings.h:217
const Settings & GetSettings() const
constexpr char kFileUriPrefix[]
Definition: dart_vm.cc:114
bool enable_skparagraph
Definition: settings.h:190
static std::shared_ptr< ServiceProtocol > GetServiceProtocol()
uint32_t observatory_port
Definition: settings.h:172
static void Install(bool is_ui_isolate, const std::string &script_uri)
Dart_NativeFunction function
Definition: fuchsia.cc:51
static DartState * Current()
Definition: dart_state.cc:56
GAsyncResult * result
bool PrepareForRunningFromKernel(std::shared_ptr< const fml::Mapping > kernel, bool child_isolate, bool last_piece)
Prepare the isolate for running for a a list of kernel files.
static std::shared_ptr< const DartVMData > GetVMData()
#define FML_LOG(severity)
Definition: logging.h:65
static void InitForIsolate()
Definition: dart_ui.cc:90
FlKeyEvent FlKeyResponderAsyncCallback callback
FlutterSemanticsFlag flags
Dart_Handle DartInvokeField(Dart_Handle target, const char *name, std::initializer_list< Dart_Handle > args)
Definition: dart_invoke.cc:12
virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id)=0
Invoked when the Dart VM requests that a deferred library be loaded. Notifies the engine that the def...
void SetNullSafetyEnabled(bool enabled)
Definition: dart_isolate.cc:72
UnhandledExceptionCallback unhandled_exception_callback
Definition: settings.h:243
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32
std::function< void()> closure
Definition: closure.h:14
void AddIsolateShutdownCallback(const fml::closure &closure)
Registers a callback that will be invoked in isolate scope just before the isolate transitions to the...
fml::closure root_isolate_shutdown_callback
Definition: settings.h:223
bool IsRootIsolate() const
Definition: ui_dart_state.h:96
uint8_t value
static fml::RefPtr< MessageLoopTaskQueues > GetInstance()
std::string domain_network_policy
Definition: settings.h:147
static void InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle)
static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url)
Definition: dart_state.cc:79
DartClassLibrary & class_library()
Definition: dart_state.h:60
Represents an instance of a live isolate. An isolate is a separate Dart execution context...
Definition: dart_isolate.h:62
static std::shared_ptr< IsolateNameServer > GetIsolateNameServer()
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 observatory The hostname IP address on which the Dart Observatory should be served If not defaults to or::depending on whether ipv6 is specified disable Disable the Dart Observatory The observatory is never available in release mode Bind to the IPv6 localhost address for the Dart Observatory Ignored if observatory host is set endless trace buffer
Definition: switches.h:98
bool enable_display_list
Definition: settings.h:193
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
Definition: dart_vm.cc:192
void SetIsDontNeedSafe(bool value)
Definition: dart_isolate.cc:76
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
Definition: ui_dart_state.h:43
PlatformConfiguration * platform_configuration() const
std::string observatory_host
Definition: settings.h:167
TaskObserverAdd task_observer_add
Definition: settings.h:213
static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function, Dart_Handle args)
std::string GetServiceId()
Returns the ID for an isolate which is used to query the service protocol.
std::string advisory_script_entrypoint
Definition: ui_dart_state.h:88
bool disable_service_auth_codes
Definition: settings.h:176
bool LoadLoadingUnit(intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)
const std::string & GetAdvisoryScriptURI() const
bool enable_observatory
Definition: settings.h:159
UIDartState(TaskObserverAdd add_callback, TaskObserverRemove remove_callback, std::string logger_prefix, UnhandledExceptionCallback unhandled_exception_callback, LogMessageCallback log_message_callback, std::shared_ptr< IsolateNameServer > isolate_name_server, bool is_root_isolate_, bool enable_skparagraph, bool enable_display_list, const UIDartState::Context &context)
void Initialize(TaskDispatcher dispatcher)
const fml::closure & GetIsolateCreateCallback() const
bool may_insecurely_connect_to_all_domains
Definition: settings.h:145
const TaskRunners & GetTaskRunners() const
static void InitForIsolate(bool may_insecurely_connect_to_all_domains, std::string domain_network_policy)
Definition: dart_io.cc:18
#define FML_DLOG(severity)
Definition: logging.h:85
char * strdup(const char *str1)
fml::RefPtr< fml::TaskRunner > GetMessageHandlingTaskRunner() const
The task runner on which the Dart code for the root isolate is running. For the root isolate...
Dart_Handle ToDart(const T &object)
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
TaskObserverRemove task_observer_remove
Definition: settings.h:214
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27
bool Shutdown()
Transition the isolate to the Phase::Shutdown phase. The only thing left to do is to collect the isol...
bool PrepareForRunningFromKernels(std::vector< std::shared_ptr< const fml::Mapping >> kernels)
Prepare the isolate for running for a a list of kernel files.
std::weak_ptr< DartIsolate > GetWeakIsolatePtr()
A weak pointer to the Dart isolate instance. This instance may only be used on the task runner that c...
void SetIsShuttingDown()
Definition: dart_state.h:73
DartMessageHandler & message_handler()
Definition: dart_state.h:61
virtual void PostTask(const fml::closure &task) override
Definition: task_runner.cc:24
AtkStateType state
std::string log_tag
Definition: settings.h:252
bool PrepareForRunningFromPrecompiledCode()
Prepare the isolate for running for a precompiled code bundle. The Dart VM must be configured for run...
static TimePoint Now()
Definition: time_point.cc:39
static fml::RefPtr< DartSnapshot > IsolateSnapshotFromMappings(std::shared_ptr< const fml::Mapping > snapshot_data, std::shared_ptr< const fml::Mapping > snapshot_instructions)
Create an isolate snapshot from existing fml::Mappings.
void LoadLoadingUnitError(intptr_t loading_unit_id, const std::string error_message, bool transient)
static UIDartState * Current()
bool enable_service_port_fallback
Definition: settings.h:180
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, fml::RefPtr< const DartSnapshot > isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, Flags flags, fml::closure root_isolate_create_callback, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, const std::vector< std::string > &dart_entrypoint_args, std::unique_ptr< IsolateConfiguration > isolate_configuration, const UIDartState::Context &context, const DartIsolate *spawning_isolate=nullptr)
Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance ma...
Definition: dart_isolate.cc:84
fml::RefPtr< const DartSnapshot > GetIsolateSnapshot() const