[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:
committed by
commit-bot@chromium.org
parent
7c7f6623a9
commit
7d467e8933
@@ -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.
|
||||
|
||||
@@ -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
@@ -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()));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)>();
|
||||
|
||||
Reference in New Issue
Block a user