26#include "third_party/dart/runtime/include/bin/native_assets_api.h"
27#include "third_party/dart/runtime/include/dart_api.h"
28#include "third_party/dart/runtime/include/dart_tools_api.h"
44class DartErrorString {
52 char**
error() {
return &str_; }
53 const char* str()
const {
return str_; }
54 explicit operator bool()
const {
return str_ !=
nullptr; }
63DartIsolate::Flags::Flags() :
Flags(nullptr) {}
65DartIsolate::Flags::Flags(
const Dart_IsolateFlags* flags) {
69 ::Dart_IsolateFlagsInitialize(&flags_);
73DartIsolate::Flags::~Flags() =
default;
75void DartIsolate::Flags::SetNullSafetyEnabled(
bool enabled) {
76 flags_.null_safety = enabled;
79void DartIsolate::Flags::SetIsDontNeedSafe(
bool value) {
80 flags_.snapshot_is_dontneed_safe =
value;
83Dart_IsolateFlags DartIsolate::Flags::Get()
const {
95 std::optional<std::string> dart_entrypoint,
96 std::optional<std::string> dart_entrypoint_library,
97 const std::vector<std::string>& dart_entrypoint_args,
98 std::unique_ptr<IsolateConfiguration> isolate_configuration,
101 std::shared_ptr<NativeAssetsManager> native_assets_manager) {
102 if (!isolate_snapshot) {
103 FML_LOG(ERROR) <<
"Invalid isolate snapshot.";
107 if (!isolate_configuration) {
108 FML_LOG(ERROR) <<
"Invalid isolate configuration.";
113 isolate_configuration->IsNullSafetyEnabled(*isolate_snapshot));
116 auto isolate = CreateRootIsolate(settings,
120 isolate_create_callback,
121 isolate_shutdown_callback,
124 std::move(native_assets_manager)
129 FML_LOG(ERROR) <<
"Could not create root isolate.";
135 FML_DLOG(ERROR) <<
"Could not shutdown transient isolate.";
140 FML_LOG(ERROR) <<
"Root isolate was created in an incorrect phase: "
141 <<
static_cast<int>(
isolate->GetPhase());
145 if (!isolate_configuration->PrepareIsolate(*
isolate.get())) {
146 FML_LOG(ERROR) <<
"Could not prepare isolate.";
151 FML_LOG(ERROR) <<
"Root isolate not in the ready phase for Dart entrypoint "
160 Dart_SetCurrentThreadOwnsIsolate();
170 if (root_isolate_create_callback) {
171 root_isolate_create_callback();
174 if (!
isolate->RunFromLibrary(std::move(dart_entrypoint_library),
175 std::move(dart_entrypoint),
176 dart_entrypoint_args)) {
177 FML_LOG(ERROR) <<
"Could not run the run main Dart entrypoint.";
182 isolate->AddIsolateShutdownCallback(
186 shutdown_on_error.Release();
191void DartIsolate::SpawnIsolateShutdownCallback(
192 std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
193 std::shared_ptr<DartIsolate>* isolate_data) {
194 DartIsolate::DartIsolateShutdownCallback(isolate_group_data, isolate_data);
197std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
198 const Settings& settings,
204 const UIDartState::Context& context,
205 const DartIsolate* spawning_isolate,
206 std::shared_ptr<NativeAssetsManager> native_assets_manager) {
207 TRACE_EVENT0(
"flutter",
"DartIsolate::CreateRootIsolate");
210 std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data;
212 auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
213 std::shared_ptr<DartIsolate>(
new DartIsolate(
217 !!spawning_isolate)));
219 DartErrorString
error;
220 Dart_Isolate vm_isolate =
nullptr;
221 auto isolate_flags = flags.Get();
223 IsolateMaker isolate_maker;
224 if (spawning_isolate) {
227 std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
228 std::shared_ptr<DartIsolate>* isolate_data,
229 Dart_IsolateFlags* flags,
char**
error) {
230 return Dart_CreateIsolateInGroup(
231 spawning_isolate->isolate(),
233 spawning_isolate->GetIsolateGroupData()
234 .GetAdvisoryScriptEntrypoint()
237 reinterpret_cast<Dart_IsolateShutdownCallback
>(
238 DartIsolate::SpawnIsolateShutdownCallback),
240 reinterpret_cast<Dart_IsolateCleanupCallback
>(
241 DartIsolateCleanupCallback),
249 std::make_unique<std::shared_ptr<DartIsolateGroupData>>(
250 std::shared_ptr<DartIsolateGroupData>(
new DartIsolateGroupData(
252 std::move(isolate_snapshot),
253 context.advisory_script_uri,
254 context.advisory_script_entrypoint,
256 isolate_create_callback,
257 isolate_shutdown_callback,
258 std::move(native_assets_manager)
260 isolate_maker = [](std::shared_ptr<DartIsolateGroupData>*
262 std::shared_ptr<DartIsolate>* isolate_data,
263 Dart_IsolateFlags* flags,
char**
error) {
264 return Dart_CreateIsolateGroup(
265 (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
266 (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
267 (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
268 (*isolate_group_data)->GetIsolateSnapshot()->GetInstructionsMapping(),
269 flags, isolate_group_data, isolate_data,
error);
273 vm_isolate = CreateDartIsolateGroup(std::move(isolate_group_data),
274 std::move(isolate_data), &isolate_flags,
275 error.error(), isolate_maker);
278 FML_LOG(ERROR) <<
"CreateRootIsolate failed: " <<
error.str();
281 if (vm_isolate ==
nullptr) {
285 std::shared_ptr<DartIsolate>* root_isolate_data =
286 static_cast<std::shared_ptr<DartIsolate>*
>(Dart_IsolateData(vm_isolate));
291 return (*root_isolate_data)->GetWeakIsolatePtr();
299 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
301 std::weak_ptr<PlatformIsolateManager> weak_platform_isolate_manager =
302 platform_isolate_manager;
303 if (platform_isolate_manager->HasShutdownMaybeFalseNegative()) {
306 FML_LOG(INFO) <<
"CreatePlatformIsolate called after shutdown";
310 Dart_Isolate parent_isolate =
isolate();
318 auto isolate_group_data = std::shared_ptr<DartIsolateGroupData>(
319 *
static_cast<std::shared_ptr<DartIsolateGroupData>*
>(
320 Dart_IsolateGroupData(parent_isolate)));
322 Settings settings(isolate_group_data->GetSettings());
330 const std::string& stack_trace) {
331 FML_LOG(ERROR) <<
"Unhandled exception:\n" <<
error <<
"\n" << stack_trace;
339 weak_platform_isolate_manager](
341 platform_task_runner->PostTask([old_task_observer_add,
342 weak_platform_isolate_manager,
key,
344 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
345 weak_platform_isolate_manager.lock();
346 if (platform_isolate_manager ==
nullptr ||
347 platform_isolate_manager->HasShutdown()) {
350 FML_LOG(INFO) <<
"Shutdown before platform isolate task observer added";
355 return platform_task_runner->GetTaskQueueId();
361 isolate_group_data->GetAdvisoryScriptEntrypoint();
362 auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
363 std::shared_ptr<DartIsolate>(
364 new DartIsolate(settings, context, platform_isolate_manager)));
366 IsolateMaker isolate_maker =
368 std::shared_ptr<DartIsolateGroupData>* unused_isolate_group_data,
369 std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
371 return Dart_CreateIsolateInGroup(
375 reinterpret_cast<Dart_IsolateShutdownCallback
>(
376 DartIsolate::SpawnIsolateShutdownCallback),
378 reinterpret_cast<Dart_IsolateCleanupCallback
>(
379 DartIsolateCleanupCallback),
383 Dart_Isolate platform_isolate = CreateDartIsolateGroup(
384 nullptr, std::move(isolate_data),
nullptr,
error, isolate_maker);
386 Dart_EnterIsolate(parent_isolate);
392 if (!platform_isolate_manager->RegisterPlatformIsolate(platform_isolate)) {
396 FML_LOG(INFO) <<
"Shutdown during platform isolate creation";
398 Dart_ShutdownIsolate();
403 Dart_PersistentHandle entry_point_handle =
404 Dart_NewPersistentHandle(entry_point);
406 platform_task_runner->PostTask([entry_point_handle, platform_isolate,
407 weak_platform_isolate_manager]() {
408 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
409 weak_platform_isolate_manager.lock();
410 if (platform_isolate_manager ==
nullptr ||
411 platform_isolate_manager->HasShutdown()) {
414 FML_LOG(INFO) <<
"Shutdown before platform isolate entry point";
420 Dart_Handle entry_point = Dart_HandleFromPersistent(entry_point_handle);
421 Dart_DeletePersistentHandle(entry_point_handle);
424 Dart_Handle isolate_lib = Dart_LookupLibrary(
tonic::ToDart(
"dart:isolate"));
426 Dart_Handle isolate_type = Dart_GetNonNullableType(
430 Dart_SetField(isolate_type,
tonic::ToDart(
"_mayExit"), Dart_False());
436 return platform_isolate;
439DartIsolate::DartIsolate(
const Settings& settings,
440 bool is_root_isolate,
442 bool is_spawning_in_group)
444 settings.task_observer_remove,
447 settings.log_message_callback,
451 may_insecurely_connect_to_all_domains_(
452 settings.may_insecurely_connect_to_all_domains),
453 is_platform_isolate_(false),
454 is_spawning_in_group_(is_spawning_in_group),
455 domain_network_policy_(settings.domain_network_policy) {
459DartIsolate::DartIsolate(
460 const Settings& settings,
461 const UIDartState::Context& context,
462 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager)
463 : UIDartState(settings.task_observer_add,
464 settings.task_observer_remove,
466 settings.unhandled_exception_callback,
467 settings.log_message_callback,
468 DartVMRef::GetIsolateNameServer(),
471 may_insecurely_connect_to_all_domains_(
472 settings.may_insecurely_connect_to_all_domains),
473 is_platform_isolate_(true),
474 is_spawning_in_group_(false),
475 domain_network_policy_(settings.domain_network_policy),
476 platform_isolate_manager_(
std::move(platform_isolate_manager)) {
491 const char* service_id_buf = Dart_IsolateServiceId(
isolate());
492 std::string service_id(service_id_buf);
493 free(
const_cast<char*
>(service_id_buf));
497bool DartIsolate::Initialize(Dart_Isolate dart_isolate) {
504 FML_DCHECK(dart_isolate == Dart_CurrentIsolate());
514 Dart_SetCurrentUserTag(Dart_NewUserTag(
"AppStartUp"));
517 if (is_platform_isolate_) {
518 SetMessageHandlingTaskRunner(
GetTaskRunners().GetPlatformTaskRunner(),
523 bool post_directly_to_runner =
527 post_directly_to_runner);
536 Dart_SetDeferredLoadHandler(OnDartLoadLibrary))) {
540 if (!UpdateThreadPoolNames()) {
549 return message_handling_task_runner_;
553 intptr_t loading_unit_id,
554 std::unique_ptr<const fml::Mapping> snapshot_data,
555 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
560 std::move(snapshot_data), std::move(snapshot_instructions));
562 Dart_Handle result = Dart_DeferredLoadComplete(
563 loading_unit_id, dart_snapshot->GetDataMapping(),
564 dart_snapshot->GetInstructionsMapping());
570 loading_unit_snapshots_.insert(dart_snapshot);
575 const std::string& error_message,
578 Dart_Handle result = Dart_DeferredLoadCompleteError(
579 loading_unit_id, error_message.c_str(), transient);
583void DartIsolate::SetMessageHandlingTaskRunner(
585 bool post_directly_to_runner) {
590 message_handling_task_runner_ = runner;
595 post_directly_to_runner =
true;
598 if (post_directly_to_runner) {
599 dispatcher = [runner](std::function<void()> task) {
600 runner->PostTask([task = std::move(task)]() {
606 dispatcher = [runner](std::function<void()> task) {
608 task_queues->RegisterTask(
609 runner->GetTaskQueueId(),
610 [task = std::move(task)]() {
611 TRACE_EVENT0(
"flutter",
"DartIsolate::HandleMessage");
624bool DartIsolate::UpdateThreadPoolNames()
const {
629 if (
auto task_runner = task_runners.GetRasterTaskRunner()) {
630 task_runner->PostTask(
631 [label = task_runners.GetLabel() + std::string{
".raster"}]() {
632 Dart_SetThreadName(label.c_str());
636 if (
auto task_runner = task_runners.GetUITaskRunner()) {
637 task_runner->PostTask(
638 [label = task_runners.GetLabel() + std::string{
".ui"}]() {
639 Dart_SetThreadName(label.c_str());
643 if (
auto task_runner = task_runners.GetIOTaskRunner()) {
644 task_runner->PostTask(
645 [label = task_runners.GetLabel() + std::string{
".io"}]() {
646 Dart_SetThreadName(label.c_str());
650 if (
auto task_runner = task_runners.GetPlatformTaskRunner()) {
651 bool is_merged_platform_ui_thread =
652 task_runner == task_runners.GetUITaskRunner();
654 if (is_merged_platform_ui_thread) {
655 label = task_runners.GetLabel() + std::string{
".ui"};
657 label = task_runners.GetLabel() + std::string{
".platform"};
659 task_runner->PostTask(
660 [label = std::move(label)]() { Dart_SetThreadName(label.c_str()); });
666bool DartIsolate::LoadLibraries() {
675 domain_network_policy_);
681 const bool is_service_isolate = Dart_IsServiceIsolate(
isolate());
684 settings.profile_microtasks,
687 if (!is_service_isolate) {
689 "ui", std::make_unique<tonic::DartClassProvider>(
this,
"dart:ui"));
697 TRACE_EVENT0(
"flutter",
"DartIsolate::PrepareForRunningFromPrecompiledCode");
704 if (Dart_IsNull(Dart_RootLibrary())) {
708 if (!MarkIsolateRunnable()) {
714 return isolate->PrepareForRunningFromPrecompiledCode();
720 if (isolate_create_callback) {
721 isolate_create_callback();
728bool DartIsolate::LoadKernel(
const std::shared_ptr<const fml::Mapping>& mapping,
730 if (!Dart_IsKernel(mapping->GetMapping(), mapping->GetSize())) {
737 Dart_Handle library =
738 Dart_LoadLibraryFromKernel(mapping->GetMapping(), mapping->GetSize());
748 Dart_SetRootLibrary(library);
756 const std::shared_ptr<const fml::Mapping>& mapping,
759 TRACE_EVENT0(
"flutter",
"DartIsolate::PrepareForRunningFromKernel");
770 if (!child_isolate && !is_spawning_in_group_) {
771 if (!mapping || mapping->GetSize() == 0) {
776 Dart_SetRootLibrary(Dart_Null());
778 if (!LoadKernel(mapping, last_piece)) {
788 if (Dart_IsNull(Dart_RootLibrary())) {
792 if (!MarkIsolateRunnable()) {
803 for (uint64_t
i = 0;
i < buffers.size();
i++) {
804 bool last_piece =
i + 1 == buffers.size();
805 const std::shared_ptr<const fml::Mapping>&
buffer = buffers.at(
i);
818 if (isolate_create_callback) {
819 isolate_create_callback();
828 std::vector<std::shared_ptr<const fml::Mapping>> kernels) {
829 const auto count = kernels.size();
834 for (
size_t i = 0;
i < count; ++
i) {
835 bool last = (
i == (count - 1));
846 std::vector<std::unique_ptr<const fml::Mapping>> kernels) {
847 std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
848 shared_kernels.reserve(kernels.size());
849 for (
auto& kernel : kernels) {
850 shared_kernels.emplace_back(std::move(kernel));
855bool DartIsolate::MarkIsolateRunnable() {
856 TRACE_EVENT0(
"flutter",
"DartIsolate::MarkIsolateRunnable");
862 if (Dart_CurrentIsolate() !=
isolate()) {
883 Dart_Handle user_entrypoint_function,
886 FML_LOG(ERROR) <<
"Could not resolve main entrypoint function.";
890 Dart_Handle start_main_isolate_function =
892 "_getStartMainIsolateFunction", {});
895 FML_LOG(ERROR) <<
"Could not resolve main entrypoint trampoline.";
901 {start_main_isolate_function, user_entrypoint_function,
args}))) {
902 FML_LOG(ERROR) <<
"Could not invoke the main entrypoint.";
910 std::optional<std::string> entrypoint,
911 const std::vector<std::string>&
args) {
919 auto library_handle =
920 library_name.has_value() && !library_name.value().empty()
921 ? ::Dart_LookupLibrary(
tonic::ToDart(library_name.value().c_str()))
922 : ::Dart_RootLibrary();
923 auto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()
934 auto user_entrypoint_function =
935 ::Dart_GetField(library_handle, entrypoint_handle);
957 Dart_Isolate vm_isolate =
isolate();
960 if (vm_isolate !=
nullptr) {
964 Dart_EnterIsolate(vm_isolate);
965 Dart_ShutdownIsolate();
971Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
972 const char* package_root,
973 const char* package_config,
974 Dart_IsolateFlags* flags,
980 "Could not access VM data to initialize isolates. This may be because "
981 "the VM has initialized shutdown on another thread already.");
985 const auto& settings = vm_data->GetSettings();
987 if (!settings.enable_vm_service) {
991 flags->load_vmservice_library =
true;
993#if (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG)
997 flags->null_safety = vm_data->GetServiceIsolateSnapshotNullSafety();
1000 UIDartState::Context context(
1001 TaskRunners(
"io.flutter." DART_VM_SERVICE_ISOLATE_NAME,
nullptr,
nullptr,
1003 context.advisory_script_uri = DART_VM_SERVICE_ISOLATE_NAME;
1004 context.advisory_script_entrypoint = DART_VM_SERVICE_ISOLATE_NAME;
1005 std::weak_ptr<DartIsolate> weak_service_isolate =
1006 DartIsolate::CreateRootIsolate(vm_data->GetSettings(),
1007 vm_data->GetServiceIsolateSnapshot(),
1009 DartIsolate::Flags{flags},
1014 std::shared_ptr<DartIsolate> service_isolate = weak_service_isolate.lock();
1015 if (!service_isolate) {
1023 settings.vm_service_host,
1024 settings.vm_service_port,
1027 settings.disable_service_auth_codes,
1028 settings.enable_service_port_fallback,
1037 if (
auto callback = vm_data->GetSettings().service_isolate_create_callback) {
1042 service_protocol->ToggleHooks(
true);
1045 <<
"Could not acquire the service protocol handlers. This might be "
1046 "because the VM has already begun teardown on another thread.";
1049 return service_isolate->isolate();
1053 std::shared_ptr<DartIsolateGroupData>* isolate_group_data =
1054 static_cast<std::shared_ptr<DartIsolateGroupData>*
>(
1055 Dart_IsolateGroupData(
isolate()));
1056 return **isolate_group_data;
1065Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
1066 const char* advisory_script_uri,
1067 const char* advisory_script_entrypoint,
1068 const char* package_root,
1069 const char* package_config,
1070 Dart_IsolateFlags* flags,
1071 std::shared_ptr<DartIsolate>* parent_isolate_data,
1073 TRACE_EVENT0(
"flutter",
"DartIsolate::DartIsolateGroupCreateCallback");
1074 if (parent_isolate_data ==
nullptr &&
1075 strcmp(advisory_script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
1081 return DartCreateAndStartServiceIsolate(package_root,
1088 if (!parent_isolate_data) {
1092 DartIsolateGroupData& parent_group_data =
1093 (*parent_isolate_data)->GetIsolateGroupData();
1097 std::string error_msg =
1098 std::string(
"Unsupported isolate URI: ") + advisory_script_uri;
1103 auto isolate_group_data =
1104 std::make_unique<std::shared_ptr<DartIsolateGroupData>>(
1105 std::shared_ptr<DartIsolateGroupData>(
new DartIsolateGroupData(
1106 parent_group_data.GetSettings(),
1107 parent_group_data.GetIsolateSnapshot(), advisory_script_uri,
1108 advisory_script_entrypoint,
1109 parent_group_data.GetChildIsolatePreparer(),
1110 parent_group_data.GetIsolateCreateCallback(),
1111 parent_group_data.GetIsolateShutdownCallback())));
1113 TaskRunners null_task_runners(advisory_script_uri,
1119 UIDartState::Context context(null_task_runners);
1120 context.advisory_script_uri = advisory_script_uri;
1121 context.advisory_script_entrypoint = advisory_script_entrypoint;
1122 auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
1123 std::shared_ptr<DartIsolate>(
1124 new DartIsolate((*isolate_group_data)->GetSettings(),
1128 Dart_Isolate vm_isolate = CreateDartIsolateGroup(
1129 std::move(isolate_group_data), std::move(isolate_data), flags,
error,
1130 [](std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1131 std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
1133 return Dart_CreateIsolateGroup(
1134 (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
1135 (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
1136 (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
1137 (*isolate_group_data)
1138 ->GetIsolateSnapshot()
1139 ->GetInstructionsMapping(),
1140 flags, isolate_group_data, isolate_data,
error);
1144 FML_LOG(ERROR) <<
"CreateDartIsolateGroup failed: " << *
error;
1151bool DartIsolate::DartIsolateInitializeCallback(
void** child_callback_data,
1153 TRACE_EVENT0(
"flutter",
"DartIsolate::DartIsolateInitializeCallback");
1154 Dart_Isolate
isolate = Dart_CurrentIsolate();
1156 *
error =
fml::strdup(
"Isolate should be available in initialize callback.");
1161 auto* isolate_group_data =
1162 static_cast<std::shared_ptr<DartIsolateGroupData>*
>(
1163 Dart_CurrentIsolateGroupData());
1165 TaskRunners null_task_runners((*isolate_group_data)->GetAdvisoryScriptURI(),
1171 UIDartState::Context context(null_task_runners);
1172 context.advisory_script_uri = (*isolate_group_data)->GetAdvisoryScriptURI();
1173 context.advisory_script_entrypoint =
1174 (*isolate_group_data)->GetAdvisoryScriptEntrypoint();
1175 auto embedder_isolate = std::make_unique<std::shared_ptr<DartIsolate>>(
1176 std::shared_ptr<DartIsolate>(
1177 new DartIsolate((*isolate_group_data)->GetSettings(),
1182 if (!InitializeIsolate(*embedder_isolate,
isolate,
error)) {
1188 *child_callback_data = embedder_isolate.release();
1194 auto* isolate_group_data =
1195 static_cast<std::shared_ptr<DartIsolateGroupData>*
>(
1196 Dart_CurrentIsolateGroupData());
1197 const std::string& script_uri = (*isolate_group_data)->GetAdvisoryScriptURI();
1198 return dart::bin::NativeAssets::DlopenRelative(
path, script_uri.data(),
1203 auto* isolate_group_data =
1204 static_cast<std::shared_ptr<DartIsolateGroupData>*
>(
1205 Dart_CurrentIsolateGroupData());
1206 auto native_assets_manager = (*isolate_group_data)->GetNativeAssetsManager();
1207 if (native_assets_manager ==
nullptr) {
1211 std::vector<std::string> asset_path =
1212 native_assets_manager->LookupNativeAsset(asset_id);
1213 if (asset_path.size() == 0) {
1218 auto& path_type = asset_path[0];
1220 static constexpr const char* kAbsolute =
"absolute";
1221 static constexpr const char* kExecutable =
"executable";
1222 static constexpr const char* kProcess =
"process";
1223 static constexpr const char* kRelative =
"relative";
1224 static constexpr const char* kSystem =
"system";
1225 if (path_type == kAbsolute || path_type == kRelative ||
1226 path_type == kSystem) {
1227 path = asset_path[1];
1230 if (path_type == kAbsolute) {
1231 return dart::bin::NativeAssets::DlopenAbsolute(
path.c_str(),
error);
1232 }
else if (path_type == kRelative) {
1234 }
else if (path_type == kSystem) {
1235 return dart::bin::NativeAssets::DlopenSystem(
path.c_str(),
error);
1236 }
else if (path_type == kProcess) {
1237 return dart::bin::NativeAssets::DlopenProcess(
error);
1238 }
else if (path_type == kExecutable) {
1239 return dart::bin::NativeAssets::DlopenExecutable(
error);
1246 auto* isolate_group_data =
1247 static_cast<std::shared_ptr<DartIsolateGroupData>*
>(
1248 Dart_CurrentIsolateGroupData());
1249 auto native_assets_manager = (*isolate_group_data)->GetNativeAssetsManager();
1250 FML_DCHECK(native_assets_manager !=
nullptr);
1251 auto available_assets = native_assets_manager->AvailableNativeAssets();
1252 auto* result =
fml::strdup(available_assets.c_str());
1257 NativeAssetsApi native_assets;
1258 memset(&native_assets, 0,
sizeof(native_assets));
1260 native_assets.dlopen_absolute = &dart::bin::NativeAssets::DlopenAbsolute;
1262 native_assets.dlopen_system = &dart::bin::NativeAssets::DlopenSystem;
1263 native_assets.dlopen_executable = &dart::bin::NativeAssets::DlopenExecutable;
1264 native_assets.dlopen_process = &dart::bin::NativeAssets::DlopenProcess;
1266 native_assets.dlsym = &dart::bin::NativeAssets::Dlsym;
1269 Dart_InitializeNativeAssetsResolver(&native_assets);
1272Dart_Isolate DartIsolate::CreateDartIsolateGroup(
1273 std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
1274 std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
1275 Dart_IsolateFlags* flags,
1277 const DartIsolate::IsolateMaker& make_isolate) {
1278 TRACE_EVENT0(
"flutter",
"DartIsolate::CreateDartIsolateGroup");
1282 make_isolate(isolate_group_data.get(), isolate_data.get(), flags,
error);
1288 bool success =
false;
1293 std::shared_ptr<DartIsolate> embedder_isolate(*isolate_data);
1294 isolate_group_data.release();
1295 isolate_data.release();
1300 success = InitializeIsolate(embedder_isolate,
isolate,
error);
1303 Dart_ShutdownIsolate();
1312bool DartIsolate::InitializeIsolate(
1313 const std::shared_ptr<DartIsolate>& embedder_isolate,
1314 Dart_Isolate isolate,
1316 TRACE_EVENT0(
"flutter",
"DartIsolate::InitializeIsolate");
1317 if (!embedder_isolate->Initialize(
isolate)) {
1323 if (!embedder_isolate->LoadLibraries()) {
1325 "Embedder could not load libraries in the new Dart isolate.");
1334 if (!embedder_isolate->IsRootIsolate()) {
1335 auto child_isolate_preparer =
1336 embedder_isolate->GetIsolateGroupData().GetChildIsolatePreparer();
1338 if (!child_isolate_preparer(embedder_isolate.get())) {
1349void DartIsolate::DartIsolateShutdownCallback(
1350 std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1351 std::shared_ptr<DartIsolate>* isolate_data) {
1352 TRACE_EVENT0(
"flutter",
"DartIsolate::DartIsolateShutdownCallback");
1357 if (isolate_data ==
nullptr) {
1361 isolate_data->get()->OnShutdownCallback();
1365void DartIsolate::DartIsolateGroupCleanupCallback(
1366 std::shared_ptr<DartIsolateGroupData>* isolate_data) {
1367 TRACE_EVENT0(
"flutter",
"DartIsolate::DartIsolateGroupCleanupCallback");
1368 delete isolate_data;
1372void DartIsolate::DartIsolateCleanupCallback(
1373 std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1374 std::shared_ptr<DartIsolate>* isolate_data) {
1375 TRACE_EVENT0(
"flutter",
"DartIsolate::DartIsolateCleanupCallback");
1376 delete isolate_data;
1380 return std::static_pointer_cast<DartIsolate>(shared_from_this());
1385 Dart_SetCurrentThreadOwnsIsolate();
1389 shutdown_callbacks_.emplace_back(std::make_unique<AutoFireClosure>(closure));
1392void DartIsolate::OnShutdownCallback() {
1394 if (state !=
nullptr) {
1400 Dart_Handle sticky_error = Dart_GetStickyError();
1401 if (!Dart_IsNull(sticky_error) && !Dart_IsFatalError(sticky_error)) {
1402 FML_LOG(ERROR) << Dart_GetError(sticky_error);
1406 if (is_platform_isolate_) {
1407 FML_DCHECK(platform_isolate_manager_ !=
nullptr);
1408 platform_isolate_manager_->RemovePlatformIsolate(
isolate());
1411 shutdown_callbacks_.clear();
1415 if (isolate_shutdown_callback) {
1416 isolate_shutdown_callback();
1420Dart_Handle DartIsolate::OnDartLoadLibrary(intptr_t loading_unit_id) {
1426 const std::string error_message =
1427 "Platform Configuration was null. Deferred library load request "
1428 "for loading unit id " +
1429 std::to_string(loading_unit_id) +
" was not sent.";
1430 FML_LOG(ERROR) << error_message;
1431 return Dart_NewApiError(error_message.c_str());
1435 const std::shared_ptr<const fml::Mapping>& mapping) {
1440 auto* isolate_group_data =
1441 static_cast<std::shared_ptr<DartIsolateGroupData>*
>(
1442 Dart_CurrentIsolateGroupData());
1444 (*isolate_group_data)->AddKernelBuffer(mapping);
1447 Dart_LoadLibraryFromKernel(mapping->GetMapping(), mapping->GetSize());
1451 auto result = Dart_FinalizeLoading(
false);
1452 if (Dart_IsError(result)) {
1455 return Dart_GetField(lib, Dart_NewStringFromCString(
"main"));
1458DartIsolate::AutoFireClosure::AutoFireClosure(
const fml::closure& closure)
1459 : closure_(closure) {}
1461DartIsolate::AutoFireClosure::~AutoFireClosure() {
static void InitForIsolate(bool may_insecurely_connect_to_all_domains, const std::string &domain_network_policy)
void SetNullSafetyEnabled(bool enabled)
void SetIsDontNeedSafe(bool value)
const fml::closure & GetIsolateShutdownCallback() const
void SetChildIsolatePreparer(const ChildIsolatePreparer &value)
const Settings & GetSettings() const
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.
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....
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...
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, std::shared_ptr< NativeAssetsManager > native_assets_manager=nullptr)
Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance ma...
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...
void SetOwnerToCurrentThread()
static void Install(bool is_ui_isolate, bool enable_microtask_profiling, 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)
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
static std::shared_ptr< ServiceProtocol > GetServiceProtocol()
static std::shared_ptr< const DartVMData > GetVMData()
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
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.
virtual TaskQueueId GetTaskQueueId()
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)
void SetIsolate(Dart_Isolate isolate)
DartMessageHandler & message_handler()
static DartState * Current()
DartClassLibrary & class_library()
static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
FlutterDesktopBinaryReply callback
#define FML_DLOG(severity)
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
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
static void InitDartFFIForIsolateGroup()
static void * NativeAssetsDlopen(const char *asset_id, char **error)
static char * NativeAssetsAvailableAssets()
constexpr char kFileUriPrefix[]
bool InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle)
std::function< fml::TaskQueueId(intptr_t, fml::closure)> TaskObserverAdd
bool FindAndInvokeDartPluginRegistrant()
static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function, Dart_Handle args)
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 disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
char * strdup(const char *str1)
std::function< void()> closure
Dart_Handle ToDart(const T &object)
Dart_Handle DartInvokeVoid(Dart_Handle closure)
bool CheckAndHandleError(Dart_Handle handle)
Dart_Handle DartInvokeField(Dart_Handle target, const char *name, std::initializer_list< Dart_Handle > args)
std::function< void(const DartIsolate &)> root_isolate_create_callback
MergedPlatformUIThread merged_platform_ui_thread
TaskObserverAdd task_observer_add
UnhandledExceptionCallback unhandled_exception_callback
fml::closure root_isolate_shutdown_callback
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
std::string advisory_script_uri
std::string advisory_script_entrypoint
#define TRACE_EVENT0(category_group, name)