diff --git a/runtime/bin/ffi_test_functions.cc b/runtime/bin/ffi_test_functions.cc index 28687ca6030..5d95e49c165 100644 --- a/runtime/bin/ffi_test_functions.cc +++ b/runtime/bin/ffi_test_functions.cc @@ -4,17 +4,13 @@ // This file contains test functions for the dart:ffi test cases. +// The tests which use this don't run on Windows yet. +#if !defined(_WIN32) + #include #include #include - -#include "platform/globals.h" -#if defined(HOST_OS_WINDOWS) -#include -#else #include -#endif - #include #include @@ -410,7 +406,6 @@ DART_EXPORT void* SmallPointer() { return reinterpret_cast(-0x80000000L); } -#if !defined(_WIN32) DART_EXPORT int RedirectStderr() { char filename[256]; snprintf(filename, sizeof(filename), "/tmp/captured_stderr_%d", getpid()); @@ -418,6 +413,7 @@ DART_EXPORT int RedirectStderr() { printf("Got file %s\n", filename); return getpid(); } -#endif } // namespace dart + +#endif diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc index d084216e2ca..4186a1e6d1c 100644 --- a/runtime/lib/ffi.cc +++ b/runtime/lib/ffi.cc @@ -500,9 +500,9 @@ static RawCode* TrampolineCode(const Function& function, #elif !defined(TARGET_ARCH_X64) // https://github.com/dart-lang/sdk/issues/35774 UNREACHABLE(); -#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) && \ - !defined(TARGET_OS_WINDOWS) +#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android + // https://github.com/dart-lang/sdk/issues/35771 Windows // https://github.com/dart-lang/sdk/issues/35772 Arm64 // https://github.com/dart-lang/sdk/issues/35773 DBC UNREACHABLE(); @@ -588,9 +588,9 @@ static void* GenerateFfiInverseTrampoline(const Function& signature, #elif !defined(TARGET_ARCH_X64) // https://github.com/dart-lang/sdk/issues/35774 UNREACHABLE(); -#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) && \ - !defined(TARGET_OS_WINDOWS) +#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android + // https://github.com/dart-lang/sdk/issues/35771 Windows // https://github.com/dart-lang/sdk/issues/35772 Arm64 // https://github.com/dart-lang/sdk/issues/35773 DBC UNREACHABLE(); diff --git a/runtime/lib/ffi_dynamic_library.cc b/runtime/lib/ffi_dynamic_library.cc index 6d2f2af74f7..3af92da7838 100644 --- a/runtime/lib/ffi_dynamic_library.cc +++ b/runtime/lib/ffi_dynamic_library.cc @@ -3,12 +3,12 @@ // BSD-style license that can be found in the LICENSE file. #if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) -// TODO(dacoharkes): Implement dynamic libraries for other targets & merge the -// implementation with: -// - runtime/bin/extensions.h +// TODO(dacoharkes): implement dynamic libraries for other targets. +// see +// - runtime/vm/native_symbol.h +// - runtime/vm/native_symbol_linux.cc +// - runtime/bin/extensions.h (but we cannot import from bin) // - runtime/bin/extensions_linux.cc -// TODO(dacoharkes): Make the code from bin available in a manner similar to -// runtime/vm/dart.h Dart_FileReadCallback. #else #include #endif @@ -19,81 +19,29 @@ namespace dart { -static void* LoadExtensionLibrary(const char* library_file) { -#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) - void* handle = dlopen(library_file, RTLD_LAZY); +DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) { +#if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) + UNREACHABLE(); +#else + GET_NON_NULL_NATIVE_ARGUMENT(String, lib_path, arguments->NativeArgAt(0)); + + dlerror(); // Clear any errors. + void* handle = dlopen(lib_path.ToCString(), RTLD_LAZY); if (handle == nullptr) { char* error = dlerror(); const String& msg = String::Handle( - String::NewFormatted("Failed to load dynamic library (%s)", error)); + String::NewFormatted("Failed to load dynamic library(%s)", error)); Exceptions::ThrowArgumentError(msg); } - return handle; -#elif defined(TARGET_OS_WINDOWS) - SetLastError(0); // Clear any errors. - - // Convert to wchar_t string. - const int name_len = - MultiByteToWideChar(CP_UTF8, 0, library_file, -1, NULL, 0); - wchar_t* name = new wchar_t[name_len]; - MultiByteToWideChar(CP_UTF8, 0, library_file, -1, name, name_len); - - void* ext = LoadLibraryW(name); - delete[] name; - - if (ext == nullptr) { - const int error = GetLastError(); - const String& msg = String::Handle( - String::NewFormatted("Failed to load dynamic library (%i)", error)); - Exceptions::ThrowArgumentError(msg); - } - - return ext; -#else - const auto& message = - String::Handle("The dart:ffi library is not available on this platform."); - Exceptions::ThrowByType(Exceptions::kUnsupported, message); -#endif -} - -DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) { - GET_NON_NULL_NATIVE_ARGUMENT(String, lib_path, arguments->NativeArgAt(0)); - - void* handle = LoadExtensionLibrary(lib_path.ToCString()); - return DynamicLibrary::New(handle); -} - -static void* ResolveSymbol(void* handle, const char* symbol) { -#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) - dlerror(); // Clear any errors. - void* pointer = dlsym(handle, symbol); - if (pointer == nullptr) { - char* error = dlerror(); - const String& msg = String::Handle( - String::NewFormatted("Failed to lookup symbol (%s)", error)); - Exceptions::ThrowArgumentError(msg); - } - return pointer; -#elif defined(TARGET_OS_WINDOWS) - SetLastError(0); - void* pointer = GetProcAddress(reinterpret_cast(handle), symbol); - if (pointer == nullptr) { - const int error = GetLastError(); - const String& msg = String::Handle( - String::NewFormatted("Failed to lookup symbol (%i)", error)); - Exceptions::ThrowArgumentError(msg); - } - return pointer; -#else - const auto& message = - String::Handle("The dart:ffi library is not available on this platform."); - Exceptions::ThrowByType(Exceptions::kUnsupported, message); #endif } DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) { +#if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) + UNREACHABLE(); +#else GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0)); GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0)); @@ -102,14 +50,22 @@ DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) { void* handle = dlib.GetHandle(); - const intptr_t pointer = reinterpret_cast( - ResolveSymbol(handle, argSymbolName.ToCString())); + dlerror(); // Clear any errors. + intptr_t pointer = + reinterpret_cast(dlsym(handle, argSymbolName.ToCString())); + char* error; + if ((error = dlerror()) != NULL) { + const String& msg = String::Handle( + String::NewFormatted("Failed to lookup symbol (%s)", error)); + Exceptions::ThrowArgumentError(msg); + } - // TODO(dacoharkes): should this return Object::null() if address is 0? + // TODO(dacoharkes): should this return NULL if addres is 0? // https://github.com/dart-lang/sdk/issues/35756 RawPointer* result = Pointer::New(type_arg, Integer::Handle(zone, Integer::New(pointer))); return result; +#endif } DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) { diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h index 0bdeec520c9..f8263237da1 100644 --- a/runtime/vm/dart_api_impl.h +++ b/runtime/vm/dart_api_impl.h @@ -300,9 +300,9 @@ class Api : AllStatic { #if !defined(TARGET_ARCH_X64) // https://github.com/dart-lang/sdk/issues/35774 return false; -#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) && \ - !defined(TARGET_OS_WINDOWS) +#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS) // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android + // https://github.com/dart-lang/sdk/issues/35771 Windows // https://github.com/dart-lang/sdk/issues/35772 Arm64 // https://github.com/dart-lang/sdk/issues/35773 DBC return false; diff --git a/samples/ffi/dylib_utils.dart b/samples/ffi/dylib_utils.dart index 1c924d4a838..1929961e35f 100644 --- a/samples/ffi/dylib_utils.dart +++ b/samples/ffi/dylib_utils.dart @@ -9,7 +9,6 @@ String _platformPath(String name, {String path}) { if (path == null) path = ""; if (Platform.isLinux) return path + "lib" + name + ".so"; if (Platform.isMacOS) return path + "lib" + name + ".dylib"; - if (Platform.isWindows) return path + name + ".dll"; throw Exception("Platform not implemented"); } diff --git a/tests/standalone_2/ffi/dylib_utils.dart b/tests/standalone_2/ffi/dylib_utils.dart index 1c924d4a838..1929961e35f 100644 --- a/tests/standalone_2/ffi/dylib_utils.dart +++ b/tests/standalone_2/ffi/dylib_utils.dart @@ -9,7 +9,6 @@ String _platformPath(String name, {String path}) { if (path == null) path = ""; if (Platform.isLinux) return path + "lib" + name + ".so"; if (Platform.isMacOS) return path + "lib" + name + ".dylib"; - if (Platform.isWindows) return path + name + ".dll"; throw Exception("Platform not implemented"); } diff --git a/tests/standalone_2/ffi/function_stress_test.dart b/tests/standalone_2/ffi/function_stress_test.dart index 46e716fb1ed..2f5f02c5120 100644 --- a/tests/standalone_2/ffi/function_stress_test.dart +++ b/tests/standalone_2/ffi/function_stress_test.dart @@ -32,7 +32,7 @@ test(GCWatcher watcher, void Function() testee, } main() async { - final watcher = GCWatcher.ifAvailable(); + final watcher = GCWatcher(); try { await test(watcher, testBoxInt64); // On 64-bit platforms this won't trigger GC because the result fits into a diff --git a/tests/standalone_2/ffi/gc_helper.dart b/tests/standalone_2/ffi/gc_helper.dart index 5e9431d2d63..084a0ceaaee 100644 --- a/tests/standalone_2/ffi/gc_helper.dart +++ b/tests/standalone_2/ffi/gc_helper.dart @@ -3,48 +3,25 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:io'; +import 'dart:convert'; import 'dylib_utils.dart'; import 'dart:ffi'; -import 'dart:io' show Platform; DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions"); -abstract class GCWatcher { - factory GCWatcher() => _GCWatcherImpl(); - factory GCWatcher.dummy() => _MockGCWatcher(); - factory GCWatcher.ifAvailable() => - Platform.isWindows ? GCWatcher.dummy() : GCWatcher(); - - Future size(); - void dispose(); -} - // Requires --verbose-gc. -class _GCWatcherImpl implements GCWatcher { +class GCWatcher { int _suffix; Future size() async { return await File("/tmp/captured_stderr_$_suffix").length(); } - _GCWatcherImpl() { + GCWatcher() { print("Starting..."); _suffix = ffiTestFunctions .lookupFunction("RedirectStderr")(); } - dispose() { - try { - File("/tmp/captured_stderr_$_suffix").deleteSync(); - } catch (e) { - print("deleting file failed"); - } - } -} - -class _MockGCWatcher implements GCWatcher { - int _ctr = 0; - - Future size() async => ++_ctr; - dispose() {} + dispose() => File("/tmp/captured_stderr_$_suffix").deleteSync(); } diff --git a/tests/standalone_2/ffi/subtype_test.dart b/tests/standalone_2/ffi/subtype_test.dart index 22dbe131a2f..dd466ae675d 100644 --- a/tests/standalone_2/ffi/subtype_test.dart +++ b/tests/standalone_2/ffi/subtype_test.dart @@ -39,7 +39,7 @@ Future testGC() async { CString cs = ffi.fromAddress(11); bar = cs; foo = ""; - final watcher = GCWatcher.ifAvailable(); + final watcher = GCWatcher(); int counts = await watcher.size(); for (int i = 0; i < 1000000; ++i) { foo = new X(i); diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status index 31ebd3db2ab..a68bdd79a5a 100644 --- a/tests/standalone_2/standalone_2_kernel.status +++ b/tests/standalone_2/standalone_2_kernel.status @@ -229,8 +229,8 @@ io/socket_many_connections_test: Skip # Timeout io/web_socket_compression_test: Skip # Timeout io/web_socket_test: Skip # Timeout -[ $arch != x64 || $compiler != dartk || $mode == product || $system != linux && $system != macos ] -ffi/function_stress_test: SkipByDesign # FFI must be supported. Also requires --verbose-gc, which isn't included in product. Windows issues will be fixed in IL CL: https://github.com/dart-lang/sdk/issues/36138 +[ $arch != x64 || $compiler != dartk || $mode == product || $system != linux && $system != macos] +ffi/function_stress_test: SkipByDesign # FFI must be supported. Also requires --verbose-gc, which isn't included in product. ffi/subtype_test: SkipByDesign # FFI must be supported. Also requires --verbose-gc, which isn't included in product. [ $mode == product || $mode != product ] diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status index 1cb8be7b552..49b61dc272a 100644 --- a/tests/standalone_2/standalone_2_vm.status +++ b/tests/standalone_2/standalone_2_vm.status @@ -133,5 +133,5 @@ full_coverage_test: Skip # TODO(vegorov) SIMDBC interpreter doesn't support cove link_natives_lazily_test: SkipByDesign # SIMDBC interpreter doesn't support lazy linking of natives. no_lazy_dispatchers_test: SkipByDesign # SIMDBC interpreter doesn't support --no_lazy_dispatchers -[ $arch != x64 || $system != linux && $system != macos && $system != windows ] +[ $arch != x64 || $system != linux && $system != macos ] ffi: Skip # ffi not yet supported on other systems than linux/macos 64