Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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#include <utility>
10
11#include "flutter/fml/logging.h"
12#include "flutter/fml/posix_wrappers.h"
13#include "flutter/fml/trace_event.h"
14#include "flutter/lib/io/dart_io.h"
15#include "flutter/lib/ui/dart_runtime_hooks.h"
16#include "flutter/lib/ui/dart_ui.h"
17#include "flutter/lib/ui/window/platform_isolate.h"
18#include "flutter/runtime/dart_isolate_group_data.h"
19#include "flutter/runtime/dart_plugin_registrant.h"
20#include "flutter/runtime/dart_service_isolate.h"
21#include "flutter/runtime/dart_vm.h"
22#include "flutter/runtime/dart_vm_lifecycle.h"
23#include "flutter/runtime/isolate_configuration.h"
24#include "flutter/runtime/runtime_controller.h"
26#include "fml/task_source.h"
27#include "fml/time/time_point.h"
28#include "third_party/dart/runtime/include/dart_api.h"
29#include "third_party/dart/runtime/include/dart_tools_api.h"
39
40namespace flutter {
41
42namespace {
43
44constexpr std::string_view kFileUriPrefix = "file://";
45
46class DartErrorString {
47 public:
48 DartErrorString() {}
49 ~DartErrorString() {
50 if (str_) {
51 ::free(str_);
52 }
53 }
54 char** error() { return &str_; }
55 const char* str() const { return str_; }
56 explicit operator bool() const { return str_ != nullptr; }
57
58 private:
59 FML_DISALLOW_COPY_AND_ASSIGN(DartErrorString);
60 char* str_ = nullptr;
61};
62
63} // anonymous namespace
64
65DartIsolate::Flags::Flags() : Flags(nullptr) {}
66
67DartIsolate::Flags::Flags(const Dart_IsolateFlags* flags) {
68 if (flags) {
69 flags_ = *flags;
70 } else {
72 }
73}
74
75DartIsolate::Flags::~Flags() = default;
76
77void DartIsolate::Flags::SetNullSafetyEnabled(bool enabled) {
78 flags_.null_safety = enabled;
79}
80
81void DartIsolate::Flags::SetIsDontNeedSafe(bool value) {
82 flags_.snapshot_is_dontneed_safe = value;
83}
84
85Dart_IsolateFlags DartIsolate::Flags::Get() const {
86 return flags_;
87}
88
89std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
90 const Settings& settings,
91 const fml::RefPtr<const DartSnapshot>& isolate_snapshot,
92 std::unique_ptr<PlatformConfiguration> platform_configuration,
93 Flags isolate_flags,
94 const fml::closure& root_isolate_create_callback,
95 const fml::closure& isolate_create_callback,
96 const fml::closure& isolate_shutdown_callback,
97 std::optional<std::string> dart_entrypoint,
98 std::optional<std::string> dart_entrypoint_library,
99 const std::vector<std::string>& dart_entrypoint_args,
100 std::unique_ptr<IsolateConfiguration> isolate_configuration,
101 const UIDartState::Context& context,
102 const DartIsolate* spawning_isolate) {
103 if (!isolate_snapshot) {
104 FML_LOG(ERROR) << "Invalid isolate snapshot.";
105 return {};
106 }
107
108 if (!isolate_configuration) {
109 FML_LOG(ERROR) << "Invalid isolate configuration.";
110 return {};
111 }
112
113 isolate_flags.SetNullSafetyEnabled(
114 isolate_configuration->IsNullSafetyEnabled(*isolate_snapshot));
115 isolate_flags.SetIsDontNeedSafe(isolate_snapshot->IsDontNeedSafe());
116
117 auto isolate = CreateRootIsolate(settings, //
118 isolate_snapshot, //
119 std::move(platform_configuration), //
120 isolate_flags, //
121 isolate_create_callback, //
122 isolate_shutdown_callback, //
123 context, //
124 spawning_isolate //
125 )
126 .lock();
127
128 if (!isolate) {
129 FML_LOG(ERROR) << "Could not create root isolate.";
130 return {};
131 }
132
133 fml::ScopedCleanupClosure shutdown_on_error([isolate]() {
134 if (!isolate->Shutdown()) {
135 FML_DLOG(ERROR) << "Could not shutdown transient isolate.";
136 }
137 });
138
139 if (isolate->GetPhase() != DartIsolate::Phase::LibrariesSetup) {
140 FML_LOG(ERROR) << "Root isolate was created in an incorrect phase: "
141 << static_cast<int>(isolate->GetPhase());
142 return {};
143 }
144
145 if (!isolate_configuration->PrepareIsolate(*isolate.get())) {
146 FML_LOG(ERROR) << "Could not prepare isolate.";
147 return {};
148 }
149
150 if (isolate->GetPhase() != DartIsolate::Phase::Ready) {
151 FML_LOG(ERROR) << "Root isolate not in the ready phase for Dart entrypoint "
152 "invocation.";
153 return {};
154 }
155
156 if (settings.root_isolate_create_callback) {
157 // Isolate callbacks always occur in isolate scope and before user code has
158 // had a chance to run.
159 tonic::DartState::Scope scope(isolate.get());
160 settings.root_isolate_create_callback(*isolate.get());
161 }
162
163 if (root_isolate_create_callback) {
164 root_isolate_create_callback();
165 }
166
167 if (!isolate->RunFromLibrary(std::move(dart_entrypoint_library), //
168 std::move(dart_entrypoint), //
169 dart_entrypoint_args)) {
170 FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
171 return {};
172 }
173
174 if (settings.root_isolate_shutdown_callback) {
175 isolate->AddIsolateShutdownCallback(
176 settings.root_isolate_shutdown_callback);
177 }
178
179 shutdown_on_error.Release();
180
181 return isolate;
182}
183
184void DartIsolate::SpawnIsolateShutdownCallback(
185 std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
186 std::shared_ptr<DartIsolate>* isolate_data) {
187 DartIsolate::DartIsolateShutdownCallback(isolate_group_data, isolate_data);
188}
189
190std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
191 const Settings& settings,
192 fml::RefPtr<const DartSnapshot> isolate_snapshot,
193 std::unique_ptr<PlatformConfiguration> platform_configuration,
194 const Flags& flags,
195 const fml::closure& isolate_create_callback,
196 const fml::closure& isolate_shutdown_callback,
197 const UIDartState::Context& context,
198 const DartIsolate* spawning_isolate) {
199 TRACE_EVENT0("flutter", "DartIsolate::CreateRootIsolate");
200
201 // Only needed if this is the main isolate for the group.
202 std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data;
203
204 auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
205 std::shared_ptr<DartIsolate>(new DartIsolate(
206 /*settings=*/settings,
207 /*is_root_isolate=*/true,
208 /*context=*/context,
209 /*is_spawning_in_group=*/!!spawning_isolate)));
210
211 DartErrorString error;
212 Dart_Isolate vm_isolate = nullptr;
213 auto isolate_flags = flags.Get();
214
215 IsolateMaker isolate_maker;
216 if (spawning_isolate) {
217 isolate_maker =
218 [spawning_isolate](
219 std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
220 std::shared_ptr<DartIsolate>* isolate_data,
221 Dart_IsolateFlags* flags, char** error) {
223 /*group_member=*/spawning_isolate->isolate(),
224 /*name=*/
225 spawning_isolate->GetIsolateGroupData()
226 .GetAdvisoryScriptEntrypoint()
227 .c_str(),
228 /*shutdown_callback=*/
229 reinterpret_cast<Dart_IsolateShutdownCallback>(
230 DartIsolate::SpawnIsolateShutdownCallback),
231 /*cleanup_callback=*/
232 reinterpret_cast<Dart_IsolateCleanupCallback>(
233 DartIsolateCleanupCallback),
234 /*child_isolate_data=*/isolate_data,
235 /*error=*/error);
236 };
237 } else {
238 // The child isolate preparer is null but will be set when the isolate is
239 // being prepared to run.
240 isolate_group_data =
241 std::make_unique<std::shared_ptr<DartIsolateGroupData>>(
242 std::shared_ptr<DartIsolateGroupData>(new DartIsolateGroupData(
243 settings, // settings
244 std::move(isolate_snapshot), // isolate snapshot
245 context.advisory_script_uri, // advisory URI
246 context.advisory_script_entrypoint, // advisory entrypoint
247 nullptr, // child isolate preparer
248 isolate_create_callback, // isolate create callback
249 isolate_shutdown_callback // isolate shutdown callback
250 )));
251 isolate_maker = [](std::shared_ptr<DartIsolateGroupData>*
252 isolate_group_data,
253 std::shared_ptr<DartIsolate>* isolate_data,
254 Dart_IsolateFlags* flags, char** error) {
256 (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
257 (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
258 (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
259 (*isolate_group_data)->GetIsolateSnapshot()->GetInstructionsMapping(),
260 flags, isolate_group_data, isolate_data, error);
261 };
262 }
263
264 vm_isolate = CreateDartIsolateGroup(std::move(isolate_group_data),
265 std::move(isolate_data), &isolate_flags,
266 error.error(), isolate_maker);
267
268 if (error) {
269 FML_LOG(ERROR) << "CreateRootIsolate failed: " << error.str();
270 }
271
272 if (vm_isolate == nullptr) {
273 return {};
274 }
275
276 std::shared_ptr<DartIsolate>* root_isolate_data =
277 static_cast<std::shared_ptr<DartIsolate>*>(Dart_IsolateData(vm_isolate));
278
279 (*root_isolate_data)
280 ->SetPlatformConfiguration(std::move(platform_configuration));
281
282 return (*root_isolate_data)->GetWeakIsolatePtr();
283}
284
286 char** error) {
287 *error = nullptr;
289 FML_DCHECK(platform_config != nullptr);
290 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
291 platform_config->client()->GetPlatformIsolateManager();
292 std::weak_ptr<PlatformIsolateManager> weak_platform_isolate_manager =
293 platform_isolate_manager;
294 if (platform_isolate_manager->HasShutdownMaybeFalseNegative()) {
295 // Don't set the error string. We want to silently ignore this error,
296 // because the engine is shutting down.
297 FML_LOG(INFO) << "CreatePlatformIsolate called after shutdown";
298 return nullptr;
299 }
300
301 Dart_Isolate parent_isolate = isolate();
302 Dart_ExitIsolate(); // Exit parent_isolate.
303
304 const TaskRunners& task_runners = GetTaskRunners();
305 fml::RefPtr<fml::TaskRunner> platform_task_runner =
306 task_runners.GetPlatformTaskRunner();
307 FML_DCHECK(platform_task_runner);
308
309 auto isolate_group_data = std::shared_ptr<DartIsolateGroupData>(
310 *static_cast<std::shared_ptr<DartIsolateGroupData>*>(
311 Dart_IsolateGroupData(parent_isolate)));
312
313 Settings settings(isolate_group_data->GetSettings());
314
315 // PlatformIsolate.spawn should behave like Isolate.spawn when unhandled
316 // exceptions happen (log the exception, but don't terminate the app). But the
317 // default unhandled_exception_callback may terminate the app, because it is
318 // only called for the root isolate (child isolates are managed by the VM and
319 // have a different error code path). So override it to simply log the error.
320 settings.unhandled_exception_callback = [](const std::string& error,
321 const std::string& stack_trace) {
322 FML_LOG(ERROR) << "Unhandled exception:\n" << error << "\n" << stack_trace;
323 return true;
324 };
325
326 // The platform isolate task observer must be added on the platform thread. So
327 // schedule the add function on the platform task runner.
328 TaskObserverAdd old_task_observer_add = settings.task_observer_add;
329 settings.task_observer_add = [old_task_observer_add, platform_task_runner,
330 weak_platform_isolate_manager](
331 intptr_t key, const fml::closure& callback) {
332 platform_task_runner->PostTask([old_task_observer_add,
333 weak_platform_isolate_manager, key,
334 callback]() {
335 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
336 weak_platform_isolate_manager.lock();
337 if (platform_isolate_manager == nullptr ||
338 platform_isolate_manager->HasShutdown()) {
339 // Shutdown happened in between this task being posted, and it running.
340 // platform_isolate has already been shut down. Do nothing.
341 FML_LOG(INFO) << "Shutdown before platform isolate task observer added";
342 return;
343 }
344 old_task_observer_add(key, callback);
345 });
346 };
347
348 UIDartState::Context context(task_runners);
349 context.advisory_script_uri = isolate_group_data->GetAdvisoryScriptURI();
351 isolate_group_data->GetAdvisoryScriptEntrypoint();
352 auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
353 std::shared_ptr<DartIsolate>(
354 new DartIsolate(settings, context, platform_isolate_manager)));
355
356 IsolateMaker isolate_maker =
357 [parent_isolate](
358 std::shared_ptr<DartIsolateGroupData>* unused_isolate_group_data,
359 std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
360 char** error) {
362 /*group_member=*/parent_isolate,
363 /*name=*/"PlatformIsolate",
364 /*shutdown_callback=*/
365 reinterpret_cast<Dart_IsolateShutdownCallback>(
366 DartIsolate::SpawnIsolateShutdownCallback),
367 /*cleanup_callback=*/
368 reinterpret_cast<Dart_IsolateCleanupCallback>(
369 DartIsolateCleanupCallback),
370 /*child_isolate_data=*/isolate_data,
371 /*error=*/error);
372 };
373 Dart_Isolate platform_isolate = CreateDartIsolateGroup(
374 nullptr, std::move(isolate_data), nullptr, error, isolate_maker);
375
376 Dart_EnterIsolate(parent_isolate);
377
378 if (*error) {
379 return nullptr;
380 }
381
382 if (!platform_isolate_manager->RegisterPlatformIsolate(platform_isolate)) {
383 // The PlatformIsolateManager was shutdown while we were creating the
384 // isolate. This means that we're shutting down the engine. We need to
385 // shutdown the platform isolate.
386 FML_LOG(INFO) << "Shutdown during platform isolate creation";
387 tonic::DartIsolateScope isolate_scope(platform_isolate);
389 return nullptr;
390 }
391
392 tonic::DartApiScope api_scope;
393 Dart_PersistentHandle entry_point_handle =
394 Dart_NewPersistentHandle(entry_point);
395
396 platform_task_runner->PostTask([entry_point_handle, platform_isolate,
397 weak_platform_isolate_manager]() {
398 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
399 weak_platform_isolate_manager.lock();
400 if (platform_isolate_manager == nullptr ||
401 platform_isolate_manager->HasShutdown()) {
402 // Shutdown happened in between this task being posted, and it running.
403 // platform_isolate has already been shut down. Do nothing.
404 FML_LOG(INFO) << "Shutdown before platform isolate entry point";
405 return;
406 }
407
408 tonic::DartIsolateScope isolate_scope(platform_isolate);
409 tonic::DartApiScope api_scope;
410 Dart_Handle entry_point = Dart_HandleFromPersistent(entry_point_handle);
411 Dart_DeletePersistentHandle(entry_point_handle);
412
413 // Disable Isolate.exit().
414 Dart_Handle isolate_lib = Dart_LookupLibrary(tonic::ToDart("dart:isolate"));
417 isolate_lib, tonic::ToDart("Isolate"), 0, nullptr);
420 Dart_SetField(isolate_type, tonic::ToDart("_mayExit"), Dart_False());
422
423 tonic::DartInvokeVoid(entry_point);
424 });
425
426 return platform_isolate;
427}
428
429DartIsolate::DartIsolate(const Settings& settings,
430 bool is_root_isolate,
431 const UIDartState::Context& context,
432 bool is_spawning_in_group)
433 : UIDartState(settings.task_observer_add,
434 settings.task_observer_remove,
435 settings.log_tag,
437 settings.log_message_callback,
439 is_root_isolate,
440 context),
441 may_insecurely_connect_to_all_domains_(
442 settings.may_insecurely_connect_to_all_domains),
443 is_platform_isolate_(false),
444 is_spawning_in_group_(is_spawning_in_group),
445 domain_network_policy_(settings.domain_network_policy) {
446 phase_ = Phase::Uninitialized;
447}
448
449DartIsolate::DartIsolate(
450 const Settings& settings,
451 const UIDartState::Context& context,
452 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager)
453 : UIDartState(settings.task_observer_add,
454 settings.task_observer_remove,
455 settings.log_tag,
456 settings.unhandled_exception_callback,
457 settings.log_message_callback,
458 DartVMRef::GetIsolateNameServer(),
459 false, // is_root_isolate
460 context),
461 may_insecurely_connect_to_all_domains_(
462 settings.may_insecurely_connect_to_all_domains),
463 is_platform_isolate_(true),
464 is_spawning_in_group_(false),
465 domain_network_policy_(settings.domain_network_policy),
466 platform_isolate_manager_(std::move(platform_isolate_manager)) {
467 phase_ = Phase::Uninitialized;
468}
469
472 FML_DCHECK(GetMessageHandlingTaskRunner()->RunsTasksOnCurrentThread());
473 }
474}
475
477 return phase_;
478}
479
481 const char* service_id_buf = Dart_IsolateServiceId(isolate());
482 std::string service_id(service_id_buf);
483 free(const_cast<char*>(service_id_buf));
484 return service_id;
485}
486
487bool DartIsolate::Initialize(Dart_Isolate dart_isolate) {
488 TRACE_EVENT0("flutter", "DartIsolate::Initialize");
489 if (phase_ != Phase::Uninitialized) {
490 return false;
491 }
492
493 FML_DCHECK(dart_isolate != nullptr);
494 FML_DCHECK(dart_isolate == Dart_CurrentIsolate());
495
496 // After this point, isolate scopes can be safely used.
497 SetIsolate(dart_isolate);
498
499 // For the root isolate set the "AppStartUp" as soon as the root isolate
500 // has been initialized. This is to ensure that all the timeline events
501 // that have the set user-tag will be listed user AppStartUp.
502 if (IsRootIsolate()) {
503 tonic::DartApiScope api_scope;
505 }
506
507 if (is_platform_isolate_) {
508 SetMessageHandlingTaskRunner(GetTaskRunners().GetPlatformTaskRunner(),
509 true);
510 } else {
511 SetMessageHandlingTaskRunner(GetTaskRunners().GetUITaskRunner(), false);
512 }
513
516 return false;
517 }
518
520 Dart_SetDeferredLoadHandler(OnDartLoadLibrary))) {
521 return false;
522 }
523
524 if (!UpdateThreadPoolNames()) {
525 return false;
526 }
527
528 phase_ = Phase::Initialized;
529 return true;
530}
531
533 return message_handling_task_runner_;
534}
535
537 intptr_t loading_unit_id,
538 std::unique_ptr<const fml::Mapping> snapshot_data,
539 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
540 tonic::DartState::Scope scope(this);
541
542 fml::RefPtr<DartSnapshot> dart_snapshot =
544 std::move(snapshot_data), std::move(snapshot_instructions));
545
547 loading_unit_id, dart_snapshot->GetDataMapping(),
548 dart_snapshot->GetInstructionsMapping());
550 LoadLoadingUnitError(loading_unit_id, Dart_GetError(result),
551 /*transient*/ true);
552 return false;
553 }
554 loading_unit_snapshots_.insert(dart_snapshot);
555 return true;
556}
557
558void DartIsolate::LoadLoadingUnitError(intptr_t loading_unit_id,
559 const std::string& error_message,
560 bool transient) {
561 tonic::DartState::Scope scope(this);
563 loading_unit_id, error_message.c_str(), transient);
565}
566
567void DartIsolate::SetMessageHandlingTaskRunner(
568 const fml::RefPtr<fml::TaskRunner>& runner,
569 bool post_directly_to_runner) {
570 if (!runner) {
571 return;
572 }
573
574 message_handling_task_runner_ = runner;
575
577
578#ifdef OS_FUCHSIA
579 post_directly_to_runner = true;
580#endif
581
582 if (post_directly_to_runner) {
583 dispatcher = [runner](std::function<void()> task) {
584 runner->PostTask([task = std::move(task)]() {
585 TRACE_EVENT0("flutter", "DartIsolate::HandleMessage");
586 task();
587 });
588 };
589 } else {
590 dispatcher = [runner](std::function<void()> task) {
591 auto task_queues = fml::MessageLoopTaskQueues::GetInstance();
592 task_queues->RegisterTask(
593 runner->GetTaskQueueId(),
594 [task = std::move(task)]() {
595 TRACE_EVENT0("flutter", "DartIsolate::HandleMessage");
596 task();
597 },
599 };
600 }
601
602 message_handler().Initialize(dispatcher);
603}
604
605// Updating thread names here does not change the underlying OS thread names.
606// Instead, this is just additional metadata for the Dart VM Service to show the
607// thread name of the isolate.
608bool DartIsolate::UpdateThreadPoolNames() const {
609 // TODO(chinmaygarde): This implementation does not account for multiple
610 // shells sharing the same (or subset of) threads.
611 const auto& task_runners = GetTaskRunners();
612
613 if (auto task_runner = task_runners.GetRasterTaskRunner()) {
614 task_runner->PostTask(
615 [label = task_runners.GetLabel() + std::string{".raster"}]() {
616 Dart_SetThreadName(label.c_str());
617 });
618 }
619
620 if (auto task_runner = task_runners.GetUITaskRunner()) {
621 task_runner->PostTask(
622 [label = task_runners.GetLabel() + std::string{".ui"}]() {
623 Dart_SetThreadName(label.c_str());
624 });
625 }
626
627 if (auto task_runner = task_runners.GetIOTaskRunner()) {
628 task_runner->PostTask(
629 [label = task_runners.GetLabel() + std::string{".io"}]() {
630 Dart_SetThreadName(label.c_str());
631 });
632 }
633
634 if (auto task_runner = task_runners.GetPlatformTaskRunner()) {
635 task_runner->PostTask(
636 [label = task_runners.GetLabel() + std::string{".platform"}]() {
637 Dart_SetThreadName(label.c_str());
638 });
639 }
640
641 return true;
642}
643
644bool DartIsolate::LoadLibraries() {
645 TRACE_EVENT0("flutter", "DartIsolate::LoadLibraries");
646 if (phase_ != Phase::Initialized) {
647 return false;
648 }
649
650 tonic::DartState::Scope scope(this);
651
652 DartIO::InitForIsolate(may_insecurely_connect_to_all_domains_,
653 domain_network_policy_);
654
656
657 const bool is_service_isolate = Dart_IsServiceIsolate(isolate());
658
659 DartRuntimeHooks::Install(IsRootIsolate() && !is_service_isolate,
661
662 if (!is_service_isolate) {
664 "ui", std::make_unique<tonic::DartClassProvider>(this, "dart:ui"));
665 }
666
667 phase_ = Phase::LibrariesSetup;
668 return true;
669}
670
672 TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromPrecompiledCode");
673 if (phase_ != Phase::LibrariesSetup) {
674 return false;
675 }
676
677 tonic::DartState::Scope scope(this);
678
680 return false;
681 }
682
683 if (!MarkIsolateRunnable()) {
684 return false;
685 }
686
687 if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
689 return isolate->PrepareForRunningFromPrecompiledCode();
690 });
691 }
692
693 const fml::closure& isolate_create_callback =
695 if (isolate_create_callback) {
696 isolate_create_callback();
697 }
698
699 phase_ = Phase::Ready;
700 return true;
701}
702
703bool DartIsolate::LoadKernel(const std::shared_ptr<const fml::Mapping>& mapping,
704 bool last_piece) {
705 if (!Dart_IsKernel(mapping->GetMapping(), mapping->GetSize())) {
706 return false;
707 }
708
709 // Mapping must be retained until isolate group shutdown.
711
712 Dart_Handle library =
713 Dart_LoadLibraryFromKernel(mapping->GetMapping(), mapping->GetSize());
714 if (tonic::CheckAndHandleError(library)) {
715 return false;
716 }
717
718 if (!last_piece) {
719 // More to come.
720 return true;
721 }
722
723 Dart_SetRootLibrary(library);
725 return false;
726 }
727 return true;
728}
729
731 const std::shared_ptr<const fml::Mapping>& mapping,
732 bool child_isolate,
733 bool last_piece) {
734 TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromKernel");
735 if (phase_ != Phase::LibrariesSetup) {
736 return false;
737 }
738
740 return false;
741 }
742
743 tonic::DartState::Scope scope(this);
744
745 if (!child_isolate && !is_spawning_in_group_) {
746 if (!mapping || mapping->GetSize() == 0) {
747 return false;
748 }
749
750 // Use root library provided by kernel in favor of one provided by snapshot.
752
753 if (!LoadKernel(mapping, last_piece)) {
754 return false;
755 }
756 }
757
758 if (!last_piece) {
759 // More to come.
760 return true;
761 }
762
764 return false;
765 }
766
767 if (!MarkIsolateRunnable()) {
768 return false;
769 }
770
771 // Child isolate shares root isolate embedder_isolate (lines 691 and 693
772 // below). Re-initializing child_isolate_preparer_ lambda while it is being
773 // executed leads to crashes.
774 if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
776 [buffers =
777 GetIsolateGroupData().GetKernelBuffers()](DartIsolate* isolate) {
778 for (uint64_t i = 0; i < buffers.size(); i++) {
779 bool last_piece = i + 1 == buffers.size();
780 const std::shared_ptr<const fml::Mapping>& buffer = buffers.at(i);
781 if (!isolate->PrepareForRunningFromKernel(buffer,
782 /*child_isolate=*/true,
783 last_piece)) {
784 return false;
785 }
786 }
787 return true;
788 });
789 }
790
791 const fml::closure& isolate_create_callback =
793 if (isolate_create_callback) {
794 isolate_create_callback();
795 }
796
797 phase_ = Phase::Ready;
798
799 return true;
800}
801
803 std::vector<std::shared_ptr<const fml::Mapping>> kernels) {
804 const auto count = kernels.size();
805 if (count == 0) {
806 return false;
807 }
808
809 for (size_t i = 0; i < count; ++i) {
810 bool last = (i == (count - 1));
811 if (!PrepareForRunningFromKernel(kernels[i], /*child_isolate=*/false,
812 last)) {
813 return false;
814 }
815 }
816
817 return true;
818}
819
821 std::vector<std::unique_ptr<const fml::Mapping>> kernels) {
822 std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
823 shared_kernels.reserve(kernels.size());
824 for (auto& kernel : kernels) {
825 shared_kernels.emplace_back(std::move(kernel));
826 }
827 return PrepareForRunningFromKernels(shared_kernels);
828}
829
830bool DartIsolate::MarkIsolateRunnable() {
831 TRACE_EVENT0("flutter", "DartIsolate::MarkIsolateRunnable");
832 if (phase_ != Phase::LibrariesSetup) {
833 return false;
834 }
835
836 // This function may only be called from an active isolate scope.
837 if (Dart_CurrentIsolate() != isolate()) {
838 return false;
839 }
840
841 // There must be no current isolate to mark an isolate as being runnable.
843
845 if (error) {
846 FML_DLOG(ERROR) << error;
847 ::free(error);
848 // Failed. Restore the isolate.
850 return false;
851 }
852 // Success. Restore the isolate.
854 return true;
855}
856
857[[nodiscard]] static bool InvokeMainEntrypoint(
858 Dart_Handle user_entrypoint_function,
860 if (tonic::CheckAndHandleError(user_entrypoint_function)) {
861 FML_LOG(ERROR) << "Could not resolve main entrypoint function.";
862 return false;
863 }
864
865 Dart_Handle start_main_isolate_function =
867 "_getStartMainIsolateFunction", {});
868
869 if (tonic::CheckAndHandleError(start_main_isolate_function)) {
870 FML_LOG(ERROR) << "Could not resolve main entrypoint trampoline.";
871 return false;
872 }
873
875 Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMain",
876 {start_main_isolate_function, user_entrypoint_function, args}))) {
877 FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
878 return false;
879 }
880
881 return true;
882}
883
884bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name,
885 std::optional<std::string> entrypoint,
886 const std::vector<std::string>& args) {
887 TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
888 if (phase_ != Phase::Ready) {
889 return false;
890 }
891
892 tonic::DartState::Scope scope(this);
893
894 auto library_handle =
895 library_name.has_value() && !library_name.value().empty()
896 ? ::Dart_LookupLibrary(tonic::ToDart(library_name.value().c_str()))
898 auto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()
899 ? tonic::ToDart(entrypoint.value().c_str())
900 : tonic::ToDart("main");
901
903 // TODO(gaaclarke): Remove once the framework PR lands that uses `--source`
904 // to compile the Dart Plugin Registrant
905 // (https://github.com/flutter/flutter/pull/100572).
907 }
908
909 auto user_entrypoint_function =
910 ::Dart_GetField(library_handle, entrypoint_handle);
911
912 auto entrypoint_args = tonic::ToDart(args);
913
914 if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
915 return false;
916 }
917
918 phase_ = Phase::Running;
919
920 return true;
921}
922
924 TRACE_EVENT0("flutter", "DartIsolate::Shutdown");
925 // This call may be re-entrant since Dart_ShutdownIsolate can invoke the
926 // cleanup callback which deletes the embedder side object of the dart isolate
927 // (a.k.a. this).
928 if (phase_ == Phase::Shutdown) {
929 return false;
930 }
931 phase_ = Phase::Shutdown;
932 Dart_Isolate vm_isolate = isolate();
933 // The isolate can be nullptr if this instance is the stub isolate data used
934 // during root isolate creation.
935 if (vm_isolate != nullptr) {
936 // We need to enter the isolate because Dart_ShutdownIsolate does not take
937 // the isolate to shutdown as a parameter.
938 FML_DCHECK(Dart_CurrentIsolate() == nullptr);
939 Dart_EnterIsolate(vm_isolate);
941 FML_DCHECK(Dart_CurrentIsolate() == nullptr);
942 }
943 return true;
944}
945
946Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
947 const char* package_root,
948 const char* package_config,
950 char** error) {
951 auto vm_data = DartVMRef::GetVMData();
952
953 if (!vm_data) {
955 "Could not access VM data to initialize isolates. This may be because "
956 "the VM has initialized shutdown on another thread already.");
957 return nullptr;
958 }
959
960 const auto& settings = vm_data->GetSettings();
961
962 if (!settings.enable_vm_service) {
963 return nullptr;
964 }
965
966 flags->load_vmservice_library = true;
967
968#if (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG)
969 // TODO(68663): The service isolate in debug mode is always launched without
970 // sound null safety. Fix after the isolate snapshot data is created with the
971 // right flags.
972 flags->null_safety = vm_data->GetServiceIsolateSnapshotNullSafety();
973#endif
974
975 UIDartState::Context context(
976 TaskRunners("io.flutter." DART_VM_SERVICE_ISOLATE_NAME, nullptr, nullptr,
977 nullptr, nullptr));
978 context.advisory_script_uri = DART_VM_SERVICE_ISOLATE_NAME;
979 context.advisory_script_entrypoint = DART_VM_SERVICE_ISOLATE_NAME;
980 std::weak_ptr<DartIsolate> weak_service_isolate =
981 DartIsolate::CreateRootIsolate(vm_data->GetSettings(), //
982 vm_data->GetServiceIsolateSnapshot(), //
983 nullptr, //
984 DartIsolate::Flags{flags}, //
985 nullptr, //
986 nullptr, //
987 context); //
988
989 std::shared_ptr<DartIsolate> service_isolate = weak_service_isolate.lock();
990 if (!service_isolate) {
991 *error = fml::strdup("Could not create the service isolate.");
992 FML_DLOG(ERROR) << *error;
993 return nullptr;
994 }
995
996 tonic::DartState::Scope scope(service_isolate);
998 settings.vm_service_host, // server IP address
999 settings.vm_service_port, // server VM service port
1000 tonic::DartState::HandleLibraryTag, // embedder library tag handler
1001 false, // disable websocket origin check
1002 settings.disable_service_auth_codes, // disable VM service auth codes
1003 settings.enable_service_port_fallback, // enable fallback to port 0
1004 // when bind fails.
1005 error // error (out)
1006 )) {
1007 // Error is populated by call to startup.
1008 FML_DLOG(ERROR) << *error;
1009 return nullptr;
1010 }
1011
1012 if (auto callback = vm_data->GetSettings().service_isolate_create_callback) {
1013 callback();
1014 }
1015
1016 if (auto service_protocol = DartVMRef::GetServiceProtocol()) {
1017 service_protocol->ToggleHooks(true);
1018 } else {
1020 << "Could not acquire the service protocol handlers. This might be "
1021 "because the VM has already begun teardown on another thread.";
1022 }
1023
1024 return service_isolate->isolate();
1025}
1026
1028 std::shared_ptr<DartIsolateGroupData>* isolate_group_data =
1029 static_cast<std::shared_ptr<DartIsolateGroupData>*>(
1031 return **isolate_group_data;
1032}
1033
1035 DartIsolate* non_const_this = const_cast<DartIsolate*>(this);
1036 return non_const_this->GetIsolateGroupData();
1037}
1038
1039// |Dart_IsolateGroupCreateCallback|
1040Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
1041 const char* advisory_script_uri,
1042 const char* advisory_script_entrypoint,
1043 const char* package_root,
1044 const char* package_config,
1046 std::shared_ptr<DartIsolate>* parent_isolate_data,
1047 char** error) {
1048 TRACE_EVENT0("flutter", "DartIsolate::DartIsolateGroupCreateCallback");
1049 if (parent_isolate_data == nullptr &&
1050 strcmp(advisory_script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
1051 // The VM attempts to start the VM service for us on |Dart_Initialize|. In
1052 // such a case, the callback data will be null and the script URI will be
1053 // DART_VM_SERVICE_ISOLATE_NAME. In such cases, we just create the service
1054 // isolate like normal but dont hold a reference to it at all. We also start
1055 // this isolate since we will never again reference it from the engine.
1056 return DartCreateAndStartServiceIsolate(package_root, //
1057 package_config, //
1058 flags, //
1059 error //
1060 );
1061 }
1062
1063 if (!parent_isolate_data) {
1064 return nullptr;
1065 }
1066
1067 DartIsolateGroupData& parent_group_data =
1068 (*parent_isolate_data)->GetIsolateGroupData();
1069
1070 if (strncmp(advisory_script_uri, kFileUriPrefix.data(),
1071 kFileUriPrefix.size())) {
1072 std::string error_msg =
1073 std::string("Unsupported isolate URI: ") + advisory_script_uri;
1074 *error = fml::strdup(error_msg.c_str());
1075 return nullptr;
1076 }
1077
1078 auto isolate_group_data =
1079 std::make_unique<std::shared_ptr<DartIsolateGroupData>>(
1080 std::shared_ptr<DartIsolateGroupData>(new DartIsolateGroupData(
1081 parent_group_data.GetSettings(),
1082 parent_group_data.GetIsolateSnapshot(), advisory_script_uri,
1083 advisory_script_entrypoint,
1084 parent_group_data.GetChildIsolatePreparer(),
1085 parent_group_data.GetIsolateCreateCallback(),
1086 parent_group_data.GetIsolateShutdownCallback())));
1087
1088 TaskRunners null_task_runners(advisory_script_uri,
1089 /* platform= */ nullptr,
1090 /* raster= */ nullptr,
1091 /* ui= */ nullptr,
1092 /* io= */ nullptr);
1093
1094 UIDartState::Context context(null_task_runners);
1095 context.advisory_script_uri = advisory_script_uri;
1096 context.advisory_script_entrypoint = advisory_script_entrypoint;
1097 auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
1098 std::shared_ptr<DartIsolate>(
1099 new DartIsolate((*isolate_group_data)->GetSettings(), // settings
1100 false, // is_root_isolate
1101 context))); // context
1102
1103 Dart_Isolate vm_isolate = CreateDartIsolateGroup(
1104 std::move(isolate_group_data), std::move(isolate_data), flags, error,
1105 [](std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1106 std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
1107 char** error) {
1109 (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
1110 (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
1111 (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
1112 (*isolate_group_data)
1113 ->GetIsolateSnapshot()
1114 ->GetInstructionsMapping(),
1115 flags, isolate_group_data, isolate_data, error);
1116 });
1117
1118 if (*error) {
1119 FML_LOG(ERROR) << "CreateDartIsolateGroup failed: " << *error;
1120 }
1121
1122 return vm_isolate;
1123}
1124
1125// |Dart_IsolateInitializeCallback|
1126bool DartIsolate::DartIsolateInitializeCallback(void** child_callback_data,
1127 char** error) {
1128 TRACE_EVENT0("flutter", "DartIsolate::DartIsolateInitializeCallback");
1130 if (isolate == nullptr) {
1131 *error = fml::strdup("Isolate should be available in initialize callback.");
1132 FML_DLOG(ERROR) << *error;
1133 return false;
1134 }
1135
1136 auto* isolate_group_data =
1137 static_cast<std::shared_ptr<DartIsolateGroupData>*>(
1139
1140 TaskRunners null_task_runners((*isolate_group_data)->GetAdvisoryScriptURI(),
1141 /* platform= */ nullptr,
1142 /* raster= */ nullptr,
1143 /* ui= */ nullptr,
1144 /* io= */ nullptr);
1145
1146 UIDartState::Context context(null_task_runners);
1147 context.advisory_script_uri = (*isolate_group_data)->GetAdvisoryScriptURI();
1148 context.advisory_script_entrypoint =
1149 (*isolate_group_data)->GetAdvisoryScriptEntrypoint();
1150 auto embedder_isolate = std::make_unique<std::shared_ptr<DartIsolate>>(
1151 std::shared_ptr<DartIsolate>(
1152 new DartIsolate((*isolate_group_data)->GetSettings(), // settings
1153 false, // is_root_isolate
1154 context))); // context
1155
1156 // root isolate should have been created via CreateRootIsolate
1157 if (!InitializeIsolate(*embedder_isolate, isolate, error)) {
1158 return false;
1159 }
1160
1161 // The ownership of the embedder object is controlled by the Dart VM. So the
1162 // only reference returned to the caller is weak.
1163 *child_callback_data = embedder_isolate.release();
1164
1165 return true;
1166}
1167
1168Dart_Isolate DartIsolate::CreateDartIsolateGroup(
1169 std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
1170 std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
1172 char** error,
1173 const DartIsolate::IsolateMaker& make_isolate) {
1174 TRACE_EVENT0("flutter", "DartIsolate::CreateDartIsolateGroup");
1175
1176 // Create the Dart VM isolate and give it the embedder object as the baton.
1178 make_isolate(isolate_group_data.get(), isolate_data.get(), flags, error);
1179
1180 if (isolate == nullptr) {
1181 return nullptr;
1182 }
1183
1184 bool success = false;
1185 {
1186 // Ownership of the isolate data objects has been transferred to the Dart
1187 // VM.
1188 // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks)
1189 std::shared_ptr<DartIsolate> embedder_isolate(*isolate_data);
1190 isolate_group_data.release();
1191 isolate_data.release();
1192 // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
1193
1194 success = InitializeIsolate(embedder_isolate, isolate, error);
1195 }
1196 if (!success) {
1198 return nullptr;
1199 }
1200
1201 // Balances the implicit [Dart_EnterIsolate] by [make_isolate] above.
1203 return isolate;
1204}
1205
1206bool DartIsolate::InitializeIsolate(
1207 const std::shared_ptr<DartIsolate>& embedder_isolate,
1208 Dart_Isolate isolate,
1209 char** error) {
1210 TRACE_EVENT0("flutter", "DartIsolate::InitializeIsolate");
1211 if (!embedder_isolate->Initialize(isolate)) {
1212 *error = fml::strdup("Embedder could not initialize the Dart isolate.");
1213 FML_DLOG(ERROR) << *error;
1214 return false;
1215 }
1216
1217 if (!embedder_isolate->LoadLibraries()) {
1218 *error = fml::strdup(
1219 "Embedder could not load libraries in the new Dart isolate.");
1220 FML_DLOG(ERROR) << *error;
1221 return false;
1222 }
1223
1224 // Root isolates will be set up by the engine and the service isolate
1225 // (which is also a root isolate) by the utility routines in the VM.
1226 // However, secondary isolates will be run by the VM if they are
1227 // marked as runnable.
1228 if (!embedder_isolate->IsRootIsolate()) {
1229 auto child_isolate_preparer =
1230 embedder_isolate->GetIsolateGroupData().GetChildIsolatePreparer();
1231 FML_DCHECK(child_isolate_preparer);
1232 if (!child_isolate_preparer(embedder_isolate.get())) {
1233 *error = fml::strdup("Could not prepare the child isolate to run.");
1234 FML_DLOG(ERROR) << *error;
1235 return false;
1236 }
1237 }
1238
1239 return true;
1240}
1241
1242// |Dart_IsolateShutdownCallback|
1243void DartIsolate::DartIsolateShutdownCallback(
1244 std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1245 std::shared_ptr<DartIsolate>* isolate_data) {
1246 TRACE_EVENT0("flutter", "DartIsolate::DartIsolateShutdownCallback");
1247
1248 // If the isolate initialization failed there will be nothing to do.
1249 // This can happen e.g. during a [DartIsolateInitializeCallback] invocation
1250 // that fails to initialize the VM-created isolate.
1251 if (isolate_data == nullptr) {
1252 return;
1253 }
1254
1255 isolate_data->get()->OnShutdownCallback();
1256}
1257
1258// |Dart_IsolateGroupCleanupCallback|
1259void DartIsolate::DartIsolateGroupCleanupCallback(
1260 std::shared_ptr<DartIsolateGroupData>* isolate_data) {
1261 TRACE_EVENT0("flutter", "DartIsolate::DartIsolateGroupCleanupCallback");
1262 delete isolate_data;
1263}
1264
1265// |Dart_IsolateCleanupCallback|
1266void DartIsolate::DartIsolateCleanupCallback(
1267 std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1268 std::shared_ptr<DartIsolate>* isolate_data) {
1269 TRACE_EVENT0("flutter", "DartIsolate::DartIsolateCleanupCallback");
1270 delete isolate_data;
1271}
1272
1273std::weak_ptr<DartIsolate> DartIsolate::GetWeakIsolatePtr() {
1274 return std::static_pointer_cast<DartIsolate>(shared_from_this());
1275}
1276
1278 shutdown_callbacks_.emplace_back(std::make_unique<AutoFireClosure>(closure));
1279}
1280
1281void DartIsolate::OnShutdownCallback() {
1283 if (state != nullptr) {
1284 state->SetIsShuttingDown();
1285 }
1286
1287 {
1288 tonic::DartApiScope api_scope;
1289 Dart_Handle sticky_error = Dart_GetStickyError();
1290 if (!Dart_IsNull(sticky_error) && !Dart_IsFatalError(sticky_error)) {
1291 FML_LOG(ERROR) << Dart_GetError(sticky_error);
1292 }
1293 }
1294
1295 if (is_platform_isolate_) {
1296 FML_DCHECK(platform_isolate_manager_ != nullptr);
1297 platform_isolate_manager_->RemovePlatformIsolate(isolate());
1298 }
1299
1300 shutdown_callbacks_.clear();
1301
1302 const fml::closure& isolate_shutdown_callback =
1304 if (isolate_shutdown_callback) {
1305 isolate_shutdown_callback();
1306 }
1307}
1308
1309Dart_Handle DartIsolate::OnDartLoadLibrary(intptr_t loading_unit_id) {
1312 loading_unit_id);
1313 return Dart_Null();
1314 }
1315 const std::string error_message =
1316 "Platform Configuration was null. Deferred library load request "
1317 "for loading unit id " +
1318 std::to_string(loading_unit_id) + " was not sent.";
1319 FML_LOG(ERROR) << error_message;
1320 return Dart_NewApiError(error_message.c_str());
1321}
1322
1324 const std::shared_ptr<const fml::Mapping>& mapping) {
1326 return Dart_Null();
1327 }
1328
1329 auto* isolate_group_data =
1330 static_cast<std::shared_ptr<DartIsolateGroupData>*>(
1332 // Mapping must be retained until isolate shutdown.
1333 (*isolate_group_data)->AddKernelBuffer(mapping);
1334
1335 auto lib =
1336 Dart_LoadLibraryFromKernel(mapping->GetMapping(), mapping->GetSize());
1337 if (tonic::CheckAndHandleError(lib)) {
1338 return Dart_Null();
1339 }
1340 auto result = Dart_FinalizeLoading(false);
1341 if (Dart_IsError(result)) {
1342 return result;
1343 }
1344 return Dart_GetField(lib, Dart_NewStringFromCString("main"));
1345}
1346
1347DartIsolate::AutoFireClosure::AutoFireClosure(const fml::closure& closure)
1348 : closure_(closure) {}
1349
1350DartIsolate::AutoFireClosure::~AutoFireClosure() {
1351 if (closure_) {
1352 closure_();
1353 }
1354}
1355
1356} // namespace flutter
int count
static void InitForIsolate(bool may_insecurely_connect_to_all_domains, const std::string &domain_network_policy)
Definition dart_io.cc:18
const fml::closure & GetIsolateShutdownCallback() const
void SetChildIsolatePreparer(const ChildIsolatePreparer &value)
const fml::closure & GetIsolateCreateCallback() const
void AddKernelBuffer(const std::shared_ptr< const fml::Mapping > &buffer)
Adds a kernel buffer mapping to the kernels loaded for this isolate group.
void SetNullSafetyEnabled(bool enabled)
void SetIsDontNeedSafe(bool value)
Represents an instance of a live isolate. An isolate is a separate Dart execution context....
bool PrepareForRunningFromKernel(const 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.
std::string GetServiceId()
Returns the ID for an isolate which is used to query the service protocol.
void LoadLoadingUnitError(intptr_t loading_unit_id, const std::string &error_message, bool transient)
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...
Dart_Isolate CreatePlatformIsolate(Dart_Handle entry_point, char **error) override
Creates a new isolate in the same group as this isolate, which runs on the platform thread....
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, const fml::RefPtr< const DartSnapshot > &isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, Flags flags, const 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...
bool PrepareForRunningFromKernels(std::vector< std::shared_ptr< const fml::Mapping > > kernels)
Prepare the isolate for running for a a list of kernel files.
static Dart_Handle LoadLibraryFromKernel(const std::shared_ptr< const fml::Mapping > &mapping)
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...
DartIsolateGroupData & GetIsolateGroupData()
void AddIsolateShutdownCallback(const fml::closure &closure)
Registers a callback that will be invoked in isolate scope just before the isolate transitions to the...
fml::RefPtr< fml::TaskRunner > GetMessageHandlingTaskRunner() const
The task runner on which the Dart code for the root isolate is running. For the root isolate,...
bool Shutdown()
Transition the isolate to the Phase::Shutdown phase. The only thing left to do is to collect the isol...
Phase GetPhase() const
The current phase of the isolate. The engine represents all dart isolates as being in one of the know...
bool PrepareForRunningFromPrecompiledCode()
Prepare the isolate for running for a precompiled code bundle. The Dart VM must be configured for run...
bool LoadLoadingUnit(intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)
Phase
The engine represents all dart isolates as being in one of the known phases. By invoking various meth...
static void Install(bool is_ui_isolate, const std::string &script_uri)
static bool Startup(const 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...
static fml::RefPtr< DartSnapshot > IsolateSnapshotFromMappings(const std::shared_ptr< const fml::Mapping > &snapshot_data, const std::shared_ptr< const fml::Mapping > &snapshot_instructions)
Create an isolate snapshot from existing fml::Mappings.
static void InitForIsolate(const Settings &settings)
Definition dart_ui.cc:367
static std::shared_ptr< ServiceProtocol > GetServiceProtocol()
static std::shared_ptr< const DartVMData > GetVMData()
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:205
virtual std::shared_ptr< PlatformIsolateManager > GetPlatformIsolateManager()=0
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...
A class for holding and distributing platform-level information to and from the Dart code in Flutter'...
PlatformConfigurationClient * client() const
Access to the platform configuration client (which typically is implemented by the RuntimeController)...
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
PlatformConfiguration * platform_configuration() const
UnhandledExceptionCallback unhandled_exception_callback() const
bool IsRootIsolate() const
const TaskRunners & GetTaskRunners() const
std::shared_ptr< IsolateNameServer > GetIsolateNameServer() const
const std::string & GetAdvisoryScriptURI() const
static UIDartState * Current()
static MessageLoopTaskQueues * GetInstance()
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition closure.h:32
static TimePoint Now()
Definition time_point.cc:49
void add_provider(const std::string &library_name, std::unique_ptr< DartClassProvider > provider)
std::function< void(std::function< void(void)>)> TaskDispatcher
void Initialize(TaskDispatcher dispatcher)
Dart_Isolate isolate()
Definition dart_state.h:51
void SetIsolate(Dart_Isolate isolate)
Definition dart_state.cc:35
DartMessageHandler & message_handler()
Definition dart_state.h:61
static DartState * Current()
Definition dart_state.cc:56
DartClassLibrary & class_library()
Definition dart_state.h:60
static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url)
Definition dart_state.cc:79
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroup(const char *script_uri, const char *name, const uint8_t *isolate_snapshot_data, const uint8_t *isolate_snapshot_instructions, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT Dart_Handle Dart_HandleFromPersistent(Dart_PersistentHandle object)
DART_EXPORT void Dart_IsolateFlagsInitialize(Dart_IsolateFlags *flags)
DART_EXPORT Dart_Handle Dart_GetNonNullableType(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle *type_arguments)
DART_EXPORT DART_WARN_UNUSED_RESULT char * Dart_IsolateMakeRunnable(Dart_Isolate isolate)
void(* Dart_IsolateCleanupCallback)(void *isolate_group_data, void *isolate_data)
Definition dart_api.h:728
DART_EXPORT Dart_Handle Dart_SetDeferredLoadHandler(Dart_DeferredLoadHandler handler)
DART_EXPORT void Dart_ShutdownIsolate(void)
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object)
DART_EXPORT Dart_Isolate Dart_CreateIsolateInGroup(Dart_Isolate group_member, const char *name, Dart_IsolateShutdownCallback shutdown_callback, Dart_IsolateCleanupCallback cleanup_callback, void *child_isolate_data, char **error)
struct _Dart_Isolate * Dart_Isolate
Definition dart_api.h:88
DART_EXPORT bool Dart_IsFatalError(Dart_Handle handle)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_FinalizeLoading(bool complete_futures)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_SetField(Dart_Handle container, Dart_Handle name, Dart_Handle value)
DART_EXPORT Dart_Isolate Dart_CurrentIsolate(void)
DART_EXPORT bool Dart_IsKernel(const uint8_t *buffer, intptr_t buffer_size)
Dart_Handle Dart_PersistentHandle
Definition dart_api.h:259
DART_EXPORT Dart_Handle Dart_False(void)
DART_EXPORT Dart_Handle Dart_NewApiError(const char *error)
DART_EXPORT Dart_Handle Dart_Null(void)
void(* Dart_IsolateShutdownCallback)(void *isolate_group_data, void *isolate_data)
Definition dart_api.h:710
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_DeferredLoadComplete(intptr_t loading_unit_id, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions)
DART_EXPORT const char * Dart_IsolateServiceId(Dart_Isolate isolate)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT void * Dart_IsolateData(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DART_EXPORT void * Dart_IsolateGroupData(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_GetStickyError(void)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
#define DART_VM_SERVICE_ISOLATE_NAME
Definition dart_api.h:3831
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT void Dart_ExitIsolate(void)
DART_EXPORT bool Dart_IsServiceIsolate(Dart_Isolate isolate)
DART_EXPORT void * Dart_CurrentIsolateGroupData(void)
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_DeferredLoadCompleteError(intptr_t loading_unit_id, const char *error_message, bool transient)
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler(Dart_LibraryTagHandler handler)
DART_EXPORT Dart_Handle Dart_RootLibrary(void)
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library)
DART_EXPORT Dart_Handle Dart_SetCurrentUserTag(Dart_Handle user_tag)
DART_EXPORT Dart_Handle Dart_NewUserTag(const char *label)
AtkStateType state
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
#define FML_DLOG(severity)
Definition logging.h:102
#define FML_LOG(severity)
Definition logging.h:82
#define FML_CHECK(condition)
Definition logging.h:85
#define FML_DCHECK(condition)
Definition logging.h:103
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
std::function< void(intptr_t, fml::closure)> TaskObserverAdd
Definition settings.h:82
constexpr char kFileUriPrefix[]
Definition dart_vm.cc:127
bool InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition switches.h:126
bool FindAndInvokeDartPluginRegistrant()
static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function, Dart_Handle args)
char * strdup(const char *str1)
std::function< void()> closure
Definition closure.h:14
Definition ref_ptr.h:256
Dart_Handle ToDart(const T &object)
Dart_Handle DartInvokeVoid(Dart_Handle closure)
bool CheckAndHandleError(Dart_Handle handle)
Definition dart_error.cc:33
Dart_Handle DartInvokeField(Dart_Handle target, const char *name, std::initializer_list< Dart_Handle > args)
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
#define ERROR(message)
#define TRACE_EVENT0(category_group, name)