[gjs/arg-inlines: 10/11] function: Ensure ffi return pointer initialization is consistent
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/arg-inlines: 10/11] function: Ensure ffi return pointer initialization is consistent
- Date: Sun, 12 Jul 2020 03:45:21 +0000 (UTC)
commit 19a581ca930f1fdeca1e15546dd909f8885c75c0
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Thu May 14 22:32:31 2020 +0200
function: Ensure ffi return pointer initialization is consistent
Return as pointer used by ffi_call as the return value, to mimic the
inverse of what is done in gi_type_info_extract_ffi_return_value() since
that's what we use to parse the results.
gi/function.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 46 insertions(+), 11 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index 9706e84e..ae873de4 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -50,6 +50,7 @@
#include <jsfriendapi.h> // for JS_GetObjectFunction
#include <jspubtd.h> // for JSProto_TypeError, JSTYPE_FUNCTION
+#include "gi/arg-inl.h"
#include "gi/arg.h"
#include "gi/boxed.h"
#include "gi/closure.h"
@@ -766,6 +767,47 @@ complete_async_calls(void)
}
}
+static void* get_return_ffi_pointer_from_giargument(
+ GITypeInfo* return_info, GIFFIReturnValue* return_value) {
+ // This should be the inverse of gi_type_info_extract_ffi_return_value().
+ // FIXME: Note that v_long and v_ulong don't have type-safe template
+ // overloads yet, and I don't understand why they won't compile
+ switch (g_type_info_get_tag(return_info)) {
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_INT32:
+ return &return_value->v_long;
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_BOOLEAN:
+ case GI_TYPE_TAG_UNICHAR:
+ return &return_value->v_ulong;
+ case GI_TYPE_TAG_INT64:
+ return &gjs_arg_member<int64_t>(return_value);
+ case GI_TYPE_TAG_UINT64:
+ return &gjs_arg_member<uint64_t>(return_value);
+ case GI_TYPE_TAG_FLOAT:
+ return &gjs_arg_member<float>(return_value);
+ case GI_TYPE_TAG_DOUBLE:
+ return &gjs_arg_member<double>(return_value);
+ case GI_TYPE_TAG_INTERFACE: {
+ GjsAutoBaseInfo info = g_type_info_get_interface(return_info);
+
+ switch (g_base_info_get_type(info)) {
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ return &return_value->v_long;
+ default:
+ return &gjs_arg_member<void*>(return_value);
+ }
+ break;
+ }
+ default:
+ return &gjs_arg_member<void*>(return_value);
+ }
+}
+
// This function can be called in two different ways. You can either use it to
// create JavaScript objects by calling it without @r_value, or you can decide
// to keep the return values in #GArgument format by providing a @r_value
@@ -794,7 +836,6 @@ static bool gjs_invoke_c_function(JSContext* context, Function* function,
GArgument *inout_original_arg_cvalues;
gpointer *ffi_arg_pointers;
GIFFIReturnValue return_value;
- gpointer return_value_p; /* Will point inside the union return_value */
GArgument return_gargument;
guint8 processed_c_args = 0;
@@ -1121,16 +1162,10 @@ static bool gjs_invoke_c_function(JSContext* context, Function* function,
g_assert_cmpuint(c_arg_pos, ==, c_argc);
g_assert_cmpuint(gi_arg_pos, ==, gi_argc);
- /* See comment for GjsFFIReturnValue above */
- if (return_tag == GI_TYPE_TAG_FLOAT)
- return_value_p = &return_value.v_float;
- else if (return_tag == GI_TYPE_TAG_DOUBLE)
- return_value_p = &return_value.v_double;
- else if (return_tag == GI_TYPE_TAG_INT64 || return_tag == GI_TYPE_TAG_UINT64)
- return_value_p = &return_value.v_uint64;
- else
- return_value_p = &return_value.v_long;
- ffi_call(&(function->invoker.cif), FFI_FN(function->invoker.native_address), return_value_p,
ffi_arg_pointers);
+ ffi_call(
+ &(function->invoker.cif), FFI_FN(function->invoker.native_address),
+ get_return_ffi_pointer_from_giargument(&return_info, &return_value),
+ ffi_arg_pointers);
/* Return value and out arguments are valid only if invocation doesn't
* return error. In arguments need to be released always.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]