3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
5
#if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
6
- // TODO(dacoharkes): implement dynamic libraries for other targets.
7
- // see
8
- // - runtime/vm/native_symbol.h
9
- // - runtime/vm/native_symbol_linux.cc
10
- // - runtime/bin/extensions.h (but we cannot import from bin)
6
+ // TODO(dacoharkes): Implement dynamic libraries for other targets & merge the
7
+ // implementation with:
8
+ // - runtime/bin/extensions.h
11
9
// - runtime/bin/extensions_linux.cc
10
+ // TODO(dacoharkes): Make the code from bin available in a manner similar to
11
+ // runtime/vm/dart.h Dart_FileReadCallback.
12
12
#else
13
13
#include < dlfcn.h>
14
14
#endif
19
19
20
20
namespace dart {
21
21
22
- DEFINE_NATIVE_ENTRY (Ffi_dl_open, 0 , 1 ) {
23
- #if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
24
- UNREACHABLE ();
22
+ static void * LoadExtensionLibrary (const char * library_file) {
23
+ #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS)
24
+ void * handle = dlopen (library_file, RTLD_LAZY);
25
+ if (handle == nullptr ) {
26
+ char * error = dlerror ();
27
+ const String& msg = String::Handle (
28
+ String::NewFormatted (" Failed to load dynamic library (%s)" , error));
29
+ Exceptions::ThrowArgumentError (msg);
30
+ }
31
+
32
+ return handle;
33
+ #elif defined(TARGET_OS_WINDOWS)
34
+ SetLastError (0 ); // Clear any errors.
35
+
36
+ // Convert to wchar_t string.
37
+ const int name_len =
38
+ MultiByteToWideChar (CP_UTF8, 0 , library_file, -1 , NULL , 0 );
39
+ wchar_t * name = new wchar_t [name_len];
40
+ MultiByteToWideChar (CP_UTF8, 0 , library_file, -1 , name, name_len);
41
+
42
+ void * ext = LoadLibraryW (name);
43
+ delete[] name;
44
+
45
+ if (ext == nullptr ) {
46
+ const int error = GetLastError ();
47
+ const String& msg = String::Handle (
48
+ String::NewFormatted (" Failed to load dynamic library (%i)" , error));
49
+ Exceptions::ThrowArgumentError (msg);
50
+ }
51
+
52
+ return ext;
25
53
#else
54
+ const Array& args = Array::Handle (Array::New (1 ));
55
+ args.SetAt (0 ,
56
+ String::Handle (String::New (
57
+ " The dart:ffi library is not available on this platform." )));
58
+ Exceptions::ThrowByType (Exceptions::kUnsupported , args);
59
+ #endif
60
+ }
61
+
62
+ DEFINE_NATIVE_ENTRY (Ffi_dl_open, 0 , 1 ) {
26
63
GET_NON_NULL_NATIVE_ARGUMENT (String, lib_path, arguments->NativeArgAt (0 ));
27
64
65
+ void * handle = LoadExtensionLibrary (lib_path.ToCString ());
66
+
67
+ return DynamicLibrary::New (handle);
68
+ }
69
+
70
+ static void * ResolveSymbol (void * handle, const char * symbol) {
71
+ #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS)
28
72
dlerror (); // Clear any errors.
29
- void * handle = dlopen (lib_path. ToCString (), RTLD_LAZY );
30
- if (handle == nullptr ) {
73
+ void * pointer = dlsym (handle, symbol );
74
+ if (pointer == nullptr ) {
31
75
char * error = dlerror ();
32
76
const String& msg = String::Handle (
33
- String::NewFormatted (" Failed to load dynamic library(%s)" , error));
77
+ String::NewFormatted (" Failed to lookup symbol (%s)" , error));
78
+ Exceptions::ThrowArgumentError (msg);
79
+ }
80
+ return pointer;
81
+ #elif defined(TARGET_OS_WINDOWS)
82
+ SetLastError (0 );
83
+ void * pointer = GetProcAddress (reinterpret_cast <HMODULE>(handle), symbol);
84
+ if (pointer == nullptr ) {
85
+ const int error = GetLastError ();
86
+ const String& msg = String::Handle (
87
+ String::NewFormatted (" Failed to lookup symbol (%i)" , error));
34
88
Exceptions::ThrowArgumentError (msg);
35
89
}
36
-
37
- return DynamicLibrary::New (handle);
90
+ return pointer;
91
+ #else
92
+ const Array& args = Array::Handle (Array::New (1 ));
93
+ args.SetAt (0 ,
94
+ String::Handle (String::New (
95
+ " The dart:ffi library is not available on this platform." )));
96
+ Exceptions::ThrowByType (Exceptions::kUnsupported , args);
38
97
#endif
39
98
}
40
99
41
100
DEFINE_NATIVE_ENTRY (Ffi_dl_lookup, 1 , 2 ) {
42
- #if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
43
- UNREACHABLE ();
44
- #else
45
101
GET_NATIVE_TYPE_ARGUMENT (type_arg, arguments->NativeTypeArgAt (0 ));
46
102
47
103
GET_NON_NULL_NATIVE_ARGUMENT (DynamicLibrary, dlib, arguments->NativeArgAt (0 ));
@@ -50,22 +106,14 @@ DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
50
106
51
107
void * handle = dlib.GetHandle ();
52
108
53
- dlerror (); // Clear any errors.
54
- intptr_t pointer =
55
- reinterpret_cast <intptr_t >(dlsym (handle, argSymbolName.ToCString ()));
56
- char * error;
57
- if ((error = dlerror ()) != NULL ) {
58
- const String& msg = String::Handle (
59
- String::NewFormatted (" Failed to lookup symbol (%s)" , error));
60
- Exceptions::ThrowArgumentError (msg);
61
- }
109
+ const intptr_t pointer = reinterpret_cast <intptr_t >(
110
+ ResolveSymbol (handle, argSymbolName.ToCString ()));
62
111
63
- // TODO(dacoharkes): should this return NULL if addres is 0?
112
+ // TODO(dacoharkes): should this return Object::null() if address is 0?
64
113
// https://github.com/dart-lang/sdk/issues/35756
65
114
RawPointer* result =
66
115
Pointer::New (type_arg, Integer::Handle (zone, Integer::New (pointer)));
67
116
return result;
68
- #endif
69
117
}
70
118
71
119
DEFINE_NATIVE_ENTRY (Ffi_dl_getHandle, 0 , 1 ) {
0 commit comments