[vm] Adds args_n to FFI resolver.

This makes it more closely mirror the Dart_NativeEntryResolver,
and acts as an extra sanity check that signatures (roughly)
align between the FfiNative decl. and the native function.

TEST=Updated runtime/vm/dart_api_impl_test.cc

Change-Id: I40799dc583ec14db14dc453afed4e2d1eb06fced
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212566
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
Clement Skau
2021-09-13 07:57:00 +00:00
committed by commit-bot@chromium.org
parent 7c7f6623a9
commit 7d467e8933
6 changed files with 22 additions and 15 deletions
+7 -3
View File
@@ -102,22 +102,26 @@ class FfiNativeTransformer extends Transformer {
final DartType dartType =
node.function.computeThisFunctionType(Nullability.nonNullable);
// Double Function(Double)
final nativeType = annotationConst.typeArguments[0];
final nativeType = annotationConst.typeArguments[0] as FunctionType;
// InterfaceType(NativeFunction<Double Function(Double)>*)
final DartType nativeInterfaceType =
InterfaceType(nativeFunctionClass, Nullability.legacy, [nativeType]);
// Derive number of arguments from the native function signature.
final args_n = nativeType.positionalParameters.length;
// TODO(dartbug.com/31579): Add `..fileOffset`s once we can handle these in
// patch files.
// _ffi_resolver('dart:math', 'Math_sqrt')
// _ffi_resolver('dart:math', 'Math_sqrt', 1)
final resolverInvocation = FunctionInvocation(
FunctionAccessKind.FunctionType,
StaticGet(resolverField),
Arguments([
ConstantExpression(
StringConstant(currentLibrary!.importUri.toString())),
ConstantExpression(functionName)
ConstantExpression(functionName),
ConstantExpression(IntConstant(args_n)),
]),
functionType: resolverField.type as FunctionType);
@@ -1094,11 +1094,11 @@ intptr_t ReturnIntPtr(intptr_t x) {
return x;
}
static void* FfiNativeResolver(const char* name) {
if (strcmp(name, "ReturnIntPtr") == 0) {
static void* FfiNativeResolver(const char* name, uintptr_t args_n) {
if (strcmp(name, "ReturnIntPtr") == 0 && args_n == 1) {
return reinterpret_cast<void*>(ReturnIntPtr);
}
if (strcmp(name, "IsThreadInGenerated") == 0) {
if (strcmp(name, "IsThreadInGenerated") == 0 && args_n == 0) {
return reinterpret_cast<void*>(IsThreadInGenerated);
}
// This should be unreachable in tests.
+1 -1
View File
@@ -3046,7 +3046,7 @@ typedef const uint8_t* (*Dart_NativeEntrySymbol)(Dart_NativeFunction nf);
*
* See Dart_SetFfiNativeResolver.
*/
typedef void* (*Dart_FfiNativeResolver)(const char* name);
typedef void* (*Dart_FfiNativeResolver)(const char* name, uintptr_t args_n);
/*
* ===========
+4 -2
View File
@@ -276,7 +276,9 @@ DEFINE_NATIVE_ENTRY(DartApiDLInitializeData, 0, 0) {
}
// FFI native C function pointer resolver.
static intptr_t FfiResolve(Dart_Handle lib_url, Dart_Handle name) {
static intptr_t FfiResolve(Dart_Handle lib_url,
Dart_Handle name,
uintptr_t args_n) {
DARTSCOPE(Thread::Current());
const String& lib_url_str = Api::UnwrapStringHandle(T->zone(), lib_url);
@@ -296,7 +298,7 @@ static intptr_t FfiResolve(Dart_Handle lib_url, Dart_Handle name) {
Exceptions::ThrowArgumentError(error);
}
auto* f = resolver(function_name.ToCString());
auto* f = resolver(function_name.ToCString(), args_n);
if (f == nullptr) {
const String& error = String::Handle(String::NewFormatted(
"Couldn't resolve function: '%s'.", function_name.ToCString()));
+3 -2
View File
@@ -9585,8 +9585,9 @@ static intptr_t EchoInt(double x) {
return x;
}
static void* FfiNativeResolver(const char* name) {
static void* FfiNativeResolver(const char* name, uintptr_t args_n) {
ASSERT(strcmp(name, "EchoInt") == 0);
ASSERT(args_n == 1);
return reinterpret_cast<void*>(EchoInt);
}
@@ -9628,7 +9629,7 @@ TEST_CASE(Dart_SetFfiNativeResolver_MissingResolver) {
"Invalid argument(s): Library has no handler: 'file:///test-lib'.");
}
static void* NopResolver(const char* name) {
static void* NopResolver(const char* name, uintptr_t args_n) {
return nullptr;
}
+4 -4
View File
@@ -824,11 +824,11 @@ class FfiNative<T> {
// Bootstrapping native for getting the FFI native C function pointer to look
// up the FFI resolver.
@pragma("vm:external-name", "Ffi_GetFfiNativeResolver")
external Pointer<NativeFunction<IntPtr Function(Handle, Handle)>>
external Pointer<NativeFunction<IntPtr Function(Handle, Handle, IntPtr)>>
_get_ffi_native_resolver<T extends NativeFunction>();
// Resolver for FFI Native C function pointers.
@pragma('vm:entry-point')
final _ffi_resolver =
_get_ffi_native_resolver<NativeFunction<IntPtr Function(Handle, Handle)>>()
.asFunction<int Function(Object, Object)>();
final _ffi_resolver = _get_ffi_native_resolver<
NativeFunction<IntPtr Function(Handle, Handle, IntPtr)>>()
.asFunction<int Function(Object, Object, int)>();