Flutter Engine
The Flutter Engine
ffi_dynamic_library.cc
Go to the documentation of this file.
1// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
6
7#include "platform/globals.h"
8#include "platform/utils.h"
9#if defined(DART_HOST_OS_WINDOWS)
10#include <Psapi.h>
11#include <Windows.h>
12#include <combaseapi.h>
13#include <stdio.h>
14#include <tchar.h>
15#endif
16
17#include "platform/uri.h"
19#include "vm/dart_api_impl.h"
20#include "vm/exceptions.h"
22#include "vm/native_entry.h"
23#include "vm/symbols.h"
24#include "vm/zone_text_buffer.h"
25
26#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) || \
27 defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
28#include <dlfcn.h>
29#endif
30
31namespace dart {
32
33#if defined(USING_SIMULATOR) || (defined(DART_PRECOMPILER) && !defined(TESTING))
34
35DART_NORETURN static void SimulatorUnsupported() {
36#if defined(USING_SIMULATOR)
38 "Not supported on simulated architectures.");
39#else
40 Exceptions::ThrowUnsupportedError("Not supported in precompiler.");
41#endif
42}
43
44DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) {
45 SimulatorUnsupported();
46}
47DEFINE_NATIVE_ENTRY(Ffi_dl_processLibrary, 0, 0) {
48 SimulatorUnsupported();
49}
50DEFINE_NATIVE_ENTRY(Ffi_dl_executableLibrary, 0, 0) {
51 SimulatorUnsupported();
52}
53DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
54 SimulatorUnsupported();
55}
56DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) {
57 SimulatorUnsupported();
58}
59DEFINE_NATIVE_ENTRY(Ffi_dl_close, 0, 1) {
60 SimulatorUnsupported();
61}
62DEFINE_NATIVE_ENTRY(Ffi_dl_providesSymbol, 0, 2) {
63 SimulatorUnsupported();
64}
65
66DEFINE_NATIVE_ENTRY(Ffi_GetFfiNativeResolver, 1, 0) {
67 SimulatorUnsupported();
68}
69
70#else // defined(USING_SIMULATOR) || \
71 // (defined(DART_PRECOMPILER) && !defined(TESTING))
72
73// If an error occurs populates |error| (if provided) with an error message
74// (caller must free this message when it is no longer needed).
75static void* LoadDynamicLibrary(const char* library_file,
76 char** error = nullptr) {
77 char* utils_error = nullptr;
78 void* handle = Utils::LoadDynamicLibrary(library_file, &utils_error);
79 if (utils_error != nullptr) {
80 if (error != nullptr) {
82 /*use malloc*/ nullptr, "Failed to load dynamic library '%s': %s",
83 library_file != nullptr ? library_file : "<process>", utils_error);
84 }
85 free(utils_error);
86 }
87 return handle;
88}
89
90#if defined(DART_HOST_OS_WINDOWS)
91// On windows, nullptr signals trying a lookup in all loaded modules.
92const nullptr_t kWindowsDynamicLibraryProcessPtr = nullptr;
93
94void* co_task_mem_allocated = nullptr;
95
96// If an error occurs populates |error| with an error message
97// (caller must free this message when it is no longer needed).
98void* LookupSymbolInProcess(const char* symbol, char** error) {
99 // Force loading ole32.dll.
100 if (co_task_mem_allocated == nullptr) {
101 co_task_mem_allocated = CoTaskMemAlloc(sizeof(intptr_t));
102 CoTaskMemFree(co_task_mem_allocated);
103 }
104
105 HANDLE current_process =
106 OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
108 if (current_process == nullptr) {
109 *error = OS::SCreate(nullptr, "Failed to open current process.");
110 return nullptr;
111 }
112
113 HMODULE modules[1024];
114 DWORD cb_needed;
115 if (EnumProcessModules(current_process, modules, sizeof(modules),
116 &cb_needed) != 0) {
117 for (intptr_t i = 0; i < (cb_needed / sizeof(HMODULE)); i++) {
118 if (auto result =
119 reinterpret_cast<void*>(GetProcAddress(modules[i], symbol))) {
120 CloseHandle(current_process);
121 return result;
122 }
123 }
124 }
125 CloseHandle(current_process);
126
128 nullptr, // Use `malloc`.
129 "None of the loaded modules contained the requested symbol '%s'.",
130 symbol);
131 return nullptr;
132}
133#endif
134
135// If an error occurs populates |error| with an error message
136// (caller must free this message when it is no longer needed).
137static void* ResolveSymbol(void* handle, const char* symbol, char** error) {
138#if defined(DART_HOST_OS_WINDOWS)
139 if (handle == kWindowsDynamicLibraryProcessPtr) {
140 return LookupSymbolInProcess(symbol, error);
141 }
142#endif
143 return Utils::ResolveSymbolInDynamicLibrary(handle, symbol, error);
144}
145
146static bool SymbolExists(void* handle, const char* symbol) {
147 char* error = nullptr;
148#if !defined(DART_HOST_OS_WINDOWS)
150#else
151 if (handle == nullptr) {
152 LookupSymbolInProcess(symbol, &error);
153 } else {
155 }
156#endif
157 if (error != nullptr) {
158 free(error);
159 return false;
160 }
161 return true;
162}
163
164DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) {
165 GET_NON_NULL_NATIVE_ARGUMENT(String, lib_path, arguments->NativeArgAt(0));
166
167 char* error = nullptr;
168 void* handle = LoadDynamicLibrary(lib_path.ToCString(), &error);
169 if (error != nullptr) {
170 const String& msg = String::Handle(String::New(error));
171 free(error);
173 }
174 return DynamicLibrary::New(handle, true);
175}
176
177DEFINE_NATIVE_ENTRY(Ffi_dl_processLibrary, 0, 0) {
178#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) || \
179 defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
180 return DynamicLibrary::New(RTLD_DEFAULT, false);
181#else
182 return DynamicLibrary::New(kWindowsDynamicLibraryProcessPtr, false);
183#endif
184}
185
186DEFINE_NATIVE_ENTRY(Ffi_dl_executableLibrary, 0, 0) {
187 return DynamicLibrary::New(LoadDynamicLibrary(nullptr), false);
188}
189
190DEFINE_NATIVE_ENTRY(Ffi_dl_close, 0, 1) {
191 GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
192 if (dlib.IsClosed()) {
193 // Already closed, nothing to do
194 } else if (!dlib.CanBeClosed()) {
195 const String& msg = String::Handle(
196 String::New("DynamicLibrary.process() and DynamicLibrary.executable() "
197 "can't be closed."));
199 } else {
200 void* handle = dlib.GetHandle();
201 char* error = nullptr;
203
204 if (error == nullptr) {
205 dlib.SetClosed(true);
206 } else {
207 const String& msg = String::Handle(String::New(error));
208 free(error);
210 }
211 }
212
213 return Object::null();
214}
215
216DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
217 GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
219 arguments->NativeArgAt(1));
220
221 if (dlib.IsClosed()) {
222 const String& msg =
223 String::Handle(String::New("Cannot lookup symbols in closed library."));
225 }
226
227 void* handle = dlib.GetHandle();
228
229 char* error = nullptr;
230 const uword pointer = reinterpret_cast<uword>(
231 ResolveSymbol(handle, argSymbolName.ToCString(), &error));
232 if (error != nullptr) {
234 "Failed to lookup symbol '%s': %s", argSymbolName.ToCString(), error));
235 free(error);
237 }
238 return Pointer::New(pointer);
239}
240
241DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) {
242 GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
243
244 intptr_t handle = reinterpret_cast<intptr_t>(dlib.GetHandle());
245 return Integer::NewFromUint64(handle);
246}
247
248DEFINE_NATIVE_ENTRY(Ffi_dl_providesSymbol, 0, 2) {
249 GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
251 arguments->NativeArgAt(1));
252
253 void* handle = dlib.GetHandle();
254 return Bool::Get(SymbolExists(handle, argSymbolName.ToCString())).ptr();
255}
256
257// nullptr if no native resolver is installed.
259 const String& lib_url_str) {
260 const Library& lib =
261 Library::Handle(Library::LookupLibrary(thread, lib_url_str));
262 if (lib.IsNull()) {
263 // It is not an error to not have a native resolver installed.
264 return nullptr;
265 }
266 return lib.ffi_native_resolver();
267}
268
269// If an error occurs populates |error| with an error message
270// (caller must free this message when it is no longer needed).
271static void* FfiResolveWithFfiNativeResolver(Thread* const thread,
272 Dart_FfiNativeResolver resolver,
273 const String& symbol,
274 intptr_t args_n,
275 char** error) {
276 auto* result = resolver(symbol.ToCString(), args_n);
277 if (result == nullptr) {
278 *error = OS::SCreate(/*use malloc*/ nullptr,
279 "Couldn't resolve function: '%s'", symbol.ToCString());
280 }
281 return result;
282}
283
284#if defined(DART_TARGET_OS_WINDOWS)
285// Replaces back slashes with forward slashes in place.
286static void ReplaceBackSlashes(char* cstr) {
287 const intptr_t length = strlen(cstr);
288 for (int i = 0; i < length; i++) {
289 cstr[i] = cstr[i] == '\\' ? '/' : cstr[i];
290 }
291}
292#endif
293
294const char* file_schema = "file://";
295const int file_schema_length = 7;
296
297// Get a file path with only forward slashes from the script path.
298static StringPtr GetPlatformScriptPath(Thread* thread) {
299 IsolateGroupSource* const source = thread->isolate_group()->source();
300
301#if defined(DART_TARGET_OS_WINDOWS)
302 // Isolate.spawnUri sets a `source` including the file schema.
303 // And on Windows we get an extra forward slash in that case.
304 const char* file_schema_slash = "file:///";
305 const int file_schema_slash_length = 8;
306 const char* path = source->script_uri;
307 if (strlen(source->script_uri) > file_schema_slash_length &&
308 strncmp(source->script_uri, file_schema_slash,
309 file_schema_slash_length) == 0) {
310 path = (source->script_uri + file_schema_slash_length);
311 }
312
313 // Replace backward slashes with forward slashes.
314 const intptr_t len = strlen(path);
315 char* path_copy = reinterpret_cast<char*>(malloc(len + 1));
316 snprintf(path_copy, len + 1, "%s", path);
317 ReplaceBackSlashes(path_copy);
319 free(path_copy);
320 return result.ptr();
321#else
322 // Isolate.spawnUri sets a `source` including the file schema.
323 if (strlen(source->script_uri) > file_schema_length &&
324 strncmp(source->script_uri, file_schema, file_schema_length) == 0) {
325 const char* path = (source->script_uri + file_schema_length);
326 return String::New(path);
327 }
328 return String::New(source->script_uri);
329#endif
330}
331
332// Array::null if asset is not in mapping or no mapping.
333static ArrayPtr GetAssetLocation(Thread* const thread, const String& asset) {
334 Zone* const zone = thread->zone();
335 auto& result = Array::Handle(zone);
336
337 const auto& native_assets_map =
338 Array::Handle(zone, GetNativeAssetsMap(thread));
339 if (!native_assets_map.IsNull()) {
340 NativeAssetsMap map(native_assets_map.ptr());
341 const auto& lookup = Object::Handle(zone, map.GetOrNull(asset));
342 if (!lookup.IsNull()) {
343 result = Array::Cast(lookup).ptr();
344 }
345 map.Release();
346 }
347 return result.ptr();
348}
349
350// String is zone allocated.
351static char* AvailableAssetsToCString(Thread* const thread) {
352 Zone* const zone = thread->zone();
353
354 const auto& native_assets_map =
355 Array::Handle(zone, GetNativeAssetsMap(thread));
356 ZoneTextBuffer buffer(zone, 1024);
357
358 if (native_assets_map.IsNull()) {
359 buffer.Printf("No available native assets.");
360 } else {
361 bool first = true;
362 buffer.Printf("Available native assets: ");
363 NativeAssetsMap map(native_assets_map.ptr());
364 NativeAssetsMap::Iterator it(&map);
365 auto& asset_id = String::Handle(zone);
366 while (it.MoveNext()) {
367 if (!first) {
368 buffer.Printf(" ,");
369 }
370 auto entry = it.Current();
371 asset_id ^= map.GetKey(entry);
372 buffer.Printf("%s", asset_id.ToCString());
373 }
374 buffer.Printf(".");
375 map.Release();
376 }
377 return buffer.buffer();
378}
379
380// Fall back to old implementation temporarily to ease the roll into flutter.
381// TODO(https://dartbug.com/55523): Remove fallback and throw errors that
382// native assets API is not initialized.
383static void* FfiResolveAssetFallback(Thread* const thread,
384 const String& asset_type,
385 const String& path,
386 const String& symbol,
387 char** error) {
388 Zone* const zone = thread->zone();
389 void* handle = nullptr;
390 if (asset_type.Equals(Symbols::absolute())) {
391 handle = LoadDynamicLibrary(path.ToCString(), error);
392 } else if (asset_type.Equals(Symbols::relative())) {
393 const auto& platform_script_uri = String::Handle(
394 zone,
396 "%s%s", file_schema,
397 String::Handle(zone, GetPlatformScriptPath(thread)).ToCString()));
398 char* path_cstr = path.ToMallocCString();
399#if defined(DART_TARGET_OS_WINDOWS)
400 ReplaceBackSlashes(path_cstr);
401#endif
402 CStringUniquePtr target_uri =
403 ResolveUri(path_cstr, platform_script_uri.ToCString());
404 free(path_cstr);
405 if (!target_uri) {
407 /*use malloc*/ nullptr,
408 "Failed to resolve '%s' relative to "
409 "'%s'.",
410 path.ToCString(), platform_script_uri.ToCString());
411 } else {
412 const char* target_path = target_uri.get() + file_schema_length;
413 handle = LoadDynamicLibrary(target_path, error);
414 }
415 } else if (asset_type.Equals(Symbols::system())) {
416 handle = LoadDynamicLibrary(path.ToCString(), error);
417 } else if (asset_type.Equals(Symbols::process())) {
418#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) || \
419 defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
420 handle = RTLD_DEFAULT;
421#else
422 handle = kWindowsDynamicLibraryProcessPtr;
423#endif
424 } else if (asset_type.Equals(Symbols::executable())) {
425 handle = LoadDynamicLibrary(nullptr, error);
426 } else {
427 UNREACHABLE();
428 }
429 if (*error != nullptr) {
430 char* inner_error = *error;
431 *error = OS::SCreate(/*use malloc*/ nullptr,
432 "Failed to load dynamic library '%s': %s",
433 path.ToCString(), inner_error);
434 free(inner_error);
435 } else {
436 void* const result = ResolveSymbol(handle, symbol.ToCString(), error);
437 if (*error != nullptr) {
438 char* inner_error = *error;
439 *error = OS::SCreate(/*use malloc*/ nullptr,
440 "Failed to lookup symbol '%s': %s",
441 symbol.ToCString(), inner_error);
442 free(inner_error);
443 } else {
444 return result;
445 }
446 }
447 ASSERT(*error != nullptr);
448 return nullptr;
449}
450
451// If an error occurs populates |error| with an error message
452// (caller must free this message when it is no longer needed).
453//
454// The |asset_location| is formatted as follows:
455// ['<path_type>', '<path (optional)>']
456// The |asset_location| is conform to: pkg/vm/lib/native_assets/validator.dart
457static void* FfiResolveAsset(Thread* const thread,
458 const Array& asset_location,
459 const String& symbol,
460 char** error) {
461 Zone* const zone = thread->zone();
462
463 const auto& asset_type =
464 String::Cast(Object::Handle(zone, asset_location.At(0)));
465 String& path = String::Handle(zone);
466 const char* path_cstr = nullptr;
467 if (asset_type.Equals(Symbols::absolute()) ||
468 asset_type.Equals(Symbols::relative()) ||
469 asset_type.Equals(Symbols::system())) {
470 path = String::RawCast(asset_location.At(1));
471 path_cstr = path.ToCString();
472 }
473
474 NativeAssetsApi* native_assets_api =
475 thread->isolate_group()->native_assets_api();
476 void* handle;
477 if (asset_type.Equals(Symbols::absolute())) {
478 if (native_assets_api->dlopen_absolute == nullptr) {
479 return FfiResolveAssetFallback(thread, asset_type, path, symbol, error);
480 }
481 NoActiveIsolateScope no_active_isolate_scope;
482 handle = native_assets_api->dlopen_absolute(path_cstr, error);
483 } else if (asset_type.Equals(Symbols::relative())) {
484 if (native_assets_api->dlopen_relative == nullptr) {
485 return FfiResolveAssetFallback(thread, asset_type, path, symbol, error);
486 }
487 NoActiveIsolateScope no_active_isolate_scope;
488 handle = native_assets_api->dlopen_relative(path_cstr, error);
489 } else if (asset_type.Equals(Symbols::system())) {
490 if (native_assets_api->dlopen_system == nullptr) {
491 return FfiResolveAssetFallback(thread, asset_type, path, symbol, error);
492 }
493 NoActiveIsolateScope no_active_isolate_scope;
494 handle = native_assets_api->dlopen_system(path_cstr, error);
495 } else if (asset_type.Equals(Symbols::executable())) {
496 if (native_assets_api->dlopen_executable == nullptr) {
497 return FfiResolveAssetFallback(thread, asset_type, path, symbol, error);
498 }
499 NoActiveIsolateScope no_active_isolate_scope;
500 handle = native_assets_api->dlopen_executable(error);
501 } else {
502 RELEASE_ASSERT(asset_type.Equals(Symbols::process()));
503 if (native_assets_api->dlopen_process == nullptr) {
504 return FfiResolveAssetFallback(thread, asset_type, path, symbol, error);
505 }
506 NoActiveIsolateScope no_active_isolate_scope;
507 handle = native_assets_api->dlopen_process(error);
508 }
509
510 if (*error != nullptr) {
511 return nullptr;
512 }
513 if (native_assets_api->dlsym == nullptr) {
514 return FfiResolveAssetFallback(thread, asset_type, path, symbol, error);
515 }
516 void* const result =
517 native_assets_api->dlsym(handle, symbol.ToCString(), error);
518 return result;
519}
520
521// Frees |error|.
522static void ThrowFfiResolveError(const String& symbol,
523 const String& asset,
524 char* error) {
525 const String& error_message = String::Handle(String::NewFormatted(
526 "Couldn't resolve native function '%s' in '%s' : %s.\n",
527 symbol.ToCString(), asset.ToCString(), error));
528 free(error);
529 Exceptions::ThrowArgumentError(error_message);
530}
531
532intptr_t FfiResolveInternal(const String& asset,
533 const String& symbol,
534 uintptr_t args_n,
535 char** error) {
536 Thread* thread = Thread::Current();
537 Zone* zone = thread->zone();
538
539 // Resolver resolution.
540 auto resolver = GetFfiNativeResolver(thread, asset);
541 if (resolver != nullptr) {
542 void* ffi_native_result = FfiResolveWithFfiNativeResolver(
543 thread, resolver, symbol, args_n, error);
544 return reinterpret_cast<intptr_t>(ffi_native_result);
545 }
546
547 // Native assets resolution.
548 const auto& asset_location =
549 Array::Handle(zone, GetAssetLocation(thread, asset));
550 if (!asset_location.IsNull()) {
551 void* asset_result = FfiResolveAsset(thread, asset_location, symbol, error);
552 return reinterpret_cast<intptr_t>(asset_result);
553 }
554
555 // Resolution in current process.
556#if !defined(DART_HOST_OS_WINDOWS)
558 RTLD_DEFAULT, symbol.ToCString(), error);
559#else
560 void* const result = LookupSymbolInProcess(symbol.ToCString(), error);
561#endif
562
563 if (*error != nullptr) {
564 // Process lookup failed, but the user might have tried to use native
565 // asset lookup. So augment the error message to include native assets info.
566 char* process_lookup_error = *error;
567 *error = OS::SCreate(/*use malloc*/ nullptr,
568 "No asset with id '%s' found. %s "
569 "Attempted to fallback to process lookup. %s",
570 asset.ToCString(), AvailableAssetsToCString(thread),
571 process_lookup_error);
572 free(process_lookup_error);
573 }
574
575 return reinterpret_cast<intptr_t>(result);
576}
577
578// FFI native C function pointer resolver.
579static intptr_t FfiResolve(Dart_Handle asset_handle,
580 Dart_Handle symbol_handle,
581 uintptr_t args_n) {
582 auto* const thread = Thread::Current();
583 DARTSCOPE(thread);
584 auto* const zone = thread->zone();
585 const String& asset = Api::UnwrapStringHandle(zone, asset_handle);
586 const String& symbol = Api::UnwrapStringHandle(zone, symbol_handle);
587 char* error = nullptr;
588
589 const intptr_t result = FfiResolveInternal(asset, symbol, args_n, &error);
590 if (error != nullptr) {
591 ThrowFfiResolveError(symbol, asset, error);
592 }
593 ASSERT(result != 0x0);
594 return result;
595}
596
597// Bootstrap to get the FFI Native resolver through a `native` call.
598DEFINE_NATIVE_ENTRY(Ffi_GetFfiNativeResolver, 1, 0) {
599 return Pointer::New(reinterpret_cast<intptr_t>(FfiResolve));
600}
601
602#endif // defined(USING_SIMULATOR) || \
603 // (defined(DART_PRECOMPILER) && !defined(TESTING))
604
605} // namespace dart
#define UNREACHABLE()
Definition: assert.h:248
#define RELEASE_ASSERT(cond)
Definition: assert.h:327
static const String & UnwrapStringHandle(const ReusableObjectHandleScope &reused, Dart_Handle object)
ObjectPtr At(intptr_t index) const
Definition: object.h:10875
static const Bool & Get(bool value)
Definition: object.h:10801
static DynamicLibraryPtr New(void *handle, bool canBeClosed, Heap::Space space=Heap::kNew)
Definition: object.cc:25749
static DART_NORETURN void ThrowStateError(const Instance &arg)
Definition: exceptions.cc:1088
static DART_NORETURN void ThrowUnsupportedError(const char *msg)
Definition: exceptions.cc:1106
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
Definition: exceptions.cc:1082
static IntegerPtr NewFromUint64(uint64_t value, Heap::Space space=Heap::kNew)
Definition: object.cc:23026
IsolateGroupSource * source() const
Definition: isolate.h:286
NativeAssetsApi * native_assets_api()
Definition: isolate.h:783
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition: object.cc:14599
Dart_FfiNativeResolver ffi_native_resolver() const
Definition: object.h:5250
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2
static ObjectPtr null()
Definition: object.h:433
ObjectPtr ptr() const
Definition: object.h:332
bool IsNull() const
Definition: object.h:363
static Object & Handle()
Definition: object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition: object.h:325
static PointerPtr New(uword native_address, Heap::Space space=Heap::kNew)
Definition: object.cc:25726
static StringPtr NewFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition: object.cc:24004
bool Equals(const String &str) const
Definition: object.h:13337
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition: object.cc:24126
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
IsolateGroup * isolate_group() const
Definition: thread.h:541
static void * LoadDynamicLibrary(const char *library_path, char **error=nullptr)
Definition: utils.cc:289
static void UnloadDynamicLibrary(void *library_handle, char **error=nullptr)
Definition: utils.cc:348
static void * ResolveSymbolInDynamicLibrary(void *library_handle, const char *symbol, char **error=nullptr)
Definition: utils.cc:322
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
void *(* Dart_FfiNativeResolver)(const char *name, uintptr_t args_n)
Definition: dart_api.h:3262
#define DARTSCOPE(thread)
Definition: dart_api_impl.h:77
#define ASSERT(E)
SkBitmap source
Definition: examples.cpp:28
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
size_t length
return FALSE
Definition: dart_vm.cc:33
static ArrayPtr GetAssetLocation(Thread *const thread, const String &asset)
static Dart_FfiNativeResolver GetFfiNativeResolver(Thread *const thread, const String &lib_url_str)
static void * FfiResolveAsset(Thread *const thread, const Array &asset_location, const String &symbol, char **error)
void * malloc(size_t size)
Definition: allocation.cc:19
static void * FfiResolveWithFfiNativeResolver(Thread *const thread, Dart_FfiNativeResolver resolver, const String &symbol, intptr_t args_n, char **error)
static char * AvailableAssetsToCString(Thread *const thread)
static void * FfiResolveAssetFallback(Thread *const thread, const String &asset_type, const String &path, const String &symbol, char **error)
static void ThrowFfiResolveError(const String &symbol, const String &asset, char *error)
uintptr_t uword
Definition: globals.h:501
static intptr_t FfiResolve(Dart_Handle asset_handle, Dart_Handle symbol_handle, uintptr_t args_n)
CStringUniquePtr ResolveUri(const char *ref_uri, const char *base_uri)
Definition: uri.cc:432
ArrayPtr GetNativeAssetsMap(Thread *thread)
static void * LoadDynamicLibrary(const char *library_file, char **error=nullptr)
const char * file_schema
const int file_schema_length
intptr_t FfiResolveInternal(const String &asset, const String &symbol, uintptr_t args_n, char **error)
DEFINE_NATIVE_ENTRY(List_allocate, 0, 2)
Definition: array.cc:13
static StringPtr GetPlatformScriptPath(Thread *thread)
static bool SymbolExists(void *handle, const char *symbol)
static void * ResolveSymbol(void *handle, const char *symbol, char **error)
static zx_koid_t GetCurrentProcessId()
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
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
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition: SkVx.h:680
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:74
SKWASM_EXPORT SkPath * path_copy(SkPath *path)
Definition: path.cpp:20
static void process(const char *inPath, const char *lexer, const char *token, const char *hPath, const char *cppPath)
Definition: Main.cpp:114
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
void * HANDLE
Definition: windows_types.h:36
unsigned long DWORD
Definition: windows_types.h:22
HINSTANCE HMODULE
Definition: windows_types.h:96