Commit e30a4159 authored by John (J5) Palmieri's avatar John (J5) Palmieri
Browse files

only update the arg counts once if child arg comes before parent arg

* if the child arg comes before the parent arg we need to update the
   argument counts and take the child arg out of the marshalling lists
   since it is handled by the parent
 * when two parents reference the same child arg as is the case with
   two arrays which have a single length argument we only want to update
   the count once
 * to do this we introduce the PYGI_META_ARG_CHILD_NEEDS_UPDATE meta type
   and only do the count update if this is set
 * APIs should keep in mind that this take extra processing so child args
   should really come after their parents

https://bugzilla.gnome.org/show_bug.cgi?id=627236
parent f6fa5dd8
......@@ -466,25 +466,30 @@ _arg_cache_from_py_array_setup (PyGIArgCache *arg_cache,
PyGICallableCache *callable_cache,
GITypeInfo *type_info,
GITransfer transfer,
PyGIDirection direction)
PyGIDirection direction,
gssize arg_index)
{
PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
seq_cache->array_type = g_type_info_get_array_type (type_info);
arg_cache->from_py_marshaller = _pygi_marshal_from_py_array;
if (seq_cache->len_arg_index >= 0 &&
direction == PYGI_DIRECTION_FROM_PYTHON) {
if (seq_cache->len_arg_index >= 0) {
PyGIArgCache *child_cache =
callable_cache->args_cache[seq_cache->len_arg_index];
if (child_cache == NULL) {
child_cache = _arg_cache_alloc ();
} else if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD) {
} else if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) {
return TRUE;
}
child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
if (seq_cache->len_arg_index < arg_index)
child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE;
else
child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
child_cache->direction = direction;
child_cache->to_py_marshaller = NULL;
child_cache->from_py_marshaller = NULL;
......@@ -517,11 +522,12 @@ _arg_cache_to_py_array_setup (PyGIArgCache *arg_cache,
callable_cache->n_to_py_child_args++;
if (child_cache != NULL) {
if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD)
return TRUE;
callable_cache->to_py_args =
g_slist_remove (callable_cache->to_py_args, child_cache);
if (child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD ||
child_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE)
return TRUE;
} else {
child_cache = _arg_cache_alloc ();
}
......@@ -1073,7 +1079,8 @@ _arg_cache_new (GITypeInfo *type_info,
callable_cache,
type_info,
transfer,
direction);
direction,
c_arg_index);
if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
_arg_cache_to_py_array_setup (arg_cache,
......@@ -1089,9 +1096,12 @@ _arg_cache_new (GITypeInfo *type_info,
* need to update indexes if this happens
*/
if (seq_cache->len_arg_index > -1 &&
seq_cache->len_arg_index < c_arg_index) {
callable_cache->args_cache[seq_cache->len_arg_index]->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) {
gssize i;
PyGIArgCache *child_cache =
callable_cache->args_cache[seq_cache->len_arg_index];
child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD;
py_arg_index -= 1;
callable_cache->n_py_args -= 1;
......
......@@ -49,13 +49,17 @@ typedef void (*PyGIMarshalCleanupFunc) (PyGIInvokeState *state,
gboolean was_processed);
/* Argument meta types denote how we process the argument:
* - Parents (PYGI_META_ARG_TYPE_PARENT) may or may not have children
* - PYGI_META_ARG_TYPE_PARENT - parents may or may not have children
* but are always processed via the normal marshaller for their
* actual GI type. If they have children the marshaller will
* also handle marshalling the children.
* - Children without python argument (PYGI_META_ARG_TYPE_CHILD) are
* - PYGI_META_ARG_TYPE_CHILD - Children without python argument are
* ignored by the marshallers and handled directly by their parents
* marshaller.
* - PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE -Sometimes children arguments
* come before the parent. In these cases they need to be flagged
* so that the argument list counts must be updated for the cache to
* be valid
* - Children with pyargs (PYGI_META_ARG_TYPE_CHILD_WITH_PYARG) are processed
* the same as other child args but also have an index into the
* python parameters passed to the invoker
......@@ -63,6 +67,7 @@ typedef void (*PyGIMarshalCleanupFunc) (PyGIInvokeState *state,
typedef enum {
PYGI_META_ARG_TYPE_PARENT,
PYGI_META_ARG_TYPE_CHILD,
PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE,
PYGI_META_ARG_TYPE_CHILD_WITH_PYARG
} PyGIMetaArgType;
......
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