summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon van der Linden <svdlinden@src.gnome.org>2009-08-19 18:34:43 +0200
committerSimon van der Linden <svdlinden@src.gnome.org>2009-08-19 18:38:03 +0200
commitf54039303928ceec3020c96f73308df2e54209c4 (patch)
tree4b907969a802464913e336f6556cfc46459783cc
parent1c71d1c01d2a8fb25fe5fdb991fd617b55d95cb6 (diff)
downloadpygobject-f54039303928ceec3020c96f73308df2e54209c4.tar.gz
Get rid of the calls to g_hash_table_copy and g_array_copy
-rw-r--r--gi/pygi-argument.c175
-rw-r--r--gi/pygi-info.c370
-rw-r--r--gi/pygi-info.h3
3 files changed, 293 insertions, 255 deletions
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 5e7b13b8..df89f47c 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -29,181 +29,6 @@
#include <datetime.h>
#include <pygobject.h>
-static gsize
-_pygi_g_type_tag_size (GITypeTag type_tag)
-{
- gsize size = 0;
-
- switch(type_tag) {
- case GI_TYPE_TAG_BOOLEAN:
- size = sizeof(gboolean);
- break;
- case GI_TYPE_TAG_INT8:
- case GI_TYPE_TAG_UINT8:
- size = sizeof(gint8);
- break;
- case GI_TYPE_TAG_INT16:
- case GI_TYPE_TAG_UINT16:
- size = sizeof(gint16);
- break;
- case GI_TYPE_TAG_INT32:
- case GI_TYPE_TAG_UINT32:
- size = sizeof(gint32);
- break;
- case GI_TYPE_TAG_INT64:
- case GI_TYPE_TAG_UINT64:
- size = sizeof(gint64);
- break;
- case GI_TYPE_TAG_SHORT:
- case GI_TYPE_TAG_USHORT:
- size = sizeof(gshort);
- break;
- case GI_TYPE_TAG_INT:
- case GI_TYPE_TAG_UINT:
- size = sizeof(gint);
- break;
- case GI_TYPE_TAG_LONG:
- case GI_TYPE_TAG_ULONG:
- size = sizeof(glong);
- break;
- case GI_TYPE_TAG_SIZE:
- case GI_TYPE_TAG_SSIZE:
- size = sizeof(gsize);
- break;
- case GI_TYPE_TAG_FLOAT:
- size = sizeof(gfloat);
- break;
- case GI_TYPE_TAG_DOUBLE:
- size = sizeof(gdouble);
- break;
- case GI_TYPE_TAG_TIME_T:
- size = sizeof(time_t);
- break;
- case GI_TYPE_TAG_GTYPE:
- size = sizeof(GType);
- break;
- case GI_TYPE_TAG_VOID:
- case GI_TYPE_TAG_UTF8:
- case GI_TYPE_TAG_FILENAME:
- case GI_TYPE_TAG_ARRAY:
- case GI_TYPE_TAG_INTERFACE:
- case GI_TYPE_TAG_GLIST:
- case GI_TYPE_TAG_GSLIST:
- case GI_TYPE_TAG_GHASH:
- case GI_TYPE_TAG_ERROR:
- PyErr_Format(PyExc_TypeError,
- "Unable to know the size (assuming %s is not a pointer)",
- g_type_tag_to_string(type_tag));
- break;
- }
-
- return size;
-}
-
-static gsize
-_pygi_g_type_info_size (GITypeInfo *type_info)
-{
- gsize size = 0;
- gboolean is_pointer;
-
- is_pointer = g_type_info_is_pointer(type_info);
-
- if (is_pointer) {
- size = sizeof(gpointer);
- } else {
- GITypeTag type_tag;
-
- type_tag = g_type_info_get_tag(type_info);
- switch(type_tag) {
- case GI_TYPE_TAG_BOOLEAN:
- case GI_TYPE_TAG_INT8:
- case GI_TYPE_TAG_UINT8:
- case GI_TYPE_TAG_INT16:
- case GI_TYPE_TAG_UINT16:
- case GI_TYPE_TAG_INT32:
- case GI_TYPE_TAG_UINT32:
- case GI_TYPE_TAG_INT64:
- case GI_TYPE_TAG_UINT64:
- case GI_TYPE_TAG_SHORT:
- case GI_TYPE_TAG_USHORT:
- case GI_TYPE_TAG_INT:
- case GI_TYPE_TAG_UINT:
- case GI_TYPE_TAG_LONG:
- case GI_TYPE_TAG_ULONG:
- case GI_TYPE_TAG_SIZE:
- case GI_TYPE_TAG_SSIZE:
- case GI_TYPE_TAG_FLOAT:
- case GI_TYPE_TAG_DOUBLE:
- case GI_TYPE_TAG_TIME_T:
- case GI_TYPE_TAG_GTYPE:
- size = _pygi_g_type_tag_size(type_tag);
- g_assert(size > 0);
- break;
- case GI_TYPE_TAG_INTERFACE:
- {
- GIBaseInfo *info;
- GIInfoType info_type;
-
- info = g_type_info_get_interface(type_info);
- info_type = g_base_info_get_type(info);
-
- switch (info_type) {
- case GI_INFO_TYPE_STRUCT:
- size = g_struct_info_get_size((GIStructInfo *)info);
- break;
- case GI_INFO_TYPE_UNION:
- size = g_union_info_get_size((GIUnionInfo *)info);
- break;
- case GI_INFO_TYPE_ENUM:
- case GI_INFO_TYPE_FLAGS:
- {
- GITypeTag type_tag;
-
- type_tag = g_enum_info_get_storage_type((GIEnumInfo *)info);
- size = _pygi_g_type_tag_size(type_tag);
- break;
- }
- case GI_INFO_TYPE_BOXED:
- case GI_INFO_TYPE_OBJECT:
- case GI_INFO_TYPE_INTERFACE:
- case GI_INFO_TYPE_CALLBACK:
- /* Should have been catched by is_pointer above. */
- case GI_INFO_TYPE_VFUNC:
- case GI_INFO_TYPE_INVALID:
- case GI_INFO_TYPE_FUNCTION:
- case GI_INFO_TYPE_CONSTANT:
- case GI_INFO_TYPE_ERROR_DOMAIN:
- case GI_INFO_TYPE_VALUE:
- case GI_INFO_TYPE_SIGNAL:
- case GI_INFO_TYPE_PROPERTY:
- case GI_INFO_TYPE_FIELD:
- case GI_INFO_TYPE_ARG:
- case GI_INFO_TYPE_TYPE:
- case GI_INFO_TYPE_UNRESOLVED:
- g_assert_not_reached();
- break;
- }
-
- g_base_info_unref(info);
- break;
- }
- case GI_TYPE_TAG_ARRAY:
- case GI_TYPE_TAG_VOID:
- case GI_TYPE_TAG_UTF8:
- case GI_TYPE_TAG_FILENAME:
- case GI_TYPE_TAG_GLIST:
- case GI_TYPE_TAG_GSLIST:
- case GI_TYPE_TAG_GHASH:
- case GI_TYPE_TAG_ERROR:
- /* Should have been catched by is_pointer above. */
- g_assert_not_reached();
- break;
- }
- }
-
- return size;
-}
-
static void
_pygi_g_type_tag_py_bounds (GITypeTag type_tag,
PyObject **lower,
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index ceb81a22..4e0aa614 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -265,6 +265,182 @@ _wrap_g_function_info_is_method (PyGIBaseInfo *self)
return PyBool_FromLong(is_method);
}
+gsize
+_pygi_g_type_tag_size (GITypeTag type_tag)
+{
+ gsize size = 0;
+
+ switch(type_tag) {
+ case GI_TYPE_TAG_BOOLEAN:
+ size = sizeof(gboolean);
+ break;
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ size = sizeof(gint8);
+ break;
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ size = sizeof(gint16);
+ break;
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_UINT32:
+ size = sizeof(gint32);
+ break;
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ size = sizeof(gint64);
+ break;
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ size = sizeof(gshort);
+ break;
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_UINT:
+ size = sizeof(gint);
+ break;
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_ULONG:
+ size = sizeof(glong);
+ break;
+ case GI_TYPE_TAG_SIZE:
+ case GI_TYPE_TAG_SSIZE:
+ size = sizeof(gsize);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ size = sizeof(gfloat);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ size = sizeof(gdouble);
+ break;
+ case GI_TYPE_TAG_TIME_T:
+ size = sizeof(time_t);
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ size = sizeof(GType);
+ break;
+ case GI_TYPE_TAG_VOID:
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_INTERFACE:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ case GI_TYPE_TAG_ERROR:
+ PyErr_Format(PyExc_TypeError,
+ "Unable to know the size (assuming %s is not a pointer)",
+ g_type_tag_to_string(type_tag));
+ break;
+ }
+
+ return size;
+}
+
+gsize
+_pygi_g_type_info_size (GITypeInfo *type_info)
+{
+ gsize size = 0;
+ gboolean is_pointer;
+
+ is_pointer = g_type_info_is_pointer(type_info);
+
+ if (is_pointer) {
+ size = sizeof(gpointer);
+ } else {
+ GITypeTag type_tag;
+
+ type_tag = g_type_info_get_tag(type_info);
+ switch(type_tag) {
+ case GI_TYPE_TAG_BOOLEAN:
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_UINT:
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_ULONG:
+ case GI_TYPE_TAG_SIZE:
+ case GI_TYPE_TAG_SSIZE:
+ case GI_TYPE_TAG_FLOAT:
+ case GI_TYPE_TAG_DOUBLE:
+ case GI_TYPE_TAG_TIME_T:
+ case GI_TYPE_TAG_GTYPE:
+ size = _pygi_g_type_tag_size(type_tag);
+ g_assert(size > 0);
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ info = g_type_info_get_interface(type_info);
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_STRUCT:
+ size = g_struct_info_get_size((GIStructInfo *)info);
+ break;
+ case GI_INFO_TYPE_UNION:
+ size = g_union_info_get_size((GIUnionInfo *)info);
+ break;
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ {
+ GITypeTag type_tag;
+
+ type_tag = g_enum_info_get_storage_type((GIEnumInfo *)info);
+ size = _pygi_g_type_tag_size(type_tag);
+ break;
+ }
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_OBJECT:
+ case GI_INFO_TYPE_INTERFACE:
+ case GI_INFO_TYPE_CALLBACK:
+ /* Should have been catched by is_pointer above. */
+ case GI_INFO_TYPE_VFUNC:
+ case GI_INFO_TYPE_INVALID:
+ case GI_INFO_TYPE_FUNCTION:
+ case GI_INFO_TYPE_CONSTANT:
+ case GI_INFO_TYPE_ERROR_DOMAIN:
+ case GI_INFO_TYPE_VALUE:
+ case GI_INFO_TYPE_SIGNAL:
+ case GI_INFO_TYPE_PROPERTY:
+ case GI_INFO_TYPE_FIELD:
+ case GI_INFO_TYPE_ARG:
+ case GI_INFO_TYPE_TYPE:
+ case GI_INFO_TYPE_UNRESOLVED:
+ g_assert_not_reached();
+ break;
+ }
+
+ g_base_info_unref(info);
+ break;
+ }
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_VOID:
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ case GI_TYPE_TAG_ERROR:
+ /* Should have been catched by is_pointer above. */
+ g_assert_not_reached();
+ break;
+ }
+ }
+
+ return size;
+}
+
+
static PyObject *
_wrap_g_function_info_invoke (PyGIBaseInfo *self,
PyObject *py_args)
@@ -275,7 +451,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
gsize n_args;
gsize n_in_args;
gsize n_out_args;
- gsize n_containers;
+ gsize n_backup_args;
Py_ssize_t n_py_args;
gsize n_aux_in_args;
gsize n_aux_out_args;
@@ -294,7 +470,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
GArgument *in_args;
GArgument *out_args;
GArgument *out_values;
- GArgument *containers;
+ GArgument *backup_args;
GArgument return_arg;
PyObject *return_value = NULL;
@@ -313,7 +489,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
n_args = g_callable_info_get_n_args((GICallableInfo *)self->info);
n_in_args = 0;
n_out_args = 0;
- n_containers = 0;
+ n_backup_args = 0;
n_aux_in_args = 0;
n_aux_out_args = 0;
@@ -347,14 +523,16 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
n_in_args += 1;
+ if (transfer == GI_TRANSFER_CONTAINER) {
+ n_backup_args += 1;
+ }
}
if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
n_out_args += 1;
}
- if ((direction == GI_DIRECTION_INOUT && transfer != GI_TRANSFER_EVERYTHING)
- || (direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_CONTAINER)) {
- n_containers += 1;
+ if (direction == GI_DIRECTION_INOUT && transfer == GI_TRANSFER_NOTHING) {
+ n_backup_args += 1;
}
switch (arg_type_tag) {
@@ -380,9 +558,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
break;
}
case GI_TYPE_TAG_ERROR:
- if (error_arg_pos >= 0) {
- PyErr_WarnEx(NULL, "Two or more error arguments; taking the last one", 1);
- }
+ g_warn_if_fail(error_arg_pos < 0);
error_arg_pos = i;
break;
default:
@@ -515,7 +691,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
in_args = g_newa(GArgument, n_in_args);
out_args = g_newa(GArgument, n_out_args);
out_values = g_newa(GArgument, n_out_args);
- containers = g_newa(GArgument, n_containers);
+ backup_args = g_newa(GArgument, n_backup_args);
/* Bind args so we can use an unique index. */
{
@@ -556,10 +732,10 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
/* Convert the input arguments. */
{
Py_ssize_t py_args_pos;
- gsize containers_pos;
+ gsize backup_args_pos;
py_args_pos = 0;
- containers_pos = 0;
+ backup_args_pos = 0;
if (is_constructor) {
/* Skip the first argument. */
@@ -650,74 +826,61 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
return NULL;
}
- if ((direction == GI_DIRECTION_INOUT && transfer != GI_TRANSFER_EVERYTHING)
- || (direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_CONTAINER)) {
- /* We need to keep a copy of the container to be able to
- * release the items after the call. */
- g_assert(containers_pos < n_containers);
- switch(arg_type_tag) {
- case GI_TYPE_TAG_FILENAME:
- case GI_TYPE_TAG_UTF8:
- containers[containers_pos].v_string = args[i]->v_pointer;
- break;
+ if (direction == GI_DIRECTION_INOUT && transfer == GI_TRANSFER_NOTHING) {
+ /* We need to keep a copy of the argument to be able to release it later. */
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos] = *args[i];
+ backup_args_pos += 1;
+ } else if (transfer == GI_TRANSFER_CONTAINER) {
+ /* We need to keep a copy of the items to be able to release them later. */
+ switch (arg_type_tag) {
case GI_TYPE_TAG_ARRAY:
- containers[containers_pos].v_pointer = g_array_copy(args[i]->v_pointer);
- break;
- case GI_TYPE_TAG_INTERFACE:
{
- GIBaseInfo *info;
- GIInfoType info_type;
+ GArray *array;
+ gsize item_size;
+ GArray *new_array;
- info = g_type_info_get_interface(arg_type_infos[i]);
- g_assert(info != NULL);
+ array = args[i]->v_pointer;
- info_type = g_base_info_get_type(info);
+ item_size = g_array_get_element_size(array);
- switch (info_type) {
- case GI_INFO_TYPE_STRUCT:
- {
- GType type;
+ new_array = g_array_sized_new(FALSE, FALSE, item_size, array->len);
+ g_array_append_vals(new_array, array->data, array->len);
- type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos].v_pointer = new_array;
- if (g_type_is_a(type, G_TYPE_VALUE)) {
- GValue *value;
- GValue *new_value;
-
- value = args[i]->v_pointer;
- new_value = g_slice_new0(GValue);
-
- g_value_init(new_value, G_VALUE_TYPE(value));
- g_value_copy(value, new_value);
-
- containers[containers_pos].v_pointer = new_value;
- break;
- }
-
- /* TODO */
-
- break;
- }
- default:
- break;
- }
-
- g_base_info_unref(info);
break;
}
case GI_TYPE_TAG_GLIST:
- containers[containers_pos].v_pointer = g_list_copy(args[i]->v_pointer);
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos].v_pointer = g_list_copy(args[i]->v_pointer);
break;
case GI_TYPE_TAG_GSLIST:
- containers[containers_pos].v_pointer = g_slist_copy(args[i]->v_pointer);
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos].v_pointer = g_slist_copy(args[i]->v_pointer);
break;
case GI_TYPE_TAG_GHASH:
- containers[containers_pos].v_pointer = g_hash_table_copy(args[i]->v_pointer);
+ {
+ GHashTable *hash_table;
+ GList *keys;
+ GList *values;
+
+ hash_table = args[i]->v_pointer;
+
+ keys = g_hash_table_get_keys(hash_table);
+ values = g_hash_table_get_values(hash_table);
+
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos].v_pointer = g_list_concat(keys, values);
+
break;
+ }
default:
- break;
+ g_warn_if_reached();
}
- containers_pos += 1;
+
+ backup_args_pos += 1;
}
if (arg_type_tag == GI_TYPE_TAG_ARRAY) {
@@ -741,7 +904,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
}
g_assert(py_args_pos == n_py_args);
- g_assert(containers_pos == n_containers);
+ g_assert(backup_args_pos == n_backup_args);
}
/* Invoke the callable. */
@@ -880,10 +1043,10 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
/* Convert output arguments and release arguments. */
{
- gsize containers_pos;
+ gsize backup_args_pos;
gsize return_values_pos;
- containers_pos = 0;
+ backup_args_pos = 0;
return_values_pos = 0;
if (n_return_values > 1) {
@@ -964,22 +1127,69 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
}
/* Release the argument. */
- if (direction == GI_DIRECTION_INOUT) {
- if (transfer != GI_TRANSFER_EVERYTHING) {
- g_assert(containers_pos < n_containers);
- _pygi_argument_release(&containers[containers_pos], arg_type_infos[i],
- GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
- containers_pos += 1;
+
+ if ((direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT)
+ && transfer == GI_TRANSFER_CONTAINER) {
+ /* Release the items we kept in another container. */
+ switch (type_tag) {
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ g_assert(backup_args_pos < n_backup_args);
+ _pygi_argument_release(&backup_args[backup_args_pos], arg_type_infos[i],
+ transfer, GI_DIRECTION_IN);
+ break;
+ case GI_TYPE_TAG_GHASH:
+ {
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ GList *item;
+ gsize length;
+ gsize j;
+
+ key_type_info = g_type_info_get_param_type(arg_type_infos[i], 0);
+ value_type_info = g_type_info_get_param_type(arg_type_infos[i], 1);
+
+ g_assert(backup_args_pos < n_backup_args);
+ item = backup_args[backup_args_pos].v_pointer;
+
+ length = g_list_length(item) / 2;
+
+ for (j = 0; j < length; j++, item = g_list_next(item)) {
+ _pygi_argument_release((GArgument *)&item->data, key_type_info,
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ }
+
+ for (j = 0; j < length; j++, item = g_list_next(item)) {
+ _pygi_argument_release((GArgument *)&item->data, value_type_info,
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ }
+
+ g_list_free(backup_args[backup_args_pos].v_pointer);
+
+ break;
+ }
+ default:
+ g_warn_if_reached();
}
- if (transfer != GI_TRANSFER_NOTHING) {
- _pygi_argument_release(args[i], arg_type_infos[i], transfer,
+
+ if (direction == GI_DIRECTION_INOUT) {
+ /* Release the output argument. */
+ _pygi_argument_release(args[i], arg_type_infos[i], GI_TRANSFER_CONTAINER,
GI_DIRECTION_OUT);
}
- } else if (direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_CONTAINER) {
- g_assert(containers_pos < n_containers);
- _pygi_argument_release(&containers[containers_pos], arg_type_infos[i],
- GI_TRANSFER_NOTHING, direction);
- containers_pos += 1;
+
+ backup_args_pos += 1;
+ } else if (direction == GI_DIRECTION_INOUT) {
+ if (transfer == GI_TRANSFER_NOTHING) {
+ g_assert(backup_args_pos < n_backup_args);
+ _pygi_argument_release(&backup_args[backup_args_pos], arg_type_infos[i],
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ backup_args_pos += 1;
+ }
+
+ _pygi_argument_release(args[i], arg_type_infos[i], transfer,
+ GI_DIRECTION_OUT);
} else {
_pygi_argument_release(args[i], arg_type_infos[i], transfer, direction);
}
@@ -992,7 +1202,7 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
}
g_assert(n_return_values <= 1 || return_values_pos == n_return_values);
- g_assert(containers_pos == n_containers);
+ g_assert(backup_args_pos == n_backup_args);
}
return_:
diff --git a/gi/pygi-info.h b/gi/pygi-info.h
index aecf96ea..a566d710 100644
--- a/gi/pygi-info.h
+++ b/gi/pygi-info.h
@@ -37,6 +37,9 @@ PyObject* _pygi_info_new (GIBaseInfo *info);
gchar* _pygi_g_base_info_get_fullname (GIBaseInfo *info);
+gsize _pygi_g_type_tag_size (GITypeTag type_tag);
+gsize _pygi_g_type_info_size (GITypeInfo *type_info);
+
void _pygi_info_register_types (PyObject *m);
G_END_DECLS