Commit 770e6abf authored by Martin Pitt's avatar Martin Pitt
Browse files

Fix list marshalling on big-endian machines

On big endian machines we cannot simply set e. g. GIArgument.v_int8 and expect
GIArgument.v_pointer to be a correct representation. This needs to use
GINT_TO_POINTER/GPOINTER_TO_INT properly, so use the already existing
_pygi_hash_pointer_to_arg()/_pygi_arg_to_hash_pointer() methods in marshalling
to and from GList and GSList, and handle int8 and int16 as well.

Part of porting pygobject to ppc64:
https://bugzilla.redhat.com/show_bug.cgi?id=842880
https://bugzilla.gnome.org/show_bug.cgi?id=680693
parent b5cd13f4
......@@ -736,6 +736,33 @@ _pygi_marshal_from_py_filename (PyGIInvokeState *state,
return TRUE;
}
static gpointer
_pygi_arg_to_hash_pointer (const GIArgument *arg,
GITypeTag type_tag)
{
switch (type_tag) {
case GI_TYPE_TAG_INT8:
return GINT_TO_POINTER(arg->v_int8);
case GI_TYPE_TAG_UINT8:
return GINT_TO_POINTER(arg->v_uint8);
case GI_TYPE_TAG_INT16:
return GINT_TO_POINTER(arg->v_int16);
case GI_TYPE_TAG_UINT16:
return GINT_TO_POINTER(arg->v_uint16);
case GI_TYPE_TAG_INT32:
return GINT_TO_POINTER(arg->v_int32);
case GI_TYPE_TAG_UINT32:
return GINT_TO_POINTER(arg->v_uint32);
case GI_TYPE_TAG_UTF8:
case GI_TYPE_TAG_FILENAME:
case GI_TYPE_TAG_INTERFACE:
return arg->v_pointer;
default:
g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
return arg->v_pointer;
}
}
gboolean
_pygi_marshal_from_py_array (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
......@@ -985,7 +1012,7 @@ _pygi_marshal_from_py_glist (PyGIInvokeState *state,
&item))
goto err;
list_ = g_list_prepend (list_, item.v_pointer);
list_ = g_list_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag));
continue;
err:
/* FIXME: clean up list
......@@ -1052,7 +1079,7 @@ _pygi_marshal_from_py_gslist (PyGIInvokeState *state,
&item))
goto err;
list_ = g_slist_prepend (list_, item.v_pointer);
list_ = g_slist_prepend (list_, _pygi_arg_to_hash_pointer (&item, sequence_cache->item_cache->type_tag));
continue;
err:
/* FIXME: Clean up list
......@@ -1070,23 +1097,6 @@ err:
return TRUE;
}
static gpointer
_pygi_arg_to_hash_pointer (const GIArgument *arg,
GITypeTag type_tag)
{
switch (type_tag) {
case GI_TYPE_TAG_INT32:
return GINT_TO_POINTER(arg->v_int32);
case GI_TYPE_TAG_UTF8:
case GI_TYPE_TAG_FILENAME:
case GI_TYPE_TAG_INTERFACE:
return arg->v_pointer;
default:
g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
return arg->v_pointer;
}
}
gboolean
_pygi_marshal_from_py_ghash (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
......
......@@ -415,6 +415,29 @@ err:
return NULL;
}
static void
_pygi_hash_pointer_to_arg (GIArgument *arg,
GITypeTag type_tag)
{
switch (type_tag) {
case GI_TYPE_TAG_INT8:
arg->v_int8 = GPOINTER_TO_INT(arg->v_pointer);
break;
case GI_TYPE_TAG_INT16:
arg->v_int16 = GPOINTER_TO_INT(arg->v_pointer);
break;
case GI_TYPE_TAG_INT32:
arg->v_int32 = GPOINTER_TO_INT(arg->v_pointer);
break;
case GI_TYPE_TAG_UTF8:
case GI_TYPE_TAG_FILENAME:
case GI_TYPE_TAG_INTERFACE:
break;
default:
g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
}
}
PyObject *
_pygi_marshal_to_py_glist (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
......@@ -446,10 +469,11 @@ _pygi_marshal_to_py_glist (PyGIInvokeState *state,
PyObject *py_item;
item_arg.v_pointer = list_->data;
py_item = item_to_py_marshaller ( state,
callable_cache,
item_arg_cache,
&item_arg);
_pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag);
py_item = item_to_py_marshaller (state,
callable_cache,
item_arg_cache,
&item_arg);
if (py_item == NULL) {
Py_CLEAR (py_obj);
......@@ -494,10 +518,11 @@ _pygi_marshal_to_py_gslist (PyGIInvokeState *state,
PyObject *py_item;
item_arg.v_pointer = list_->data;
py_item = item_to_py_marshaller ( state,
_pygi_hash_pointer_to_arg (&item_arg, item_arg_cache->type_tag);
py_item = item_to_py_marshaller (state,
callable_cache,
item_arg_cache,
&item_arg);
&item_arg);
if (py_item == NULL) {
Py_CLEAR (py_obj);
......@@ -511,23 +536,6 @@ _pygi_marshal_to_py_gslist (PyGIInvokeState *state,
return py_obj;
}
static void
_pygi_hash_pointer_to_arg (GIArgument *arg,
GITypeTag type_tag)
{
switch (type_tag) {
case GI_TYPE_TAG_INT32:
arg->v_int32 = GPOINTER_TO_INT(arg->v_pointer);
break;
case GI_TYPE_TAG_UTF8:
case GI_TYPE_TAG_FILENAME:
case GI_TYPE_TAG_INTERFACE:
break;
default:
g_critical("Unsupported type %s", g_type_tag_to_string(type_tag));
}
}
PyObject *
_pygi_marshal_to_py_ghash (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment