[perl-Glib-Object-Introspection] Fix return value handling on big-endian architectures



commit 7e87f0cf10c0816b14415e4429a934be119fed05
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date:   Wed Jan 22 23:14:07 2014 +0100

    Fix return value handling on big-endian architectures
    
    https://rt.cpan.org/Ticket/Display.html?id=89552

 NEWS                  |    5 +++++
 gperl-i11n-invoke-c.c |   31 +++++++++++++++++++++++++++++--
 2 files changed, 34 insertions(+), 2 deletions(-)
---
diff --git a/NEWS b/NEWS
index b10dfe3..882196e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Overview of changes in Glib::Object::Introspection <next>
+========================================================
+
+* Fix return value handling on big-endian architectures.
+
 Overview of changes in Glib::Object::Introspection 0.022
 ========================================================
 
diff --git a/gperl-i11n-invoke-c.c b/gperl-i11n-invoke-c.c
index 19f6317..1b00543 100644
--- a/gperl-i11n-invoke-c.c
+++ b/gperl-i11n-invoke-c.c
@@ -29,6 +29,10 @@ invoke_c_code (GICallableInfo *info,
        guint i;
        GPerlI11nInvocationInfo iinfo = {0,};
        guint n_return_values;
+#if GI_CHECK_VERSION (1, 32, 0)
+       GIFFIReturnValue ffi_return_value;
+#endif
+       gpointer return_value_p;
        GIArgument return_value;
        GError * local_error = NULL;
        gpointer local_error_address = &local_error;
@@ -46,6 +50,10 @@ invoke_c_code (GICallableInfo *info,
                iinfo.args[0] = &instance;
        }
 
+       /*
+        * --- handle arguments -----------------------------------------------
+        */
+
        for (i = 0 ; i < iinfo.n_args ; i++) {
                GIArgInfo * arg_info;
                GITypeInfo * arg_type;
@@ -172,6 +180,10 @@ invoke_c_code (GICallableInfo *info,
                iinfo.arg_types[iinfo.n_invoke_args - 1] = &ffi_type_pointer;
        }
 
+       /*
+        * --- prepare & call -------------------------------------------------
+        */
+
        /* prepare and call the function */
        if (FFI_OK != ffi_prep_cif (&cif, FFI_DEFAULT_ABI, iinfo.n_invoke_args,
                                    iinfo.return_type_ffi, iinfo.arg_types))
@@ -180,7 +192,13 @@ invoke_c_code (GICallableInfo *info,
                ccroak ("Could not prepare a call interface");
        }
 
-       ffi_call (&cif, func_pointer, &return_value, iinfo.args);
+#if GI_CHECK_VERSION (1, 32, 0)
+       return_value_p = &ffi_return_value;
+#else
+       return_value_p = &return_value;
+#endif
+
+       ffi_call (&cif, func_pointer, return_value_p, iinfo.args);
 
        /* free call-scoped data */
        _invoke_free_after_call_handlers (&iinfo);
@@ -190,8 +208,17 @@ invoke_c_code (GICallableInfo *info,
        }
 
        /*
-        * handle return values
+        * --- handle return values -------------------------------------------
         */
+
+#if GI_CHECK_VERSION (1, 32, 0)
+       /* libffi has special semantics for return value storage; see `man
+        * ffi_call`.  We use gobject-introspection's extraction helper. */
+       gi_type_info_extract_ffi_return_value (iinfo.return_type_info,
+                                              &ffi_return_value,
+                                              &return_value);
+#endif
+
        n_return_values = 0;
 
        /* place return value and output args on the stack */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]