Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit f6a5b29

Browse files
author
Dart CI
committed
Version 2.19.0-246.0.dev
Merge c04673f into dev
2 parents 57e7ca5 + c04673f commit f6a5b29

File tree

7 files changed

+104
-38
lines changed

7 files changed

+104
-38
lines changed

runtime/bin/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,9 @@ template("dart_executable") {
787787

788788
if (is_win) {
789789
libs = [
790+
# ole32.dll contains CoTaskMemAlloc. Here so that package:ffi can look
791+
# CoTaskMemAlloc up with `DynamicLibrary.process()`.
792+
"ole32.lib",
790793
"iphlpapi.lib",
791794
"psapi.lib",
792795
"ws2_32.lib",

runtime/lib/ffi_dynamic_library.cc

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
#include "platform/globals.h"
6+
#if defined(DART_HOST_OS_WINDOWS)
7+
#include <Psapi.h>
8+
#include <Windows.h>
9+
#include <combaseapi.h>
10+
#include <stdio.h>
11+
#include <tchar.h>
12+
#endif
13+
514
#include "include/dart_api.h"
615
#include "vm/bootstrap_natives.h"
716
#include "vm/exceptions.h"
@@ -15,7 +24,7 @@
1524

1625
namespace dart {
1726

18-
#if defined(USING_SIMULATOR)
27+
#if defined(USING_SIMULATOR) || defined(DART_PRECOMPILER)
1928

2029
DART_NORETURN static void SimulatorUnsupported() {
2130
Exceptions::ThrowUnsupportedError(
@@ -41,7 +50,7 @@ DEFINE_NATIVE_ENTRY(Ffi_dl_providesSymbol, 0, 2) {
4150
SimulatorUnsupported();
4251
}
4352

44-
#else // defined(USING_SIMULATOR)
53+
#else // defined(USING_SIMULATOR) || defined(DART_PRECOMPILER)
4554

4655
static void* LoadDynamicLibrary(const char* library_file) {
4756
char* error = nullptr;
@@ -56,9 +65,60 @@ static void* LoadDynamicLibrary(const char* library_file) {
5665
return handle;
5766
}
5867

68+
#if defined(DART_HOST_OS_WINDOWS)
69+
// On windows, nullptr signals trying a lookup in all loaded modules.
70+
const nullptr_t kWindowsDynamicLibraryProcessPtr = nullptr;
71+
72+
void* co_task_mem_alloced = nullptr;
73+
74+
void* LookupSymbolInProcess(const char* symbol, char** error) {
75+
// Force loading ole32.dll.
76+
if (co_task_mem_alloced == nullptr) {
77+
co_task_mem_alloced = CoTaskMemAlloc(sizeof(intptr_t));
78+
CoTaskMemFree(co_task_mem_alloced);
79+
}
80+
81+
HANDLE current_process =
82+
OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
83+
GetCurrentProcessId());
84+
if (current_process == nullptr) {
85+
*error = OS::SCreate(nullptr, "Failed to open current process.");
86+
return nullptr;
87+
}
88+
89+
HMODULE modules[1024];
90+
DWORD cb_needed;
91+
if (EnumProcessModules(current_process, modules, sizeof(modules),
92+
&cb_needed) != 0) {
93+
for (intptr_t i = 0; i < (cb_needed / sizeof(HMODULE)); i++) {
94+
if (auto result =
95+
reinterpret_cast<void*>(GetProcAddress(modules[i], symbol))) {
96+
CloseHandle(current_process);
97+
return result;
98+
}
99+
}
100+
}
101+
CloseHandle(current_process);
102+
103+
*error = OS::SCreate(
104+
nullptr,
105+
"None of the loaded modules contained the requested symbol '%s'.",
106+
symbol);
107+
return nullptr;
108+
}
109+
#endif
110+
59111
static void* ResolveSymbol(void* handle, const char* symbol) {
60112
char* error = nullptr;
61-
void* result = Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
113+
#if !defined(DART_HOST_OS_WINDOWS)
114+
void* const result =
115+
Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
116+
#else
117+
void* const result =
118+
handle == kWindowsDynamicLibraryProcessPtr
119+
? LookupSymbolInProcess(symbol, &error)
120+
: Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
121+
#endif
62122
if (error != nullptr) {
63123
const String& msg = String::Handle(String::NewFormatted(
64124
"Failed to lookup symbol '%s': %s", symbol, error));
@@ -70,7 +130,15 @@ static void* ResolveSymbol(void* handle, const char* symbol) {
70130

71131
static bool SymbolExists(void* handle, const char* symbol) {
72132
char* error = nullptr;
133+
#if !defined(DART_HOST_OS_WINDOWS)
73134
Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
135+
#else
136+
if (handle == nullptr) {
137+
LookupSymbolInProcess(symbol, &error);
138+
} else {
139+
Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
140+
}
141+
#endif
74142
if (error != nullptr) {
75143
free(error);
76144
return false;
@@ -91,8 +159,7 @@ DEFINE_NATIVE_ENTRY(Ffi_dl_processLibrary, 0, 0) {
91159
defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
92160
return DynamicLibrary::New(RTLD_DEFAULT);
93161
#else
94-
Exceptions::ThrowUnsupportedError(
95-
"DynamicLibrary.process is not available on this platform.");
162+
return DynamicLibrary::New(kWindowsDynamicLibraryProcessPtr);
96163
#endif
97164
}
98165

tests/ffi/has_symbol_test.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ void testHasSymbol() {
1919
Expect.isTrue(ffiTestFunctions.providesSymbol('ReturnMaxUint8'));
2020
Expect.isFalse(ffiTestFunctions.providesSymbol('SymbolNotInLibrary'));
2121

22-
if (Platform.isMacOS ||
23-
Platform.isIOS ||
24-
Platform.isAndroid ||
25-
Platform.isLinux) {
26-
DynamicLibrary p = DynamicLibrary.process();
22+
final p = DynamicLibrary.process();
23+
Expect.isFalse(p.providesSymbol('symbol_that_does_not_exist_in_process'));
24+
if (Platform.isWindows) {
25+
Expect.isTrue(p.providesSymbol('HeapAlloc'));
26+
Expect.isTrue(p.providesSymbol('CoTaskMemAlloc'));
27+
} else {
2728
Expect.isTrue(p.providesSymbol('dlopen'));
28-
Expect.isFalse(p.providesSymbol('symbol_that_does_not_exist_in_process'));
2929
}
3030

31-
DynamicLibrary e = DynamicLibrary.executable();
31+
final e = DynamicLibrary.executable();
3232
Expect.isTrue(e.providesSymbol('Dart_Invoke'));
3333
Expect.isFalse(e.providesSymbol('symbol_that_does_not_exist_in_executable'));
3434
}

tests/ffi/vmspecific_dynamic_library_test.dart

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,20 @@ typedef NativeDoubleUnOp = Double Function(Double);
3737
typedef DoubleUnOp = double Function(double);
3838

3939
void testLookup() {
40-
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
40+
final l = dlopenPlatformSpecific("ffi_test_dynamic_library");
4141
var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
4242
Expect.approxEquals(12.0, timesFour(3));
4343

44-
if (Platform.isMacOS ||
45-
Platform.isIOS ||
46-
Platform.isAndroid ||
47-
Platform.isLinux) {
44+
final p = DynamicLibrary.process();
45+
if (Platform.isWindows) {
46+
Expect.isTrue(p.lookup<Void>("HeapAlloc") != nullptr);
47+
Expect.isTrue(p.lookup<Void>("CoTaskMemAlloc") != nullptr);
48+
} else {
4849
// Lookup a symbol from 'libc' since it's loaded with global visibility.
49-
DynamicLibrary p = DynamicLibrary.process();
5050
Expect.isTrue(p.lookup<Void>("strcmp") != nullptr);
51-
} else {
52-
Expect.throws<UnsupportedError>(() => DynamicLibrary.process());
5351
}
5452

55-
DynamicLibrary e = DynamicLibrary.executable();
53+
final e = DynamicLibrary.executable();
5654
Expect.isTrue(e.lookup("Dart_Invoke") != nullptr);
5755
}
5856

tests/ffi_2/has_symbol_test.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ void testHasSymbol() {
2121
Expect.isTrue(ffiTestFunctions.providesSymbol('ReturnMaxUint8'));
2222
Expect.isFalse(ffiTestFunctions.providesSymbol('SymbolNotInLibrary'));
2323

24-
if (Platform.isMacOS ||
25-
Platform.isIOS ||
26-
Platform.isAndroid ||
27-
Platform.isLinux) {
28-
DynamicLibrary p = DynamicLibrary.process();
24+
final p = DynamicLibrary.process();
25+
Expect.isFalse(p.providesSymbol('symbol_that_does_not_exist_in_process'));
26+
if (Platform.isWindows) {
27+
Expect.isTrue(p.providesSymbol('HeapAlloc'));
28+
Expect.isTrue(p.providesSymbol('CoTaskMemAlloc'));
29+
} else {
2930
Expect.isTrue(p.providesSymbol('dlopen'));
30-
Expect.isFalse(p.providesSymbol('symbol_that_does_not_exist_in_process'));
3131
}
3232

33-
DynamicLibrary e = DynamicLibrary.executable();
33+
final e = DynamicLibrary.executable();
3434
Expect.isTrue(e.providesSymbol('Dart_Invoke'));
3535
Expect.isFalse(e.providesSymbol('symbol_that_does_not_exist_in_executable'));
3636
}

tests/ffi_2/vmspecific_dynamic_library_test.dart

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,20 @@ typedef NativeDoubleUnOp = Double Function(Double);
3939
typedef DoubleUnOp = double Function(double);
4040

4141
void testLookup() {
42-
DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
42+
final l = dlopenPlatformSpecific("ffi_test_dynamic_library");
4343
var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
4444
Expect.approxEquals(12.0, timesFour(3));
4545

46-
if (Platform.isMacOS ||
47-
Platform.isIOS ||
48-
Platform.isAndroid ||
49-
Platform.isLinux) {
46+
final p = DynamicLibrary.process();
47+
if (Platform.isWindows) {
48+
Expect.isTrue(p.lookup<Void>("HeapAlloc") != nullptr);
49+
Expect.isTrue(p.lookup<Void>("CoTaskMemAlloc") != nullptr);
50+
} else {
5051
// Lookup a symbol from 'libc' since it's loaded with global visibility.
51-
DynamicLibrary p = DynamicLibrary.process();
5252
Expect.isTrue(p.lookup<Void>("strcmp") != nullptr);
53-
} else {
54-
Expect.throws<UnsupportedError>(() => DynamicLibrary.process());
5553
}
5654

57-
DynamicLibrary e = DynamicLibrary.executable();
55+
final e = DynamicLibrary.executable();
5856
Expect.isTrue(e.lookup("Dart_Invoke") != nullptr);
5957
}
6058

tools/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ CHANNEL dev
2727
MAJOR 2
2828
MINOR 19
2929
PATCH 0
30-
PRERELEASE 245
30+
PRERELEASE 246
3131
PRERELEASE_PATCH 0

0 commit comments

Comments
 (0)