-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Labels
area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.library-ffi
Milestone
Description
sdk/runtime/lib/ffi_dynamic_library.cc
Lines 385 to 458 in faee649
| static void* FfiResolveAsset(Thread* const thread, | |
| const Array& asset_location, | |
| const String& symbol, | |
| char** error) { | |
| Zone* const zone = thread->zone(); | |
| const auto& asset_type = | |
| String::Cast(Object::Handle(zone, asset_location.At(0))); | |
| String& path = String::Handle(zone); | |
| if (asset_type.Equals(Symbols::absolute()) || | |
| asset_type.Equals(Symbols::relative()) || | |
| asset_type.Equals(Symbols::system())) { | |
| path = String::RawCast(asset_location.At(1)); | |
| } | |
| void* handle = nullptr; | |
| if (asset_type.Equals(Symbols::absolute())) { | |
| handle = LoadDynamicLibrary(path.ToCString(), error); | |
| } else if (asset_type.Equals(Symbols::relative())) { | |
| const auto& platform_script_uri = String::Handle( | |
| zone, | |
| String::NewFormatted( | |
| "%s%s", file_schema, | |
| String::Handle(zone, GetPlatformScriptPath(thread)).ToCString())); | |
| const char* target_uri = nullptr; | |
| char* path_cstr = path.ToMallocCString(); | |
| #if defined(DART_TARGET_OS_WINDOWS) | |
| ReplaceBackSlashes(path_cstr); | |
| #endif | |
| const bool resolved = | |
| ResolveUri(path_cstr, platform_script_uri.ToCString(), &target_uri); | |
| free(path_cstr); | |
| if (!resolved) { | |
| *error = OS::SCreate(/*use malloc*/ nullptr, | |
| "Failed to resolve '%s' relative to '%s'.", | |
| path.ToCString(), platform_script_uri.ToCString()); | |
| } else { | |
| const char* target_path = target_uri + file_schema_length; | |
| handle = LoadDynamicLibrary(target_path, error); | |
| } | |
| } else if (asset_type.Equals(Symbols::system())) { | |
| handle = LoadDynamicLibrary(path.ToCString(), error); | |
| } else if (asset_type.Equals(Symbols::process())) { | |
| #if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) || \ | |
| defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA) | |
| handle = RTLD_DEFAULT; | |
| #else | |
| handle = kWindowsDynamicLibraryProcessPtr; | |
| #endif | |
| } else if (asset_type.Equals(Symbols::executable())) { | |
| handle = LoadDynamicLibrary(nullptr, error); | |
| } else { | |
| UNREACHABLE(); | |
| } | |
| if (*error != nullptr) { | |
| char* inner_error = *error; | |
| *error = OS::SCreate(/*use malloc*/ nullptr, | |
| "Failed to load dynamic library '%s': %s", | |
| path.ToCString(), inner_error); | |
| free(inner_error); | |
| } else { | |
| void* const result = ResolveSymbol(handle, symbol.ToCString(), error); | |
| if (*error != nullptr) { | |
| char* inner_error = *error; | |
| *error = OS::SCreate(/*use malloc*/ nullptr, | |
| "Failed to lookup symbol '%s': %s", | |
| symbol.ToCString(), inner_error); | |
| free(inner_error); | |
| } else { | |
| return result; | |
| } | |
| } | |
| ASSERT(*error != nullptr); | |
| return nullptr; | |
| } |
Currently, @Natives resolve their asset and symbol in one step. If the asset is a dynamic library, the handle to this library is not cached, so dlopen is called again.
In the implementation of dlopen this seems to not be a problem, it returns the same handle and increases the ref count.
However, this will pose a problem once we would like to dlclose on isolate group shutdown.
Metadata
Metadata
Assignees
Labels
area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.library-ffi
Type
Projects
Status
No status