[vm/ffi] Remove platform specific logic from DynamicLibrary.open

Change-Id: Id69e17563c4d64f6ead5e143077a7364520f65a0
Reviewed-on: https://dart-review.googlesource.com/c/93173
Auto-Submit: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Samir Jindel <sjindel@google.com>
Commit-Queue: Samir Jindel <sjindel@google.com>
This commit is contained in:
Daco Harkes 2019-02-14 16:08:28 +00:00 committed by commit-bot@chromium.org
parent 6a5c9597c6
commit 3abc7d34d7
12 changed files with 75 additions and 58 deletions

View file

@ -19,51 +19,14 @@
namespace dart {
// Concatenates a NULL terminated array of strings.
// The returned string is scope allocated.
// TODO(dacoharkes): Can we share this with runtime/bin/extensions.cc?
const char* Concatenate(const char** strings) {
int size = 1; // null termination.
for (int i = 0; strings[i] != NULL; i++) {
size += strlen(strings[i]);
}
char* result = reinterpret_cast<char*>(Dart_ScopeAllocate(size));
int index = 0;
for (int i = 0; strings[i] != NULL; i++) {
index += snprintf(result + index, size - index, "%s", strings[i]);
}
ASSERT(index == size - 1);
ASSERT(result[size - 1] == '\0');
return result;
}
// TODO(dacoharkes): Can we share this with runtime/bin/extensions.cc?
const char* LibraryPath(const char* library_name) {
const char* library_prefix = "lib";
#if defined(TARGET_OS_LINUX)
const char* library_extension = "so";
#elif defined(TARGET_OS_MACOS)
const char* library_extension = "dylib";
#else
const char* library_extension = "";
UNREACHABLE();
#endif
const char* path_components[] = {
library_prefix, library_name, ".", library_extension, NULL,
};
return Concatenate(path_components);
}
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, argName, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(String, lib_path, arguments->NativeArgAt(0));
dlerror(); // Clear any errors.
void* handle = dlopen(LibraryPath(argName.ToCString()), RTLD_LAZY);
void* handle = dlopen(lib_path.ToCString(), RTLD_LAZY);
if (handle == nullptr) {
char* error = dlerror();
const String& msg = String::Handle(

View file

@ -0,0 +1,18 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:ffi' as ffi;
import 'dart:io' show Platform;
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";
throw Exception("Platform not implemented");
}
ffi.DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
String fullPath = _platformPath(name, path: path);
return ffi.DynamicLibrary.open(fullPath);
}

View file

@ -4,12 +4,14 @@
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
typedef DoubleUnOp = double Function(double);
main(List<String> arguments) {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
print(l);
print(l.runtimeType);

View file

@ -4,6 +4,8 @@
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
typedef NativeUnaryOp = ffi.Int32 Function(ffi.Int32);
typedef NativeBinaryOp = ffi.Int32 Function(ffi.Int32, ffi.Int32);
typedef UnaryOp = int Function(int);
@ -93,7 +95,7 @@ main(List<String> arguments) {
print('start main');
ffi.DynamicLibrary ffiTestFunctions =
ffi.DynamicLibrary.open("ffi_test_functions");
dlopenPlatformSpecific("ffi_test_functions");
{
// int32 bin op

View file

@ -4,6 +4,8 @@
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
import 'coordinate.dart';
typedef NativeCoordinateOp = Coordinate Function(Coordinate);
@ -33,7 +35,7 @@ main(List<String> arguments) {
print('start main');
ffi.DynamicLibrary ffiTestFunctions =
ffi.DynamicLibrary.open("ffi_test_functions");
dlopenPlatformSpecific("ffi_test_functions");
{
// pass a c pointer to a c function as an argument to a c function

View file

@ -4,6 +4,8 @@
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
import 'coordinate.dart';
typedef NativeCoordinateOp = Coordinate Function(Coordinate);
@ -12,7 +14,7 @@ main(List<String> arguments) {
print('start main');
ffi.DynamicLibrary ffiTestFunctions =
ffi.DynamicLibrary.open("ffi_test_functions");
dlopenPlatformSpecific("ffi_test_functions");
{
// pass a struct to a c function and get a struct as return value

View file

@ -0,0 +1,18 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:ffi' as ffi;
import 'dart:io' show Platform;
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";
throw Exception("Platform not implemented");
}
ffi.DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
String fullPath = _platformPath(name, path: path);
return ffi.DynamicLibrary.open(fullPath);
}

View file

@ -8,6 +8,8 @@ library FfiTest;
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
import 'package:expect/expect.dart';
void main() {
@ -20,13 +22,13 @@ void main() {
}
void testOpen() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Expect.notEquals(null, l);
}
void testOpenError() {
Expect.throws(
() => ffi.DynamicLibrary.open("doesnotexistforsurelibrary123409876"));
() => dlopenPlatformSpecific("doesnotexistforsurelibrary123409876"));
}
typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
@ -34,30 +36,30 @@ typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
typedef DoubleUnOp = double Function(double);
void testLookup() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
Expect.approxEquals(12.0, timesFour(3));
}
void testLookupError() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Expect.throws(() => l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>(
"functionnamethatdoesnotexistforsure749237593845"));
}
void testToString() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Expect.stringEquals(
"DynamicLibrary: handle=0x", l.toString().substring(0, 25));
}
void testEquality() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l2 = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
ffi.DynamicLibrary l2 = dlopenPlatformSpecific("ffi_test_dynamic_library");
Expect.equals(l, l2);
Expect.equals(l.hashCode, l2.hashCode);
Expect.notEquals(l, null);
Expect.notEquals(null, l);
ffi.DynamicLibrary l3 = ffi.DynamicLibrary.open("ffi_test_functions");
ffi.DynamicLibrary l3 = dlopenPlatformSpecific("ffi_test_functions");
Expect.notEquals(l, l3);
}

View file

@ -8,6 +8,8 @@ library FfiTest;
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
import "package:expect/expect.dart";
import 'coordinate.dart';
@ -24,7 +26,7 @@ void main() {
}
ffi.DynamicLibrary ffiTestFunctions =
ffi.DynamicLibrary.open("ffi_test_functions");
dlopenPlatformSpecific("ffi_test_functions");
/// pass a pointer to a c function as an argument to a c function
void testFunctionWithFunctionPointer() {

View file

@ -9,6 +9,8 @@ library FfiTest;
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
import "package:expect/expect.dart";
import 'coordinate.dart';
@ -23,7 +25,7 @@ void main() {
}
ffi.DynamicLibrary ffiTestFunctions =
ffi.DynamicLibrary.open("ffi_test_functions");
dlopenPlatformSpecific("ffi_test_functions");
/// pass a struct to a c function and get a struct as return value
void testFunctionWithStruct() {

View file

@ -8,6 +8,8 @@ library FfiTest;
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
import "package:expect/expect.dart";
void main() {
@ -29,7 +31,7 @@ void main() {
}
ffi.DynamicLibrary ffiTestFunctions =
ffi.DynamicLibrary.open("ffi_test_functions");
dlopenPlatformSpecific("ffi_test_functions");
typedef NativeBinaryOp = ffi.Int32 Function(ffi.Int32, ffi.Int32);
typedef UnaryOp = int Function(int);

View file

@ -8,6 +8,8 @@ library FfiTest;
import 'dart:ffi' as ffi;
import 'dylib_utils.dart';
void main() {
testGetGeneric();
testGetGeneric2();
@ -245,7 +247,7 @@ void testFromFunctionTearOff() {
void testLookupFunctionGeneric() {
Function generic<T extends Function>() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Function result;
result = l.lookupFunction<T, DoubleUnOp>("cos"); //# 15: compile-time error
return result;
@ -256,7 +258,7 @@ void testLookupFunctionGeneric() {
void testLookupFunctionGeneric2() {
Function generic<T extends Function>() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
Function result;
result = //# 16: compile-time error
l.lookupFunction<NativeDoubleUnOp, T>("cos"); //# 16: compile-time error
@ -267,12 +269,12 @@ void testLookupFunctionGeneric2() {
}
void testLookupFunctionWrongNativeFunctionSignature() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
l.lookupFunction<IntUnOp, IntUnOp>("cos"); //# 17: compile-time error
}
void testLookupFunctionTypeMismatch() {
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
l.lookupFunction<NativeDoubleUnOp, IntUnOp>("cos"); //# 18: compile-time error
}