[vm/ffi] void functions
Change-Id: I1544e0985d934dfa354143764dee61feb08b2592
Reviewed-on: https://dart-review.googlesource.com/c/93422
Auto-Submit: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Samir Jindel <sjindel@google.com>
Commit-Queue: Samir Jindel <sjindel@google.com>
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 4b93041..ba4e06d 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -138,6 +138,7 @@
/// [IntPtr] -> [int]
/// [Double] -> [double]
/// [Float] -> [double]
+ /// [Void] -> [void]
/// [Pointer]<T> -> [Pointer]<T>
/// T extends [Pointer] -> T
/// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
@@ -162,6 +163,9 @@
if (nativeType_ == NativeType.kFloat || nativeType_ == NativeType.kDouble) {
return InterfaceType(doubleClass);
}
+ if (nativeType_ == NativeType.kVoid) {
+ return VoidType();
+ }
if (nativeType_ == NativeType.kNativeFunction) {
DartType fun = (nativeType as InterfaceType).typeArguments[0];
if (fun is FunctionType) {
diff --git a/runtime/bin/ffi_test_functions.cc b/runtime/bin/ffi_test_functions.cc
index 0248829..d21ba52 100644
--- a/runtime/bin/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test_functions.cc
@@ -365,4 +365,20 @@
return retval;
}
+// Does nothing with input.
+// Used for testing functions that return void
+DART_EXPORT void DevNullFloat(float a) {
+ std::cout << "DevNullFloat(" << a << ")\n";
+ std::cout << "returning nothing\n";
+}
+
+// Invents an elite floating point number.
+// Used for testing functions that do not take any arguments.
+DART_EXPORT float InventFloatValue() {
+ std::cout << "InventFloatValue()\n";
+ float retval = 1337.0f;
+ std::cout << "returning " << retval << "\n";
+ return retval;
+}
+
} // namespace dart
diff --git a/runtime/vm/ffi_trampoline_stubs_x64.cc b/runtime/vm/ffi_trampoline_stubs_x64.cc
index 9374f61..001c68d 100644
--- a/runtime/vm/ffi_trampoline_stubs_x64.cc
+++ b/runtime/vm/ffi_trampoline_stubs_x64.cc
@@ -4,6 +4,7 @@
// TODO(dacoharkes): Move this into compiler namespace.
+#include "vm/class_id.h"
#include "vm/globals.h"
#include "vm/stub_code.h"
@@ -391,6 +392,9 @@
const AbstractType& result_type,
Address closure_dart) {
switch (result_type.type_class_id()) {
+ case kFfiVoidCid:
+ __ LoadObject(RAX, Object::null_object());
+ return;
case kFfiInt8Cid:
case kFfiInt16Cid:
case kFfiInt32Cid:
diff --git a/tests/standalone_2/ffi/function_test.dart b/tests/standalone_2/ffi/function_test.dart
index dacce5d..c2019f7 100644
--- a/tests/standalone_2/ffi/function_test.dart
+++ b/tests/standalone_2/ffi/function_test.dart
@@ -28,6 +28,8 @@
testNullManyArgs();
testNullPointers();
testFloatRounding();
+ testVoidReturn();
+ testNoArgs();
}
ffi.DynamicLibrary ffiTestFunctions =
@@ -284,3 +286,28 @@
p2.free();
}
+
+typedef NativeFloatToVoid = ffi.Void Function(ffi.Float);
+typedef DoubleToVoid = void Function(double);
+
+void testVoidReturn() {
+ DoubleToVoid devNullFloat = ffiTestFunctions
+ .lookupFunction<NativeFloatToVoid, DoubleToVoid>("DevNullFloat");
+
+ devNullFloat(1337.0);
+
+ dynamic loseSignature = devNullFloat;
+ dynamic result = loseSignature(1337.0);
+ Expect.isNull(result);
+}
+
+typedef NativeVoidToFloat = ffi.Float Function();
+typedef VoidToDouble = double Function();
+
+void testNoArgs() {
+ VoidToDouble inventFloatValue = ffiTestFunctions
+ .lookupFunction<NativeVoidToFloat, VoidToDouble>("InventFloatValue");
+
+ double result = inventFloatValue();
+ Expect.approxEquals(1337.0, result);
+}