[pygobject/invoke-rewrite] [gi-invoke-ng] handle vfuncs and fix cosntrutors



commit cf7f97eabc9c49773c2916929b8c43ef453d0652
Author: John (J5) Palmieri <johnp redhat com>
Date:   Fri Mar 25 18:47:36 2011 -0400

    [gi-invoke-ng] handle vfuncs and fix cosntrutors

 gi/pygi-cache.c               |    9 ++++++
 gi/pygi-cache.h               |    2 +
 gi/pygi-invoke-ng.c           |   56 ++++++++++++++++++++++++++++++----------
 gi/pygi-invoke-state-struct.h |    2 +
 4 files changed, 55 insertions(+), 14 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index ae1c06d..ed3bc70 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -735,6 +735,8 @@ _arg_cache_new_from_interface_info (GIInterfaceInfo *iface_info,
     PyGIInterfaceCache *iface_cache = NULL;
     PyGIArgCache *arg_cache = NULL;
 
+    GI_IS_INTERFACE_INFO (iface_info);
+
     /* Callbacks are special cased */
     if (info_type != GI_INFO_TYPE_CALLBACK) {
         iface_cache = _interface_cache_new_from_interface_info(iface_info);
@@ -1357,6 +1359,13 @@ PyGIFunctionCache *
 _pygi_function_cache_new (GIFunctionInfo *function_info)
 {
     PyGIFunctionCache *fc = _function_cache_new_from_function_info(function_info);
+    GIInfoType type = g_base_info_get_type ( (GIBaseInfo *)function_info);
+
+    if  (type == GI_INFO_TYPE_VFUNC)
+        fc->is_vfunc = TRUE;
+    else if (type == GI_INFO_TYPE_CALLBACK)
+        fc->is_callback = TRUE;
+
     if (fc == NULL)
         return NULL;
 
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 87f5ec8..4a13457 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -119,6 +119,8 @@ struct _PyGIFunctionCache
 
     gboolean is_method;
     gboolean is_constructor;
+    gboolean is_vfunc;
+    gboolean is_callback;
 
     PyGIArgCache *return_cache;
     PyGIArgCache **args_cache;
diff --git a/gi/pygi-invoke-ng.c b/gi/pygi-invoke-ng.c
index 4dd01b2..ec057e9 100644
--- a/gi/pygi-invoke-ng.c
+++ b/gi/pygi-invoke-ng.c
@@ -37,14 +37,24 @@ _invoke_function (PyGIInvokeState *state,
 
     pyg_begin_allow_threads;
 
-    /* FIXME: use this for now but we can streamline the call */
-    retval = g_function_info_invoke ( (GIFunctionInfo *) function_info,
-                                      state->in_args,
-                                      cache->n_in_args,
-                                      state->out_args,
-                                      cache->n_out_args,
-                                      &state->return_arg,
-                                      &error);
+    /* FIXME: use this for now but we can streamline the calls */
+    if (cache->is_vfunc)
+        retval = g_vfunc_info_invoke ( function_info,
+                                           state->implementor_gtype,
+                                           state->in_args,
+                                           cache->n_in_args,
+                                           state->out_args,
+                                           cache->n_out_args,
+                                          &state->return_arg,
+                                          &error);
+    else
+        retval = g_function_info_invoke ( function_info,
+                                          state->in_args,
+                                          cache->n_in_args,
+                                          state->out_args,
+                                          cache->n_out_args,
+                                         &state->return_arg,
+                                         &error);
     pyg_end_allow_threads;
 
     if (!retval) {
@@ -73,7 +83,8 @@ _invoke_function (PyGIInvokeState *state,
 static inline gboolean
 _invoke_state_init_from_function_cache (PyGIInvokeState *state,
                                                                     PyGIFunctionCache *cache,
-                                                                    PyObject *py_args)
+                                        PyObject *py_args,
+                                        PyObject *kwargs)
 {
     state->py_in_args = py_args;
     state->n_py_in_args = PySequence_Length (py_args);
@@ -97,15 +108,30 @@ _invoke_state_init_from_function_cache (PyGIInvokeState *state,
 
         Py_INCREF(state->constructor_class);
 
-        state->n_py_in_args--;
-
         /* we could optimize this by using offsets instead of modifying the tuple but it makes the
          * code more error prone and confusing so don't do that unless profiling shows
          * significant gain
          */
-        state->py_in_args = PyTuple_GetSlice (py_args, 1, state->py_in_args);
+        state->py_in_args = PyTuple_GetSlice (py_args, 1, state->n_py_in_args);
+        state->n_py_in_args--;
+    } else {
+        Py_INCREF(state->py_in_args);
+    }
+    state->implementor_gtype = 0;
+    if (cache->is_vfunc) {
+        PyObject *py_gtype;
+        py_gtype = PyDict_GetItemString (kwargs, "gtype");
+        if (py_gtype == NULL) {
+            PyErr_SetString (PyExc_TypeError,
+                             "need the GType of the implementor class");
+            return FALSE;
+        }
+
+        state->implementor_gtype = pyg_type_from_object (py_gtype);
+        Py_DECREF(py_gtype);
 
-        Py_DECREF(py_args);
+        if (state->implementor_gtype == 0)
+            return FALSE;
     }
 
     state->args = g_slice_alloc0 (cache->n_args * sizeof (GIArgument *));
@@ -144,6 +170,8 @@ _invoke_state_clear(PyGIInvokeState *state, PyGIFunctionCache *cache)
     g_slice_free1(cache->n_in_args * sizeof(GIArgument), state->in_args);
     g_slice_free1(cache->n_out_args * sizeof(GIArgument), state->out_args);
     g_slice_free1(cache->n_out_args * sizeof(GIArgument), state->out_values);
+
+    Py_XDECREF(state->py_in_args);
 }
 
 static inline gboolean
@@ -354,7 +382,7 @@ _wrap_g_callable_info_invoke (PyGIBaseInfo *self,
             return NULL;
     }
 
-    _invoke_state_init_from_function_cache(&state, self->cache, py_args);
+    _invoke_state_init_from_function_cache(&state, self->cache, py_args, kwargs);
     if (!_invoke_marshal_in_args (&state, self->cache))
         goto err;
 
diff --git a/gi/pygi-invoke-state-struct.h b/gi/pygi-invoke-state-struct.h
index fb3bfea..3147ee8 100644
--- a/gi/pygi-invoke-state-struct.h
+++ b/gi/pygi-invoke-state-struct.h
@@ -13,6 +13,8 @@ typedef struct _PyGIInvokeState
     PyObject *constructor_class;
     gssize n_py_in_args;
 
+    GType implementor_gtype;
+
     GIArgument **args;
     GIArgument *in_args;
 



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