[pygobject/invoke-rewrite] hooked up caching stage and fixed segfaults
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/invoke-rewrite] hooked up caching stage and fixed segfaults
- Date: Mon, 10 Jan 2011 00:39:34 +0000 (UTC)
commit f32b1f494aa5d09b9b198f607722c819c6bbd808
Author: John (J5) Palmieri <johnp redhat com>
Date: Sun Jan 9 19:37:55 2011 -0500
hooked up caching stage and fixed segfaults
* caching stage is hooked up but not used yet
* throws exceptions for everything that can not be cached yet
gi/pygi-cache.c | 59 ++++++++++++++++++++++++++++++++++++++++++-----------
gi/pygi-info.c | 3 ++
gi/pygi-invoke.c | 5 ++++
gi/pygi.h | 2 +
4 files changed, 56 insertions(+), 13 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 8c52710..4ab711f 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -31,7 +31,7 @@ PyGIArgCache * _arg_cache_in_new_from_type_info (GITypeInfo *type_info,
gint py_arg_index);
/* cleanup */
static inline void
-_pygi_interface_cache_free (PyGIInterfaceCache *cache)
+_interface_cache_free_func (PyGIInterfaceCache *cache)
{
if (cache != NULL) {
Py_XDECREF(cache->py_type);
@@ -46,15 +46,15 @@ _pygi_hash_cache_free (PyGIHashCache *cache)
g_slice_free(PyGIHashCache, cache);
}
-static inline void
-_pygi_sequence_cache_free (PyGISequenceCache *cache)
+static void
+_sequence_cache_free_func (PyGISequenceCache *cache)
{
if (cache != NULL)
g_slice_free(PyGISequenceCache, cache);
}
-static inline void
-_pygi_callback_cache_free (PyGICallbackCache *cache)
+static void
+_callback_cache_free_func (PyGICallbackCache *cache)
{
if (cache != NULL)
g_slice_free(PyGICallbackCache, cache);
@@ -63,7 +63,11 @@ _pygi_callback_cache_free (PyGICallbackCache *cache)
void
_pygi_arg_cache_free (PyGIArgCache *cache)
{
- g_base_info_unref(cache->arg_info);
+ if (cache == NULL)
+ return;
+
+ if (cache->arg_info != NULL)
+ g_base_info_unref(cache->arg_info);
if (cache->destroy_notify)
cache->destroy_notify(cache);
else
@@ -75,13 +79,16 @@ _pygi_function_cache_free (PyGIFunctionCache *cache)
{
int i;
+ if (cache == NULL)
+ return;
+
g_slist_free(cache->in_args);
g_slist_free(cache->out_args);
for (i = 0; i < cache->n_args; i++) {
PyGIArgCache *tmp = cache->args_cache[i];
_pygi_arg_cache_free(tmp);
}
-
+ g_slice_free1(cache->n_args * sizeof(PyGIArgCache *), cache->args_cache);
g_slice_free(PyGIFunctionCache, cache);
}
@@ -97,7 +104,8 @@ _function_cache_new_from_function_info(GIFunctionInfo *function_info)
fc->is_method = flags & GI_FUNCTION_IS_METHOD;
fc->is_constructor = flags & GI_FUNCTION_IS_CONSTRUCTOR;
fc->n_args = g_callable_info_get_n_args ( (GICallableInfo *) function_info);
- fc->args_cache = g_slice_alloc0(fc->n_args * sizeof(PyGIArgCache *));
+ if (fc->n_args > 0)
+ fc->args_cache = g_slice_alloc0(fc->n_args * sizeof(PyGIArgCache *));
return fc;
}
@@ -122,8 +130,6 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info)
item_type_info = g_type_info_get_param_type (type_info, 0);
item_type_tag = g_type_info_get_tag (item_type_info);
- sc->item_cache->type_tag = item_type_tag;
-
/* FIXME: support out also */
sc->item_cache = _arg_cache_in_new_from_type_info(item_type_info,
NULL,
@@ -132,9 +138,15 @@ _sequence_cache_new_from_type_info(GITypeInfo *type_info)
GI_DIRECTION_IN,
0, 0);
+ if (sc->item_cache == NULL) {
+ _pygi_arg_cache_free((PyGIArgCache *)sc);
+ return NULL;
+ }
+
+ sc->item_cache->type_tag = item_type_tag;
g_base_info_unref( (GIBaseInfo *) item_type_info);
- ((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_pygi_sequence_cache_free;
+ ((PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
return sc;
}
@@ -443,7 +455,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
{
int arg_index;
for (arg_index = 0; arg_index < function_cache->n_args; arg_index++) {
- PyGIArgCache *arg_cache;
+ PyGIArgCache *arg_cache = NULL;
GIArgInfo *arg_info;
GITypeInfo *type_info;
GIDirection direction;
@@ -463,7 +475,7 @@ _args_cache_generate(GIFunctionInfo *function_info,
type_info = g_arg_info_get_type(arg_info);
type_tag = g_type_info_get_tag(type_info);
- switch(arg_cache->direction) {
+ switch(direction) {
case GI_DIRECTION_IN:
py_arg_index = function_cache->n_in_args;
function_cache->n_in_args++;
@@ -477,16 +489,33 @@ _args_cache_generate(GIFunctionInfo *function_info,
arg_index,
py_arg_index);
+ if (arg_cache == NULL)
+ goto arg_err;
+
function_cache->in_args =
g_slist_append(function_cache->in_args, arg_cache);
break;
case GI_DIRECTION_OUT:
function_cache->n_out_args++;
+ PyErr_Format(PyExc_NotImplementedError,
+ "Out caching is not fully implemented yet");
+
+ goto arg_err;
+
+ case GI_DIRECTION_INOUT:
+ PyErr_Format(PyExc_NotImplementedError,
+ "In/Out caching is not fully implemented yet");
+ goto arg_err;
+
}
function_cache->args_cache[arg_index] = arg_cache;
g_base_info_unref( (GIBaseInfo *) type_info);
+ continue;
+arg_err:
+ g_base_info_unref( (GIBaseInfo *) type_info);
+ return FALSE;
}
return TRUE;
}
@@ -495,9 +524,13 @@ PyGIFunctionCache *
_pygi_function_cache_new (GIFunctionInfo *function_info)
{
PyGIFunctionCache *fc = _function_cache_new_from_function_info(function_info);
+ if (fc == NULL)
+ return NULL;
+
if (!_args_cache_generate(function_info, fc))
goto err;
+ return fc;
err:
_pygi_function_cache_free(fc);
return NULL;
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 9d15e5e..94d117b 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -22,6 +22,7 @@
*/
#include "pygi-private.h"
+#include "pygi-cache.h"
#include <pygobject.h>
#include <pyglib-python-compat.h>
@@ -36,6 +37,8 @@ _base_info_dealloc (PyGIBaseInfo *self)
PyObject_ClearWeakRefs ( (PyObject *) self);
g_base_info_unref (self->info);
+
+ _pygi_function_cache_free(self->cache);
Py_TYPE( (PyObject *) self)->tp_free ( (PyObject *) self);
}
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 3a4fafa..2d6870b 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -920,6 +920,11 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self, PyObject *py_args)
{
struct invocation_state state = { 0, };
+ if (self->cache == NULL) {
+ self->cache = _pygi_function_cache_new(self->info);
+ if (self->cache == NULL)
+ return NULL;
+ }
_initialize_invocation_state (&state, self->info, py_args);
if (!_prepare_invocation_state (&state, self->info, py_args)) {
diff --git a/gi/pygi.h b/gi/pygi.h
index 03f71a4..a87b6fc 100644
--- a/gi/pygi.h
+++ b/gi/pygi.h
@@ -32,6 +32,7 @@
#if ENABLE_INTROSPECTION
#include <girepository.h>
+#include "pygi-cache.h"
typedef struct {
PyObject_HEAD
@@ -41,6 +42,7 @@ typedef struct {
typedef struct {
PyObject_HEAD
GIBaseInfo *info;
+ PyGIFunctionCache *cache;
PyObject *inst_weakreflist;
} PyGIBaseInfo;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]