[libpeas] Convert the API using va_list to use GArgument instead.
- From: Steve Frécinaux <sfre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libpeas] Convert the API using va_list to use GArgument instead.
- Date: Mon, 16 Aug 2010 23:03:02 +0000 (UTC)
commit 35fec222a45615bd001c9a5e2e8192e99d99b8bc
Author: Steve Frécinaux <code istique net>
Date: Tue Aug 17 00:52:40 2010 +0200
Convert the API using va_list to use GArgument instead.
GArgument is designed to allow passing function arguments around and
processing them quite efficiently, and on the other hand a va_list can
only be processed once and must be used from a single function only.
This proved being error-prone, so this patch just switches all API
playing with function arguments from using va_list to using GArgument.
This means one extra marshalling step in the Seed loader, but that's
all...
This commit also fixes calling methods of the Seed extensions when there
are more than a single (out) argument. It was not working everywhere
because it accessed the va_list content from several distinct functions.
docs/reference/libpeas-sections.txt | 1 +
libpeas/Makefile.am | 2 +-
libpeas/peas-extension.c | 37 ++++-
libpeas/peas-extension.h | 8 +-
libpeas/peas-introspection.c | 328 +++++++++++++++++--------------
libpeas/peas-introspection.h | 14 +-
loaders/c/peas-extension-c.c | 5 +-
loaders/python/peas-extension-python.c | 5 +-
loaders/seed/peas-extension-seed.c | 102 ++++++----
9 files changed, 302 insertions(+), 200 deletions(-)
---
diff --git a/docs/reference/libpeas-sections.txt b/docs/reference/libpeas-sections.txt
index 33515b6..7f86258 100644
--- a/docs/reference/libpeas-sections.txt
+++ b/docs/reference/libpeas-sections.txt
@@ -179,6 +179,7 @@ PeasExtensionClass
peas_extension_get_extension_type
peas_extension_call
peas_extension_call_valist
+peas_extension_callv
<SUBSECTION Standard>
PEAS_EXTENSION
PEAS_IS_EXTENSION
diff --git a/libpeas/Makefile.am b/libpeas/Makefile.am
index 885d950..c0861ab 100644
--- a/libpeas/Makefile.am
+++ b/libpeas/Makefile.am
@@ -87,7 +87,7 @@ if HAVE_INTROSPECTION
introspection_sources = $(INST_H_FILES) $(C_FILES)
Peas-1.0.gir: libpeas-1.0.la
- Peas_1_0_gir_INCLUDES = GObject-2.0 GModule-2.0
+ Peas_1_0_gir_INCLUDES = GObject-2.0 GModule-2.0 GIRepository-2.0
Peas_1_0_gir_CFLAGS = $(PEAS_CFLAGS)
Peas_1_0_gir_LIBS = libpeas-1.0.la
Peas_1_0_gir_FILES = $(addprefix $(srcdir)/,$(introspection_sources))
diff --git a/libpeas/peas-extension.c b/libpeas/peas-extension.c
index a2c5803..9deb1a5 100644
--- a/libpeas/peas-extension.c
+++ b/libpeas/peas-extension.c
@@ -24,6 +24,7 @@
#endif
#include "peas-extension.h"
+#include "peas-introspection.h"
/**
* SECTION:peas-extension
@@ -210,11 +211,45 @@ peas_extension_call_valist (PeasExtension *exten,
const gchar *method_name,
va_list args)
{
+ GICallableInfo *callable_info;
+ GITypeInfo *retval_info;
+ GArgument *gargs;
+ GArgument retval;
+ gpointer retval_ptr;
+ gboolean ret;
+
+ g_return_val_if_fail (PEAS_IS_EXTENSION (exten), FALSE);
+ g_return_val_if_fail (method_name != NULL, FALSE);
+
+ callable_info = peas_gi_get_method_info (exten->priv->exten_type, method_name);
+ gargs = g_new (GArgument, g_callable_info_get_n_args (callable_info));
+ peas_gi_valist_to_arguments (callable_info, args, gargs, &retval_ptr);
+
+ ret = peas_extension_callv (exten, method_name, gargs, &retval);
+
+ if (retval_ptr != NULL)
+ {
+ retval_info = g_callable_info_get_return_type (callable_info);
+ peas_gi_argument_to_pointer (retval_info, &retval, retval_ptr);
+ g_base_info_unref ((GIBaseInfo *) retval_info);
+ }
+
+ g_free (gargs);
+
+ return ret;
+}
+
+gboolean
+peas_extension_callv (PeasExtension *exten,
+ const gchar *method_name,
+ GArgument *args,
+ GArgument *return_value)
+{
PeasExtensionClass *klass;
g_return_val_if_fail (PEAS_IS_EXTENSION (exten), FALSE);
g_return_val_if_fail (method_name != NULL, FALSE);
klass = PEAS_EXTENSION_GET_CLASS (exten);
- return klass->call (exten, method_name, args);
+ return klass->call (exten, method_name, args, return_value);
}
diff --git a/libpeas/peas-extension.h b/libpeas/peas-extension.h
index d74487e..8a2b89a 100644
--- a/libpeas/peas-extension.h
+++ b/libpeas/peas-extension.h
@@ -23,6 +23,7 @@
#define __PEAS_EXTENSION_H__
#include <glib-object.h>
+#include <girepository.h>
G_BEGIN_DECLS
@@ -66,7 +67,8 @@ struct _PeasExtensionClass {
/*< private >*/
gboolean (*call) (PeasExtension *exten,
const gchar *method,
- va_list args);
+ GArgument *args,
+ GArgument *return_value);
};
/*
@@ -83,6 +85,10 @@ gboolean peas_extension_call (PeasExtension *exten,
gboolean peas_extension_call_valist (PeasExtension *exten,
const gchar *method_name,
va_list args);
+gboolean peas_extension_callv (PeasExtension *exten,
+ const gchar *method_name,
+ GArgument *args,
+ GArgument *return_value);
G_END_DECLS
diff --git a/libpeas/peas-introspection.c b/libpeas/peas-introspection.c
index ea26dad..1ef4689 100644
--- a/libpeas/peas-introspection.c
+++ b/libpeas/peas-introspection.c
@@ -25,57 +25,200 @@
#include "peas-introspection.h"
-static gboolean
-set_return_value (gpointer in_retval,
- GArgument *out_retval,
- GITypeInfo *retval_type_info)
+void
+peas_gi_valist_to_arguments (GICallableInfo *callable_info,
+ va_list va_args,
+ GArgument *arguments,
+ gpointer *return_value)
{
- /* We should discourage people to actually use NULL for the return value. */
- g_return_val_if_fail (in_retval != NULL, TRUE);
+ guint i, n_args;
+ GIArgInfo *arg_info;
+ GITypeInfo *arg_type_info;
+ GITypeInfo *retval_info;
+ GArgument *cur_arg;
+
+ n_args = g_callable_info_get_n_args (callable_info);
+
+ for (i = 0; i < n_args; i++)
+ {
+ arg_info = g_callable_info_get_arg (callable_info, i);
+ arg_type_info = g_arg_info_get_type (arg_info);
+ cur_arg = &arguments[i];
+
+ switch (g_arg_info_get_direction (arg_info))
+ {
+ case GI_DIRECTION_IN:
+ {
+ /* Notes: According to GCC 4.4,
+ * - int8, uint8, int16, uint16, short and ushort are promoted to int when passed through '...'
+ * - float is promoted to double when passed through '...'
+ */
+ switch (g_type_info_get_tag (arg_type_info))
+ {
+ case GI_TYPE_TAG_VOID:
+ case GI_TYPE_TAG_BOOLEAN:
+ cur_arg->v_boolean = va_arg (va_args, gboolean);
+ break;
+ case GI_TYPE_TAG_INT8:
+ cur_arg->v_int8 = va_arg (va_args, gint);
+ break;
+ case GI_TYPE_TAG_UINT8:
+ cur_arg->v_uint8 = va_arg (va_args, gint);
+ break;
+ case GI_TYPE_TAG_INT16:
+ cur_arg->v_int16 = va_arg (va_args, gint);
+ break;
+ case GI_TYPE_TAG_UINT16:
+ cur_arg->v_uint16 = va_arg (va_args, gint);
+ break;
+ case GI_TYPE_TAG_INT32:
+ cur_arg->v_int32 = va_arg (va_args, gint32);
+ break;
+ case GI_TYPE_TAG_UINT32:
+ cur_arg->v_uint32 = va_arg (va_args, guint32);
+ break;
+ case GI_TYPE_TAG_INT64:
+ cur_arg->v_int64 = va_arg (va_args, gint64);
+ break;
+ case GI_TYPE_TAG_UINT64:
+ cur_arg->v_uint64 = va_arg (va_args, guint64);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ cur_arg->v_float = va_arg (va_args, gdouble);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ cur_arg->v_double = va_arg (va_args, gdouble);
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ /* apparently, GType is meant to be a gsize, from gobject/gtype.h in glib */
+ cur_arg->v_size = va_arg (va_args, GType);
+ break;
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ cur_arg->v_string = va_arg (va_args, gchar *);
+ break;
+ 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:
+ cur_arg->v_pointer = va_arg (va_args, gpointer);
+ break;
+ default:
+ g_warn_if_reached ();
+ cur_arg->v_pointer = va_arg (va_args, gpointer);
+ break;
+ }
+ break;
+ }
+ /* In the other cases, we expect we will always have a pointer. */
+ case GI_DIRECTION_INOUT:
+ case GI_DIRECTION_OUT:
+ cur_arg->v_pointer = va_arg (va_args, gpointer);
+ break;
+ }
+
+ g_base_info_unref ((GIBaseInfo *) arg_type_info);
+ g_base_info_unref ((GIBaseInfo *) arg_info);
+ }
+
+ if (return_value != NULL)
+ {
+ retval_info = g_callable_info_get_return_type (callable_info);
+
+ if (g_type_info_get_tag (retval_info) != GI_TYPE_TAG_VOID)
+ *return_value = va_arg (va_args, gpointer);
+ else
+ *return_value = NULL;
+
+ g_base_info_unref ((GIBaseInfo *) retval_info);
+ }
+}
+
+static void
+peas_gi_split_in_and_out_arguments (GICallableInfo *callable_info,
+ GArgument *args,
+ GArgument *in_args,
+ guint *n_in_args,
+ GArgument *out_args,
+ guint *n_out_args)
+{
+ guint n_args, i;
+ GIArgInfo *arg_info;
+
+ n_args = g_callable_info_get_n_args (callable_info);
+
+ for (i = 0; i < n_args; i++)
+ {
+ arg_info = g_callable_info_get_arg (callable_info, i);
+
+ switch (g_arg_info_get_direction (arg_info))
+ {
+ case GI_DIRECTION_IN:
+ in_args[(*n_in_args)++] = args[i];
+ break;
+ case GI_DIRECTION_INOUT:
+ in_args[(*n_in_args)++] = args[i];
+ out_args[(*n_out_args)++] = args[i];
+ break;
+ case GI_DIRECTION_OUT:
+ out_args[(*n_out_args)++] = args[i];
+ break;
+ }
- switch (g_type_info_get_tag (retval_type_info))
+ g_base_info_unref ((GIBaseInfo *) arg_info);
+ }
+}
+
+void
+peas_gi_argument_to_pointer (GITypeInfo *type_info,
+ GArgument *arg,
+ gpointer ptr)
+{
+ switch (g_type_info_get_tag (type_info))
{
case GI_TYPE_TAG_VOID:
case GI_TYPE_TAG_BOOLEAN:
- *((gboolean *) in_retval) = out_retval->v_boolean;
+ *((gboolean *) ptr) = arg->v_boolean;
break;
case GI_TYPE_TAG_INT8:
- *((gint8 *) in_retval) = out_retval->v_int8;
+ *((gint8 *) ptr) = arg->v_int8;
break;
case GI_TYPE_TAG_UINT8:
- *((guint8 *) in_retval) = out_retval->v_uint8;
+ *((guint8 *) ptr) = arg->v_uint8;
break;
case GI_TYPE_TAG_INT16:
- *((gint16 *) in_retval) = out_retval->v_int16;
+ *((gint16 *) ptr) = arg->v_int16;
break;
case GI_TYPE_TAG_UINT16:
- *((guint16 *) in_retval) = out_retval->v_uint16;
+ *((guint16 *) ptr) = arg->v_uint16;
break;
case GI_TYPE_TAG_INT32:
- *((gint32 *) in_retval) = out_retval->v_int32;
+ *((gint32 *) ptr) = arg->v_int32;
break;
case GI_TYPE_TAG_UINT32:
- *((guint32 *) in_retval) = out_retval->v_uint32;
+ *((guint32 *) ptr) = arg->v_uint32;
break;
case GI_TYPE_TAG_INT64:
- *((gint64 *) in_retval) = out_retval->v_int64;
+ *((gint64 *) ptr) = arg->v_int64;
break;
case GI_TYPE_TAG_UINT64:
- *((guint64 *) in_retval) = out_retval->v_uint64;
+ *((guint64 *) ptr) = arg->v_uint64;
break;
case GI_TYPE_TAG_FLOAT:
- *((gfloat *) in_retval) = out_retval->v_float;
+ *((gfloat *) ptr) = arg->v_float;
break;
case GI_TYPE_TAG_DOUBLE:
- *((gdouble *) in_retval) = out_retval->v_double;
+ *((gdouble *) ptr) = arg->v_double;
break;
case GI_TYPE_TAG_GTYPE:
/* apparently, GType is meant to be a gsize, from gobject/gtype.h in glib */
- *((gsize *) in_retval) = out_retval->v_size;
+ *((gsize *) ptr) = arg->v_size;
break;
case GI_TYPE_TAG_UTF8:
case GI_TYPE_TAG_FILENAME:
- *((gchar **) in_retval) = out_retval->v_string;
+ *((gchar **) ptr) = arg->v_string;
break;
case GI_TYPE_TAG_ARRAY:
case GI_TYPE_TAG_INTERFACE:
@@ -83,18 +226,16 @@ set_return_value (gpointer in_retval,
case GI_TYPE_TAG_GSLIST:
case GI_TYPE_TAG_GHASH:
case GI_TYPE_TAG_ERROR:
- *((gsize **) in_retval) = out_retval->v_pointer;
+ *((gpointer **) ptr) = arg->v_pointer;
break;
default:
- g_return_val_if_reached (FALSE);
+ g_return_if_reached ();
}
-
- return TRUE;
}
GICallableInfo *
-peas_method_get_info (GType iface_type,
- const gchar *method_name)
+peas_gi_get_method_info (GType iface_type,
+ const gchar *method_name)
{
GIRepository *repo;
GIBaseInfo *iface_info;
@@ -135,26 +276,22 @@ peas_method_get_info (GType iface_type,
}
gboolean
-peas_method_apply_valist (GObject *instance,
- GType iface_type,
- const gchar *method_name,
- va_list args)
+peas_method_apply (GObject *instance,
+ GType iface_type,
+ const gchar *method_name,
+ GArgument *args,
+ GArgument *return_value)
{
GICallableInfo *func_info;
- GITypeInfo *retval_info;
- GArgument out_retval;
guint n_args, n_in_args, n_out_args;
GArgument *in_args, *out_args;
- guint i;
gboolean ret = TRUE;
GError *error = NULL;
- func_info = peas_method_get_info (iface_type, method_name);
+ func_info = peas_gi_get_method_info (iface_type, method_name);
if (func_info == NULL)
return FALSE;
- retval_info = g_callable_info_get_return_type (func_info);
-
n_args = g_callable_info_get_n_args (func_info);
n_in_args = 0;
n_out_args = 0;
@@ -162,112 +299,19 @@ peas_method_apply_valist (GObject *instance,
in_args = g_new0 (GArgument, n_args + 1);
out_args = g_new0 (GArgument, n_args);
- /* Set the object as the first argument for the method. */
- in_args[n_in_args++].v_pointer = instance;
-
- ret = TRUE;
- for (i = 0; ret && i < n_args; i++)
- {
- GIArgInfo *arg_info;
- GITypeInfo *arg_type_info;
-
- arg_info = g_callable_info_get_arg (func_info, i);
- arg_type_info = g_arg_info_get_type (arg_info);
-
- switch (g_arg_info_get_direction (arg_info))
- {
- case GI_DIRECTION_IN:
- {
- GArgument *cur_arg = &in_args[n_in_args++];
-
- /* Notes: According to GCC 4.4,
- * - int8, uint8, int16, uint16, short and ushort are promoted to int when passed through '...'
- * - float is promoted to double when passed through '...'
- */
- switch (g_type_info_get_tag (arg_type_info))
- {
- case GI_TYPE_TAG_VOID:
- case GI_TYPE_TAG_BOOLEAN:
- cur_arg->v_boolean = va_arg (args, gboolean);
- break;
- case GI_TYPE_TAG_INT8:
- cur_arg->v_int8 = va_arg (args, gint);
- break;
- case GI_TYPE_TAG_UINT8:
- cur_arg->v_uint8 = va_arg (args, gint);
- break;
- case GI_TYPE_TAG_INT16:
- cur_arg->v_int16 = va_arg (args, gint);
- break;
- case GI_TYPE_TAG_UINT16:
- cur_arg->v_uint16 = va_arg (args, gint);
- break;
- case GI_TYPE_TAG_INT32:
- cur_arg->v_int32 = va_arg (args, gint32);
- break;
- case GI_TYPE_TAG_UINT32:
- cur_arg->v_uint32 = va_arg (args, guint32);
- break;
- case GI_TYPE_TAG_INT64:
- cur_arg->v_int64 = va_arg (args, gint64);
- break;
- case GI_TYPE_TAG_UINT64:
- cur_arg->v_uint64 = va_arg (args, guint64);
- break;
- case GI_TYPE_TAG_FLOAT:
- cur_arg->v_float = va_arg (args, gdouble);
- break;
- case GI_TYPE_TAG_DOUBLE:
- cur_arg->v_double = va_arg (args, gdouble);
- break;
- case GI_TYPE_TAG_GTYPE:
- /* apparently, GType is meant to be a gsize, from gobject/gtype.h in glib */
- cur_arg->v_size = va_arg (args, GType);
- break;
- case GI_TYPE_TAG_UTF8:
- case GI_TYPE_TAG_FILENAME:
- cur_arg->v_string = va_arg (args, gchar *);
- break;
- 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:
- cur_arg->v_pointer = va_arg (args, gpointer);
- break;
- default:
- g_warn_if_reached ();
- ret = FALSE;
- break;
- }
- break;
- }
- /* In the other cases, we expect we will always have a pointer. */
- case GI_DIRECTION_INOUT:
- in_args[n_in_args++].v_pointer = out_args[n_out_args++].v_pointer = va_arg (args, gpointer);
- break;
- case GI_DIRECTION_OUT:
- out_args[n_out_args++].v_pointer = va_arg (args, gpointer);
- break;
- }
-
- g_base_info_unref ((GIBaseInfo *) arg_type_info);
- g_base_info_unref ((GIBaseInfo *) arg_info);
- }
+ peas_gi_split_in_and_out_arguments (func_info, args,
+ in_args+1, &n_in_args,
+ out_args, &n_out_args);
- if (!ret)
- {
- g_warning ("Invalid argument type for calling '%s.%s'",
- g_type_name (iface_type), method_name);
- goto out;
- }
+ /* Set the object as the first argument for the method. */
+ in_args[0].v_pointer = instance;
+ n_in_args++;
g_debug ("Calling '%s.%s' on '%p'",
g_type_name (iface_type), method_name, instance);
ret = g_function_info_invoke (func_info, in_args, n_in_args, out_args,
- n_out_args, &out_retval, &error);
+ n_out_args, return_value, &error);
if (!ret)
{
g_warning ("Error while calling '%s.%s': %s",
@@ -276,21 +320,9 @@ peas_method_apply_valist (GObject *instance,
goto out;
}
- if (g_type_info_get_tag (retval_info) != GI_TYPE_TAG_VOID)
- {
- ret = set_return_value (va_arg (args, gpointer), &out_retval, retval_info);
-
- if (!ret)
- {
- g_warning ("Invalid return type for '%s.%s'",
- g_type_name (iface_type), method_name);
- }
- }
-
out:
g_free (in_args);
g_free (out_args);
- g_base_info_unref ((GIBaseInfo *) retval_info);
g_base_info_unref ((GIBaseInfo *) func_info);
return ret;
diff --git a/libpeas/peas-introspection.h b/libpeas/peas-introspection.h
index 0c373f4..679f9cf 100644
--- a/libpeas/peas-introspection.h
+++ b/libpeas/peas-introspection.h
@@ -27,13 +27,21 @@
G_BEGIN_DECLS
-GICallableInfo *peas_method_get_info (GType iface_type,
+GICallableInfo *peas_gi_get_method_info (GType iface_type,
const gchar *method_name);
-gboolean peas_method_apply_valist (GObject *instance,
+void peas_gi_valist_to_arguments (GICallableInfo *callable_info,
+ va_list va_args,
+ GArgument *arguments,
+ gpointer *return_value);
+void peas_gi_argument_to_pointer (GITypeInfo *type_info,
+ GArgument *arg,
+ gpointer ptr);
+gboolean peas_method_apply (GObject *instance,
GType iface_type,
const gchar *method_name,
- va_list args);
+ GArgument *args,
+ GArgument *return_value);
G_END_DECLS
diff --git a/loaders/c/peas-extension-c.c b/loaders/c/peas-extension-c.c
index 60556ce..0fe4815 100644
--- a/loaders/c/peas-extension-c.c
+++ b/loaders/c/peas-extension-c.c
@@ -43,14 +43,15 @@ peas_extension_c_init (PeasExtensionC *cexten)
static gboolean
peas_extension_c_call (PeasExtension *exten,
const gchar *method_name,
- va_list args)
+ GArgument *args,
+ GArgument *retval)
{
PeasExtensionC *cexten = PEAS_EXTENSION_C (exten);
GType gtype;
gtype = peas_extension_get_extension_type (exten);
- return peas_method_apply_valist (cexten->instance, gtype, method_name, args);
+ return peas_method_apply (cexten->instance, gtype, method_name, args, retval);
}
static void
diff --git a/loaders/python/peas-extension-python.c b/loaders/python/peas-extension-python.c
index 8a505a7..a667933 100644
--- a/loaders/python/peas-extension-python.c
+++ b/loaders/python/peas-extension-python.c
@@ -48,7 +48,8 @@ peas_extension_python_init (PeasExtensionPython *pyexten)
static gboolean
peas_extension_python_call (PeasExtension *exten,
const gchar *method_name,
- va_list args)
+ GArgument *args,
+ GArgument *retval)
{
PeasExtensionPython *pyexten = PEAS_EXTENSION_PYTHON (exten);
GType gtype;
@@ -57,7 +58,7 @@ peas_extension_python_call (PeasExtension *exten,
gtype = peas_extension_get_extension_type (exten);
instance = pygobject_get (pyexten->instance);
- return peas_method_apply_valist (instance, gtype, method_name, args);
+ return peas_method_apply (instance, gtype, method_name, args, retval);
}
static void
diff --git a/loaders/seed/peas-extension-seed.c b/loaders/seed/peas-extension-seed.c
index b7b4274..71094e7 100644
--- a/loaders/seed/peas-extension-seed.c
+++ b/loaders/seed/peas-extension-seed.c
@@ -38,7 +38,7 @@ enum {
typedef struct {
GITypeInfo *type_info;
- gpointer ptr;
+ GArgument *ptr;
} OutArg;
static void
@@ -88,10 +88,10 @@ peas_extension_seed_finalize (GObject *object)
}
static SeedValue
-read_next_argument (SeedContext ctx,
- va_list args,
- GITypeInfo *arg_type_info,
- SeedException *exc)
+get_argument (SeedContext ctx,
+ GArgument *arg,
+ GITypeInfo *arg_type_info,
+ SeedException *exc)
{
/* Notes: According to GCC 4.4,
* - int8, uint8, int16, uint16, short and ushort are promoted to int when passed through '...'
@@ -103,37 +103,40 @@ read_next_argument (SeedContext ctx,
g_assert_not_reached ();
break;
case GI_TYPE_TAG_BOOLEAN:
- return seed_value_from_boolean (ctx, va_arg (args, gboolean), exc);
+ return seed_value_from_boolean (ctx, arg->v_boolean, exc);
case GI_TYPE_TAG_INT8:
- case GI_TYPE_TAG_INT16:
- return seed_value_from_int (ctx, va_arg (args, gint), exc);
+ return seed_value_from_int (ctx, arg->v_int8, exc);
case GI_TYPE_TAG_UINT8:
+ return seed_value_from_uint (ctx, arg->v_uint8, exc);
+ case GI_TYPE_TAG_INT16:
+ return seed_value_from_int (ctx, arg->v_int16, exc);
case GI_TYPE_TAG_UINT16:
- return seed_value_from_uint (ctx, va_arg (args, guint), exc);
+ return seed_value_from_uint (ctx, arg->v_uint16, exc);
case GI_TYPE_TAG_INT32:
- return seed_value_from_long (ctx, va_arg (args, gint32), exc);
+ return seed_value_from_long (ctx, arg->v_int32, exc);
case GI_TYPE_TAG_UINT32:
- return seed_value_from_ulong (ctx, va_arg (args, guint32), exc);
+ return seed_value_from_ulong (ctx, arg->v_uint32, exc);
case GI_TYPE_TAG_INT64:
- return seed_value_from_int64 (ctx, va_arg (args, gint64), exc);
+ return seed_value_from_int64 (ctx, arg->v_int64, exc);
case GI_TYPE_TAG_UINT64:
- return seed_value_from_uint64 (ctx, va_arg (args, guint64), exc);
+ return seed_value_from_uint64 (ctx, arg->v_uint64, exc);
case GI_TYPE_TAG_FLOAT:
+ return seed_value_from_float (ctx, arg->v_float, exc);
case GI_TYPE_TAG_DOUBLE:
- return seed_value_from_double (ctx, va_arg (args, gdouble), exc);
+ return seed_value_from_double (ctx, arg->v_double, exc);
break;
case GI_TYPE_TAG_GTYPE:
/* apparently, GType is meant to be a gsize, from gobject/gtype.h in glib */
- return seed_value_from_ulong (ctx, va_arg (args, GType), exc);
+ return seed_value_from_ulong (ctx, arg->v_size, exc);
case GI_TYPE_TAG_UTF8:
- return seed_value_from_string (ctx, va_arg (args, gchar *), exc);
+ return seed_value_from_string (ctx, arg->v_string, exc);
case GI_TYPE_TAG_FILENAME:
- return seed_value_from_filename (ctx, va_arg (args, gchar *), exc);
+ return seed_value_from_filename (ctx, arg->v_string, exc);
case GI_TYPE_TAG_INTERFACE:
- return seed_value_from_object (ctx, va_arg (args, GObject *), exc);
+ return seed_value_from_object (ctx, arg->v_pointer, exc);
/* FIXME */
case GI_TYPE_TAG_ARRAY:
@@ -158,53 +161,53 @@ set_return_value (OutArg *arg,
switch (g_type_info_get_tag (arg->type_info))
{
case GI_TYPE_TAG_BOOLEAN:
- *((gboolean *) arg->ptr) = seed_value_to_boolean (ctx, value, exc);
+ arg->ptr->v_boolean = seed_value_to_boolean (ctx, value, exc);
break;
case GI_TYPE_TAG_INT8:
- *((gint8 *) arg->ptr) = seed_value_to_int (ctx, value, exc);
+ arg->ptr->v_int8 = seed_value_to_int (ctx, value, exc);
break;
case GI_TYPE_TAG_UINT8:
- *((guint8 *) arg->ptr) = seed_value_to_uint (ctx, value, exc);
+ arg->ptr->v_uint8 = seed_value_to_uint (ctx, value, exc);
break;
case GI_TYPE_TAG_INT16:
- *((gint16 *) arg->ptr) = seed_value_to_int (ctx, value, exc);
+ arg->ptr->v_int16 = seed_value_to_int (ctx, value, exc);
break;
case GI_TYPE_TAG_UINT16:
- *((guint16 *) arg->ptr) = seed_value_to_uint (ctx, value, exc);
+ arg->ptr->v_uint16 = seed_value_to_uint (ctx, value, exc);
break;
case GI_TYPE_TAG_INT32:
- *((gint32 *) arg->ptr) = seed_value_to_long (ctx, value, exc);
+ arg->ptr->v_int32 = seed_value_to_long (ctx, value, exc);
break;
case GI_TYPE_TAG_UINT32:
- *((guint32 *) arg->ptr) = seed_value_to_ulong (ctx, value, exc);
+ arg->ptr->v_uint32 = seed_value_to_ulong (ctx, value, exc);
break;
case GI_TYPE_TAG_INT64:
- *((gint64 *) arg->ptr) = seed_value_to_int64 (ctx, value, exc);
+ arg->ptr->v_int64 = seed_value_to_int64 (ctx, value, exc);
break;
case GI_TYPE_TAG_UINT64:
- *((guint64 *) arg->ptr) = seed_value_to_uint64 (ctx, value, exc);
+ arg->ptr->v_uint64 = seed_value_to_uint64 (ctx, value, exc);
break;
case GI_TYPE_TAG_FLOAT:
- *((gfloat *) arg->ptr) = seed_value_to_float (ctx, value, exc);
+ arg->ptr->v_float = seed_value_to_float (ctx, value, exc);
break;
case GI_TYPE_TAG_DOUBLE:
- *((gdouble *) arg->ptr) = seed_value_to_double (ctx, value, exc);
+ arg->ptr->v_double = seed_value_to_double (ctx, value, exc);
break;
case GI_TYPE_TAG_GTYPE:
/* apparently, GType is meant to be a gsize, from gobject/gtype.h in glib */
- *((GType *) arg->ptr) = seed_value_to_ulong (ctx, value, exc);
+ arg->ptr->v_size = seed_value_to_ulong (ctx, value, exc);
break;
case GI_TYPE_TAG_UTF8:
- *((gchar **) arg->ptr) = seed_value_to_string (ctx, value, exc);
+ arg->ptr->v_string = seed_value_to_string (ctx, value, exc);
break;
case GI_TYPE_TAG_FILENAME:
- *((gchar **) arg->ptr) = seed_value_to_filename (ctx, value, exc);
+ arg->ptr->v_string = seed_value_to_filename (ctx, value, exc);
break;
case GI_TYPE_TAG_INTERFACE:
- *((GObject **) arg->ptr) = seed_value_to_object (ctx, value, exc);
+ arg->ptr->v_pointer = seed_value_to_object (ctx, value, exc);
break;
/* FIXME */
@@ -213,7 +216,7 @@ set_return_value (OutArg *arg,
case GI_TYPE_TAG_GSLIST:
case GI_TYPE_TAG_GHASH:
case GI_TYPE_TAG_ERROR:
- *((gpointer *) arg->ptr) = NULL;
+ arg->ptr->v_pointer = NULL;
default:
g_return_if_reached ();
@@ -223,12 +226,14 @@ set_return_value (OutArg *arg,
static gboolean
peas_extension_seed_call (PeasExtension *exten,
const gchar *method_name,
- va_list args)
+ GArgument *args,
+ GArgument *retval)
{
PeasExtensionSeed *sexten = PEAS_EXTENSION_SEED (exten);
GType exten_type;
SeedValue js_method;
GICallableInfo *func_info;
+ GITypeInfo *retval_info;
guint n_args, n_in_args, n_out_args, i;
SeedValue *js_in_args;
OutArg *out_args;
@@ -261,14 +266,27 @@ peas_extension_seed_call (PeasExtension *exten,
}
/* Prepare the arguments */
- func_info = peas_method_get_info (exten_type, method_name);
+ func_info = peas_gi_get_method_info (exten_type, method_name);
n_args = g_callable_info_get_n_args (func_info);
n_in_args = 0;
n_out_args = 0;
js_in_args = g_new0 (SeedValue, n_args);
- out_args = g_new0 (OutArg, n_args);
+ out_args = g_new0 (OutArg, n_args + 1);
+
+ /* We put the return value first in the out tuple, as it seems to be
+ * the common behaviour for GI-based bindings */
+ retval_info = g_callable_info_get_return_type (func_info);
+ if (g_type_info_get_tag (retval_info) != GI_TYPE_TAG_VOID)
+ {
+ out_args[0].ptr = retval;
+ out_args[0].type_info = retval_info;
+ g_base_info_ref ((GIBaseInfo *) retval_info);
+ n_out_args = 1;
+ }
+ g_base_info_unref ((GIBaseInfo *) retval_info);
+ /* Handle the other arguments */
for (i = 0; i < n_args && exc == NULL; i++)
{
GIArgInfo *arg_info;
@@ -280,13 +298,13 @@ peas_extension_seed_call (PeasExtension *exten,
switch (g_arg_info_get_direction (arg_info))
{
case GI_DIRECTION_IN:
- js_in_args[n_in_args++] = read_next_argument (sexten->js_context,
- args,
- arg_type_info,
- &exc);
+ js_in_args[n_in_args++] = get_argument (sexten->js_context,
+ &args[i],
+ arg_type_info,
+ &exc);
break;
case GI_DIRECTION_OUT:
- out_args[n_out_args].ptr = va_arg (args, gpointer);
+ out_args[n_out_args].ptr = &args[i];
out_args[n_out_args].type_info = arg_type_info;
g_base_info_ref ((GIBaseInfo *) arg_type_info);
n_out_args++;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]