summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2022-02-03 23:54:09 -0800
committerEmmanuele Bassi <ebassi@gmail.com>2022-02-13 12:25:18 +0000
commit64d450bd423bb54e4c1da3f21c9d39ee98adb823 (patch)
treee27ae87bc1a392f9356a37f474745291bdddb687
parentc72913682407c2564124cce94cb923c4e28b1dfa (diff)
downloadgobject-introspection-64d450bd423bb54e4c1da3f21c9d39ee98adb823.tar.gz
girffi: Add gi_type_tag_extract_ffi_return_value()
This new API does the same thing as gi_type_info_extract_ffi_return_value, but takes a GITypeTag instead of GITypeInfo pointer, and additionally a GIInfoType if the GITypeTag is GI_TYPE_TAG_INTERFACE. (These pieces of data are the only things used from the GITypeInfo structure.) It's intended for bindings using an argument cache, such as GJS and PyGObject, so that they don't have to store a whole 64-bit GITypeInfo pointer in their cache in many common cases, and can just store the 5-bit type tag instead, or the 5-bit interface type in case of GI_TYPE_TAG_INTERFACE. The original gi_type_info_extract_ffi_return_value() is reimplemented in terms of the new gi_type_tag_extract_ffi_return_value().
-rw-r--r--girepository/gicallableinfo.c82
-rw-r--r--girepository/girffi.h6
2 files changed, 62 insertions, 26 deletions
diff --git a/girepository/gicallableinfo.c b/girepository/gicallableinfo.c
index 16e391f9..e224ea6f 100644
--- a/girepository/gicallableinfo.c
+++ b/girepository/gicallableinfo.c
@@ -475,23 +475,31 @@ g_callable_info_iterate_return_attributes (GICallableInfo *info,
}
/**
- * gi_type_info_extract_ffi_return_value:
- * @return_info: TODO
- * @ffi_value: TODO
- * @arg: (out caller-allocates): TODO
+ * gi_type_tag_extract_ffi_return_value:
+ * @return_tag: #GITypeTag of the return value
+ * @interface_type: #GIInfoType of the underlying interface type
+ * @ffi_value: pointer to #GIFFIReturnValue union containing the return value
+ * from ffi_call()
+ * @arg: (out caller-allocates): pointer to an allocated #GIArgument
*
* Extract the correct bits from an ffi_arg return value into
* GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152
*
* Also see <citerefentry><refentrytitle>ffi_call</refentrytitle><manvolnum>3</manvolnum></citerefentry>
* - the storage requirements for return values are "special".
+ *
+ * The @interface_type argument only applies if @return_tag is
+ * %GI_TYPE_TAG_INTERFACE. Otherwise it is ignored.
+ *
+ * Since: 1.72
*/
void
-gi_type_info_extract_ffi_return_value (GITypeInfo *return_info,
- GIFFIReturnValue *ffi_value,
- GIArgument *arg)
+gi_type_tag_extract_ffi_return_value (GITypeTag return_tag,
+ GIInfoType interface_type,
+ GIFFIReturnValue *ffi_value,
+ GIArgument *arg)
{
- switch (g_type_info_get_tag (return_info)) {
+ switch (return_tag) {
case GI_TYPE_TAG_INT8:
arg->v_int8 = (gint8) ffi_value->v_long;
break;
@@ -525,24 +533,14 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info,
arg->v_double = ffi_value->v_double;
break;
case GI_TYPE_TAG_INTERFACE:
- {
- GIBaseInfo* interface_info;
- GIInfoType interface_type;
-
- interface_info = g_type_info_get_interface(return_info);
- interface_type = g_base_info_get_type(interface_info);
-
- switch(interface_type) {
- case GI_INFO_TYPE_ENUM:
- case GI_INFO_TYPE_FLAGS:
- arg->v_int32 = (gint32) ffi_value->v_long;
- break;
- default:
- arg->v_pointer = (gpointer) ffi_value->v_pointer;
- break;
- }
-
- g_base_info_unref(interface_info);
+ switch(interface_type) {
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ arg->v_int32 = (gint32) ffi_value->v_long;
+ break;
+ default:
+ arg->v_pointer = (gpointer) ffi_value->v_pointer;
+ break;
}
break;
default:
@@ -552,6 +550,38 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info,
}
/**
+ * gi_type_info_extract_ffi_return_value:
+ * @return_info: #GITypeInfo describing the return type
+ * @ffi_value: pointer to #GIFFIReturnValue union containing the return value
+ * from ffi_call()
+ * @arg: (out caller-allocates): pointer to an allocated #GIArgument
+ *
+ * Extract the correct bits from an ffi_arg return value into
+ * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152
+ *
+ * Also see <citerefentry><refentrytitle>ffi_call</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ * - the storage requirements for return values are "special".
+ */
+void
+gi_type_info_extract_ffi_return_value (GITypeInfo *return_info,
+ GIFFIReturnValue *ffi_value,
+ GIArgument *arg)
+{
+ GITypeTag return_tag = g_type_info_get_tag (return_info);
+ GIInfoType interface_type = GI_INFO_TYPE_INVALID;
+
+ if (return_tag == GI_TYPE_TAG_INTERFACE)
+ {
+ GIBaseInfo *interface_info = g_type_info_get_interface (return_info);
+ interface_type = g_base_info_get_type (interface_info);
+ g_base_info_unref (interface_info);
+ }
+
+ return gi_type_tag_extract_ffi_return_value (return_tag, interface_type,
+ ffi_value, arg);
+}
+
+/**
* g_callable_info_invoke:
* @info: TODO
* @function: TODO
diff --git a/girepository/girffi.h b/girepository/girffi.h
index 2bbc97ac..349ae57e 100644
--- a/girepository/girffi.h
+++ b/girepository/girffi.h
@@ -75,6 +75,12 @@ void gi_type_info_extract_ffi_return_value (GITypeInfo
GIFFIReturnValue *ffi_value,
GIArgument *arg);
+GI_AVAILABLE_IN_1_72
+void gi_type_tag_extract_ffi_return_value (GITypeTag tag,
+ GIInfoType interface_type,
+ GIFFIReturnValue *ffi_value,
+ GIArgument *arg);
+
GI_AVAILABLE_IN_ALL
gboolean g_function_info_prep_invoker (GIFunctionInfo *info,
GIFunctionInvoker *invoker,