[pygobject/invoke-rewrite] [gi] added ugly aux arg counters



commit 1cdbd4be9b015f792c2c02afa5ac7e24edbdae86
Author: John (J5) Palmieri <johnp redhat com>
Date:   Sun Jan 30 17:04:13 2011 -0500

    [gi] added ugly aux arg counters
    
    * we need to simplify the ffi invoke so we can simply reference args
      at their position in the C parameter list
    * this works for now but is fragile if new aux values are added in the future

 gi/pygi-argument.c |   12 ++++++++-
 gi/pygi-cache.c    |   66 +++++++++++++++++++++++++++++++++++----------------
 gi/pygi-cache.h    |    2 +
 gi/pygi-invoke.c   |   12 +++++++--
 4 files changed, 66 insertions(+), 26 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 756b25c..0dc277d 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -2698,8 +2698,16 @@ array_success:
         PyGIArgCache *aux_cache =
             function_cache->args_cache[sequence_cache->len_arg_index];
 
-
-        state->in_args[aux_cache->c_arg_index].v_long = length;
+        if (aux_cache->direction == GI_DIRECTION_INOUT) {
+            gint *len_arg = (gint *)state->in_args[aux_cache->c_arg_index].v_pointer;
+            /* if we are not setup yet just set the in arg */
+            if (len_arg == NULL)
+                state->in_args[aux_cache->c_arg_index].v_long = length;
+            else
+                *len_arg = length;
+        } else {              
+            state->in_args[aux_cache->c_arg_index].v_long = length;
+        }
     }
 
     if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 8736e8b..b7822f5 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -481,7 +481,8 @@ static inline gboolean
 _arg_cache_in_array_setup(PyGIArgCache *arg_cache,
                           PyGIFunctionCache *function_cache,
                           GITypeInfo *type_info,
-                          GITransfer transfer)
+                          GITransfer transfer,
+                          GIDirection direction)
 {
     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; 
     seq_cache->array_type = g_type_info_get_array_type(type_info);
@@ -489,6 +490,7 @@ _arg_cache_in_array_setup(PyGIArgCache *arg_cache,
     if (seq_cache->len_arg_index >= 0) {
         PyGIArgCache *aux_cache = _arg_cache_new();
         aux_cache->aux_type = PYGI_AUX_TYPE_IGNORE;
+        aux_cache->direction = direction;
         if (function_cache->args_cache[seq_cache->len_arg_index] != NULL) {
             PyGIArgCache *invalid_cache = function_cache->args_cache[seq_cache->len_arg_index];
             arg_cache->c_arg_index = invalid_cache->c_arg_index;
@@ -507,7 +509,8 @@ static inline gboolean
 _arg_cache_out_array_setup(PyGIArgCache *arg_cache,
                            PyGIFunctionCache *function_cache,
                            GITypeInfo *type_info,
-                           GITransfer transfer)
+                           GITransfer transfer,
+                           gssize arg_index)
 {
     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache; 
     arg_cache->out_marshaller = _pygi_marshal_out_array;
@@ -516,10 +519,14 @@ _arg_cache_out_array_setup(PyGIArgCache *arg_cache,
 
     if (seq_cache->len_arg_index >= 0) {
         PyGIArgCache *aux_cache = function_cache->args_cache[seq_cache->len_arg_index];
-        if (aux_cache == NULL)
+        if (seq_cache->len_arg_index < arg_index)
+             function_cache->n_out_aux_args++;
+
+        if (aux_cache == NULL) {
             aux_cache = _arg_cache_new();
-        else if (aux_cache->aux_type == PYGI_AUX_TYPE_IGNORE)
+        } else if (aux_cache->aux_type == PYGI_AUX_TYPE_IGNORE) {
             return TRUE;
+        }
 
         aux_cache->aux_type = PYGI_AUX_TYPE_IGNORE;
         if (function_cache->args_cache[seq_cache->len_arg_index] != NULL) {
@@ -528,6 +535,9 @@ _arg_cache_out_array_setup(PyGIArgCache *arg_cache,
             _pygi_arg_cache_free(invalid_cache);
         }
 
+        if (aux_cache->direction != GI_DIRECTION_INOUT)
+            aux_cache->direction = GI_DIRECTION_OUT;
+
         function_cache->args_cache[seq_cache->len_arg_index] = aux_cache;
     }
 
@@ -1060,14 +1070,16 @@ _arg_cache_new_from_type_info (GITypeInfo *type_info,
                if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT)
                    _arg_cache_in_array_setup(arg_cache,
                                              function_cache,
-                                             type_info, 
-                                             transfer);
+                                             type_info,
+                                             transfer,
+                                             direction);
 
                if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT)
-                   _arg_cache_out_array_setup(arg_cache, 
+                   _arg_cache_out_array_setup(arg_cache,
                                               function_cache,
                                               type_info,
-                                              transfer);
+                                              transfer,
+                                              c_arg_index);
 
                break;
            }
@@ -1245,6 +1257,14 @@ _args_cache_generate(GIFunctionInfo *function_info,
         gboolean is_caller_allocates;
         gint py_arg_index = -1;
 
+        arg_info =
+            g_callable_info_get_arg( (GICallableInfo *) function_info, i);
+
+        direction = g_arg_info_get_direction(arg_info);
+        transfer = g_arg_info_get_ownership_transfer(arg_info);
+        type_info = g_arg_info_get_type(arg_info);
+        type_tag = g_type_info_get_tag(type_info);
+
         /* must be an aux arg filled in by its owner
          * fill in it's c_arg_index, add to the in count
          * and continue
@@ -1255,24 +1275,25 @@ _args_cache_generate(GIFunctionInfo *function_info,
                 arg_cache->py_arg_index = function_cache->n_py_args;
                 function_cache->n_py_args++;
             }
-            arg_cache->c_arg_index = function_cache->n_in_args;
-            function_cache->n_in_args++;
-            continue;
-        }
 
-        arg_info =
-            g_callable_info_get_arg( (GICallableInfo *) function_info, i);
+            if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
+                arg_cache->c_arg_index = function_cache->n_in_args;
+                function_cache->n_in_args++;
+            }
+ 
+            if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
+                function_cache->n_out_args++;
+                function_cache->n_out_aux_args++;
+            }
 
-        direction = g_arg_info_get_direction(arg_info);
-        transfer = g_arg_info_get_ownership_transfer(arg_info);
-        type_info = g_arg_info_get_type(arg_info);
-        type_tag = g_type_info_get_tag(type_info);
+            g_base_info_unref( (GIBaseInfo *)arg_info);
+            continue;
+        }
 
         if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
             py_arg_index = function_cache->n_py_args;
             function_cache->n_in_args++;
             function_cache->n_py_args++;
-
         }
 
         arg_cache =
@@ -1309,10 +1330,13 @@ _args_cache_generate(GIFunctionInfo *function_info,
         }
 
         function_cache->args_cache[arg_index] = arg_cache;
-        g_base_info_unref( (GIBaseInfo *) type_info);
+        g_base_info_unref( (GIBaseInfo *)type_info);
+        g_base_info_unref( (GIBaseInfo *)arg_info);
+   
         continue;
 arg_err:
-        g_base_info_unref( (GIBaseInfo *) type_info);
+        g_base_info_unref( (GIBaseInfo *)type_info);
+        g_base_info_unref( (GIBaseInfo *)arg_info);        
         return FALSE;
     }
     return TRUE;
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 3b18d41..7bc3f9d 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -126,6 +126,8 @@ struct _PyGIFunctionCache
     /* counts */
     gssize n_in_args;
     gssize n_out_args;
+    gssize n_out_aux_args;
+
     gssize n_args;
     gssize n_py_args;
 };
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index db19c6c..eb2c8df 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -999,6 +999,10 @@ _invoke_marshal_in_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
 
                 break;
             case GI_DIRECTION_INOUT:
+                /* this will be filled in if it is an aux value */
+                if (state->in_args[in_count].v_pointer != NULL)
+                    state->out_values[out_count] = state->in_args[in_count];
+
                 state->in_args[in_count].v_pointer = &state->out_values[out_count];
                 in_count++;
 
@@ -1075,7 +1079,9 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
         }
     }
 
-    if (cache->n_out_args == 0) {
+    total_out_args -= cache->n_out_aux_args;
+
+    if (cache->n_out_args - cache->n_out_aux_args  == 0) {
         py_out = py_return;
     } else if (total_out_args == 1) {
         /* if we get here there is one out arg an no return */
@@ -1095,12 +1101,12 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
             py_arg_index++;
         }
 
-        for(; py_arg_index < total_out_args; py_arg_index++, out_cache_index++) {
+        for(; py_arg_index < total_out_args; py_arg_index++) {
             PyGIArgCache *arg_cache = (PyGIArgCache *)cache_item->data;
             PyObject *py_obj = arg_cache->out_marshaller(state,
                                                          cache,
                                                          arg_cache,
-                                                         &(state->out_values[out_cache_index]));
+                                                         state->args[arg_cache->c_arg_index]);
 
             if (py_obj == NULL)
                 return NULL;



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