[perl-Glib-Object-Introspection/ppc64-fixes] Properly convert Perl callback return values on big-endian systems
- From: Torsten Schönfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib-Object-Introspection/ppc64-fixes] Properly convert Perl callback return values on big-endian systems
- Date: Thu, 18 Sep 2014 09:34:13 +0000 (UTC)
commit 6fc20aa778ffc9a58c11371568ebb8de6ff994f9
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date: Thu Sep 18 11:32:43 2014 +0200
Properly convert Perl callback return values on big-endian systems
ffi expects certain return value semantics that we were not satisfying. This
lead to incorrect conversions on big-endian systems.
https://rt.cpan.org/Ticket/Display.html?id=98463
gperl-i11n-invoke-perl.c | 79 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 78 insertions(+), 1 deletions(-)
---
diff --git a/gperl-i11n-invoke-perl.c b/gperl-i11n-invoke-perl.c
index da11a59..4eb6c33 100644
--- a/gperl-i11n-invoke-perl.c
+++ b/gperl-i11n-invoke-perl.c
@@ -4,6 +4,10 @@ static void _prepare_perl_invocation_info (GPerlI11nPerlInvocationInfo *iinfo,
GICallableInfo *info,
gpointer *args);
static void _clear_perl_invocation_info (GPerlI11nPerlInvocationInfo *iinfo);
+static void _fill_ffi_return_value (GITypeInfo *return_info,
+ gpointer resp,
+ GIArgument *arg);
+
static void
invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata)
@@ -255,7 +259,7 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
sv_to_arg (POPs, &arg, NULL, type_info,
transfer, may_be_null, &iinfo.base);
- arg_to_raw (&arg, resp, type_info);
+ _fill_ffi_return_value (type_info, resp, &arg);
}
PUTBACK;
@@ -374,3 +378,76 @@ _clear_perl_invocation_info (GPerlI11nPerlInvocationInfo *iinfo)
{
clear_invocation_info ((GPerlI11nInvocationInfo *) iinfo);
}
+
+/* ------------------------------------------------------------------------- */
+
+/* Copied from pygobject's pygi-closure.c. */
+static void
+_fill_ffi_return_value (GITypeInfo *return_info,
+ gpointer resp,
+ GIArgument *arg)
+{
+ if (!resp)
+ return;
+ switch (g_type_info_get_tag (return_info)) {
+ case GI_TYPE_TAG_BOOLEAN:
+ *((ffi_sarg *) resp) = arg->v_boolean;
+ break;
+ case GI_TYPE_TAG_INT8:
+ *((ffi_sarg *) resp) = arg->v_int8;
+ break;
+ case GI_TYPE_TAG_UINT8:
+ *((ffi_arg *) resp) = arg->v_uint8;
+ break;
+ case GI_TYPE_TAG_INT16:
+ *((ffi_sarg *) resp) = arg->v_int16;
+ break;
+ case GI_TYPE_TAG_UINT16:
+ *((ffi_arg *) resp) = arg->v_uint16;
+ break;
+ case GI_TYPE_TAG_INT32:
+ *((ffi_sarg *) resp) = arg->v_int32;
+ break;
+ case GI_TYPE_TAG_UINT32:
+ *((ffi_arg *) resp) = arg->v_uint32;
+ break;
+ case GI_TYPE_TAG_INT64:
+ *((ffi_sarg *) resp) = arg->v_int64;
+ break;
+ case GI_TYPE_TAG_UINT64:
+ *((ffi_arg *) resp) = arg->v_uint64;
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ *((gfloat *) resp) = arg->v_float;
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ *((gdouble *) resp) = arg->v_double;
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ *((ffi_arg *) resp) = arg->v_size;
+ break;
+ case GI_TYPE_TAG_UNICHAR:
+ *((ffi_arg *) resp) = arg->v_uint32;
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *interface_info;
+ interface_info = g_type_info_get_interface (return_info);
+ switch (g_base_info_get_type (interface_info)) {
+ case GI_INFO_TYPE_ENUM:
+ *(ffi_sarg *) resp = arg->v_int;
+ break;
+ case GI_INFO_TYPE_FLAGS:
+ *(ffi_arg *) resp = arg->v_uint;
+ break;
+ default:
+ *(ffi_arg *) resp = (ffi_arg) arg->v_pointer;
+ break;
+ }
+ break;
+ }
+ default:
+ *(ffi_arg *) resp = (ffi_arg) arg->v_pointer;
+ break;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]