mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 15:36:17 +01:00
Bug 567087 - generic marshaller
Since GObject-Introspection depends on both ffi and GObject, it's a convenient home for jdahlin's generic signal marshaller until such time as GObject can directly depend on ffi. When it gets added to GObject, we can simply point our marshaller at that one. svn path=/trunk/; revision=1022
This commit is contained in:
parent
b95d92aca0
commit
ca638d9ecf
171
ginvoke.c
171
ginvoke.c
@ -261,3 +261,174 @@ g_function_info_invoke (GIFunctionInfo *info,
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
static ffi_type *
|
||||
value_to_ffi_type (const GValue *gvalue, gpointer *value)
|
||||
{
|
||||
ffi_type *rettype = NULL;
|
||||
GType type = g_type_fundamental (G_VALUE_TYPE (gvalue));
|
||||
g_assert (type != G_TYPE_INVALID);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case G_TYPE_BOOLEAN:
|
||||
case G_TYPE_CHAR:
|
||||
case G_TYPE_INT:
|
||||
rettype = &ffi_type_sint;
|
||||
*value = (gpointer)&(gvalue->data[0].v_int);
|
||||
break;
|
||||
case G_TYPE_UCHAR:
|
||||
case G_TYPE_UINT:
|
||||
rettype = &ffi_type_uint;
|
||||
*value = (gpointer)&(gvalue->data[0].v_uint);
|
||||
break;
|
||||
case G_TYPE_STRING:
|
||||
case G_TYPE_OBJECT:
|
||||
case G_TYPE_BOXED:
|
||||
case G_TYPE_POINTER:
|
||||
rettype = &ffi_type_pointer;
|
||||
*value = (gpointer)&(gvalue->data[0].v_pointer);
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
rettype = &ffi_type_float;
|
||||
*value = (gpointer)&(gvalue->data[0].v_float);
|
||||
break;
|
||||
case G_TYPE_DOUBLE:
|
||||
rettype = &ffi_type_double;
|
||||
*value = (gpointer)&(gvalue->data[0].v_double);
|
||||
break;
|
||||
case G_TYPE_LONG:
|
||||
rettype = &ffi_type_slong;
|
||||
*value = (gpointer)&(gvalue->data[0].v_long);
|
||||
break;
|
||||
case G_TYPE_ULONG:
|
||||
rettype = &ffi_type_ulong;
|
||||
*value = (gpointer)&(gvalue->data[0].v_ulong);
|
||||
break;
|
||||
case G_TYPE_INT64:
|
||||
rettype = &ffi_type_sint64;
|
||||
*value = (gpointer)&(gvalue->data[0].v_int64);
|
||||
break;
|
||||
case G_TYPE_UINT64:
|
||||
rettype = &ffi_type_uint64;
|
||||
*value = (gpointer)&(gvalue->data[0].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)
|
||||
{
|
||||
switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))
|
||||
{
|
||||
case G_TYPE_INT:
|
||||
g_value_set_int (gvalue, *(gint*)value);
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
g_value_set_float (gvalue, *(gfloat*)value);
|
||||
break;
|
||||
case G_TYPE_DOUBLE:
|
||||
g_value_set_double (gvalue, *(gdouble*)value);
|
||||
break;
|
||||
case G_TYPE_BOOLEAN:
|
||||
g_value_set_boolean (gvalue, *(gboolean*)value);
|
||||
break;
|
||||
case G_TYPE_STRING:
|
||||
g_value_set_string (gvalue, *(gchar**)value);
|
||||
break;
|
||||
case G_TYPE_CHAR:
|
||||
g_value_set_char (gvalue, *(gchar*)value);
|
||||
break;
|
||||
case G_TYPE_UCHAR:
|
||||
g_value_set_uchar (gvalue, *(guchar*)value);
|
||||
break;
|
||||
case G_TYPE_UINT:
|
||||
g_value_set_uint (gvalue, *(guint*)value);
|
||||
break;
|
||||
case G_TYPE_POINTER:
|
||||
g_value_set_pointer (gvalue, *(gpointer*)value);
|
||||
break;
|
||||
case G_TYPE_LONG:
|
||||
g_value_set_long (gvalue, *(glong*)value);
|
||||
break;
|
||||
case G_TYPE_ULONG:
|
||||
g_value_set_ulong (gvalue, *(gulong*)value);
|
||||
break;
|
||||
case G_TYPE_INT64:
|
||||
g_value_set_int64 (gvalue, *(gint64*)value);
|
||||
break;
|
||||
case G_TYPE_UINT64:
|
||||
g_value_set_uint64 (gvalue, *(guint64*)value);
|
||||
break;
|
||||
case G_TYPE_BOXED:
|
||||
g_value_set_boxed (gvalue, *(gpointer*)value);
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unsupported fundamental type: %s",
|
||||
g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gi_cclosure_marshal_generic (GClosure *closure,
|
||||
GValue *return_gvalue,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data)
|
||||
{
|
||||
ffi_type *rtype;
|
||||
void *rvalue;
|
||||
int n_args;
|
||||
ffi_type **atypes;
|
||||
void **args;
|
||||
int i;
|
||||
ffi_cif cif;
|
||||
GCClosure *cc = (GCClosure*) closure;
|
||||
|
||||
if (return_gvalue && G_VALUE_TYPE (return_gvalue))
|
||||
{
|
||||
rtype = value_to_ffi_type (return_gvalue, &rvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtype = &ffi_type_void;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||
{
|
||||
atypes[n_args-1] = value_to_ffi_type (param_values + 0,
|
||||
&args[n_args-1]);
|
||||
atypes[0] = &ffi_type_pointer;
|
||||
args[0] = &closure->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
atypes[0] = value_to_ffi_type (param_values + 0, &args[0]);
|
||||
atypes[n_args-1] = &ffi_type_pointer;
|
||||
args[n_args-1] = &closure->data;
|
||||
}
|
||||
|
||||
for (i = 1; i < n_args - 1; i++)
|
||||
atypes[i] = value_to_ffi_type (param_values + i, &args[i]);
|
||||
|
||||
if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK)
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -141,6 +141,15 @@ typedef enum
|
||||
GQuark g_irepository_error_quark (void);
|
||||
|
||||
|
||||
/* Global utility functions */
|
||||
|
||||
void gi_cclosure_marshal_generic (GClosure *closure,
|
||||
GValue *return_gvalue,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data);
|
||||
|
||||
/* Types of objects registered in the repository */
|
||||
|
||||
typedef enum
|
||||
|
Loading…
Reference in New Issue
Block a user