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