summaryrefslogtreecommitdiff
path: root/girepository/ginvoke.c
diff options
context:
space:
mode:
Diffstat (limited to 'girepository/ginvoke.c')
-rw-r--r--girepository/ginvoke.c142
1 files changed, 104 insertions, 38 deletions
diff --git a/girepository/ginvoke.c b/girepository/ginvoke.c
index 84e1e748..581956a3 100644
--- a/girepository/ginvoke.c
+++ b/girepository/ginvoke.c
@@ -88,57 +88,121 @@ value_to_ffi_type (const GValue *gvalue, gpointer *value)
return rettype;
}
+/* See comment aboe set_gargument_from_ffi_return_value() */
+static ffi_type *
+g_value_to_ffi_return_type (const GValue *gvalue,
+ const GIArgument *ffi_value,
+ gpointer *value)
+{
+ ffi_type *rettype = NULL;
+ GType type = g_type_fundamental (G_VALUE_TYPE (gvalue));
+ g_assert (type != G_TYPE_INVALID);
+
+ *value = (gpointer)&(ffi_value->v_long);
+
+ switch (type) {
+ case G_TYPE_CHAR:
+ rettype = &ffi_type_sint8;
+ break;
+ case G_TYPE_UCHAR:
+ rettype = &ffi_type_uint8;
+ break;
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_INT:
+ rettype = &ffi_type_sint;
+ break;
+ case G_TYPE_UINT:
+ rettype = &ffi_type_uint;
+ break;
+ case G_TYPE_STRING:
+ case G_TYPE_OBJECT:
+ case G_TYPE_BOXED:
+ case G_TYPE_POINTER:
+ rettype = &ffi_type_pointer;
+ break;
+ case G_TYPE_FLOAT:
+ rettype = &ffi_type_float;
+ *value = (gpointer)&(ffi_value->v_float);
+ break;
+ case G_TYPE_DOUBLE:
+ rettype = &ffi_type_double;
+ *value = (gpointer)&(ffi_value->v_double);
+ break;
+ case G_TYPE_LONG:
+ rettype = &ffi_type_slong;
+ break;
+ case G_TYPE_ULONG:
+ rettype = &ffi_type_ulong;
+ break;
+ case G_TYPE_INT64:
+ rettype = &ffi_type_sint64;
+ *value = (gpointer)&(ffi_value->v_int64);
+ break;
+ case G_TYPE_UINT64:
+ rettype = &ffi_type_uint64;
+ *value = (gpointer)&(ffi_value->v_uint64);
+ break;
+ default:
+ rettype = &ffi_type_pointer;
+ *value = NULL;
+ g_warning ("Unsupported fundamental type: %s", g_type_name (type));
+ break;
+ }
+ return rettype;
+}
+
static void
-value_from_ffi_type (GValue *gvalue, gpointer *value)
+g_value_from_ffi_value (GValue *gvalue,
+ const GIArgument *value)
{
- switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
- {
- case G_TYPE_INT:
- g_value_set_int (gvalue, *(gint*)value);
+ switch (g_type_fundamental (G_VALUE_TYPE (gvalue))) {
+ case G_TYPE_INT:
+ g_value_set_int (gvalue, (gint)value->v_long);
break;
- case G_TYPE_FLOAT:
- g_value_set_float (gvalue, *(gfloat*)value);
+ case G_TYPE_FLOAT:
+ g_value_set_float (gvalue, (gfloat)value->v_float);
break;
- case G_TYPE_DOUBLE:
- g_value_set_double (gvalue, *(gdouble*)value);
+ case G_TYPE_DOUBLE:
+ g_value_set_double (gvalue, (gdouble)value->v_double);
break;
- case G_TYPE_BOOLEAN:
- g_value_set_boolean (gvalue, *(gboolean*)value);
+ case G_TYPE_BOOLEAN:
+ g_value_set_boolean (gvalue, (gboolean)value->v_long);
break;
- case G_TYPE_STRING:
- g_value_set_string (gvalue, *(gchar**)value);
+ case G_TYPE_STRING:
+ g_value_set_string (gvalue, (gchar*)value->v_pointer);
break;
- case G_TYPE_CHAR:
- g_value_set_char (gvalue, *(gchar*)value);
+ case G_TYPE_CHAR:
+ g_value_set_char (gvalue, (gchar)value->v_long);
break;
- case G_TYPE_UCHAR:
- g_value_set_uchar (gvalue, *(guchar*)value);
+ case G_TYPE_UCHAR:
+ g_value_set_uchar (gvalue, (guchar)value->v_ulong);
break;
- case G_TYPE_UINT:
- g_value_set_uint (gvalue, *(guint*)value);
+ case G_TYPE_UINT:
+ g_value_set_uint (gvalue, (guint)value->v_ulong);
break;
- case G_TYPE_POINTER:
- g_value_set_pointer (gvalue, *(gpointer*)value);
+ case G_TYPE_POINTER:
+ g_value_set_pointer (gvalue, (gpointer)value->v_pointer);
break;
- case G_TYPE_LONG:
- g_value_set_long (gvalue, *(glong*)value);
+ case G_TYPE_LONG:
+ g_value_set_long (gvalue, (glong)value->v_long);
break;
- case G_TYPE_ULONG:
- g_value_set_ulong (gvalue, *(gulong*)value);
+ case G_TYPE_ULONG:
+ g_value_set_ulong (gvalue, (gulong)value->v_ulong);
break;
- case G_TYPE_INT64:
- g_value_set_int64 (gvalue, *(gint64*)value);
+ case G_TYPE_INT64:
+ g_value_set_int64 (gvalue, (gint64)value->v_int64);
break;
- case G_TYPE_UINT64:
- g_value_set_uint64 (gvalue, *(guint64*)value);
+ case G_TYPE_UINT64:
+ g_value_set_uint64 (gvalue, (guint64)value->v_uint64);
break;
- case G_TYPE_BOXED:
- g_value_set_boxed (gvalue, *(gpointer*)value);
+ case G_TYPE_BOXED:
+ g_value_set_boxed (gvalue, (gpointer)value->v_pointer);
break;
- default:
- g_warning ("Unsupported fundamental type: %s",
- g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));
- }
+ default:
+ g_warning ("Unsupported fundamental type: %s",
+ g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));
+ }
+
}
void
@@ -149,6 +213,7 @@ gi_cclosure_marshal_generic (GClosure *closure,
gpointer invocation_hint,
gpointer marshal_data)
{
+ GIArgument return_ffi_value;
ffi_type *rtype;
void *rvalue;
int n_args;
@@ -160,15 +225,16 @@ gi_cclosure_marshal_generic (GClosure *closure,
if (return_gvalue && G_VALUE_TYPE (return_gvalue))
{
+ rtype = g_value_to_ffi_return_type (return_gvalue, &return_ffi_value,
+ &rvalue);
rtype = value_to_ffi_type (return_gvalue, &rvalue);
}
else
{
rtype = &ffi_type_void;
+ rvalue = &return_ffi_value.v_long;
}
- rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg)));
-
n_args = n_param_values + 1;
atypes = g_alloca (sizeof (ffi_type *) * n_args);
args = g_alloca (sizeof (gpointer) * n_args);
@@ -204,5 +270,5 @@ gi_cclosure_marshal_generic (GClosure *closure,
ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args);
if (return_gvalue && G_VALUE_TYPE (return_gvalue))
- value_from_ffi_type (return_gvalue, rvalue);
+ g_value_from_ffi_value (return_gvalue, &return_ffi_value);
}