[seed: 7/7] [ffi] Calling functions works now...
- From: Robert Carr <racarr src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [seed: 7/7] [ffi] Calling functions works now...
- Date: Sun, 2 Aug 2009 01:29:08 +0000 (UTC)
commit 04adfffbe102296024ff2d1d8f5fb6f16d38860a
Author: Robert Carr <racarr gnome org>
Date: Sat Aug 1 21:28:14 2009 -0400
[ffi] Calling functions works now...
modules/ffi/Makefile.am | 2 +-
modules/ffi/seed-ffi.c | 220 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 216 insertions(+), 6 deletions(-)
---
diff --git a/modules/ffi/Makefile.am b/modules/ffi/Makefile.am
index c13f2ea..965e8ad 100644
--- a/modules/ffi/Makefile.am
+++ b/modules/ffi/Makefile.am
@@ -8,7 +8,7 @@ seedlib_LTLIBRARIES = \
libseed_ffi_la_SOURCES = \
seed-ffi.c
-AM_CPPFLAGS = \
+libseed_ffi_la_CFLAGS = \
-I top_srcdir@/libseed/ \
$(GOBJECT_INTROSPECTION_CFLAGS) \
$(SEED_DEBUG_CFLAGS) \
diff --git a/modules/ffi/seed-ffi.c b/modules/ffi/seed-ffi.c
index 28d86b0..b9744d7 100644
--- a/modules/ffi/seed-ffi.c
+++ b/modules/ffi/seed-ffi.c
@@ -41,6 +41,135 @@ typedef struct _seed_ffi_function_priv {
SeedObject module_obj;
} seed_ffi_function_priv;
+static ffi_type *
+gtype_to_ffi_type (SeedContext ctx,
+ SeedValue value,
+ GType otype,
+ GArgument *garg,
+ gpointer *arg,
+ SeedException *exception)
+{
+ ffi_type *return_type;
+ GType type = g_type_fundamental (otype);
+ g_assert (type != G_TYPE_INVALID);
+
+ switch (type)
+ {
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_CHAR:
+ case G_TYPE_INT:
+ return_type = &ffi_type_sint;
+ garg->v_int = seed_value_to_int (ctx, value, exception);
+ *arg = &(garg->v_int);
+ break;
+ case G_TYPE_UCHAR:
+ case G_TYPE_UINT:
+ return_type = &ffi_type_uint;
+ garg->v_uint = seed_value_to_uint (ctx, value, exception);
+ *arg = &(garg->v_uint);
+ break;
+ case G_TYPE_STRING:
+ return_type = &ffi_type_pointer;
+ garg->v_pointer = seed_value_to_string (ctx, value, exception);
+ *arg = &(garg->v_pointer);
+ break;
+ case G_TYPE_OBJECT:
+ // case G_TYPE_BOXED:
+ // case G_TYPE_POINTER:
+ return_type = &ffi_type_pointer;
+ garg->v_pointer = seed_value_to_object (ctx, value, exception);
+ *arg = &(garg->v_pointer);
+ break;
+ case G_TYPE_FLOAT:
+ return_type = &ffi_type_float;
+ garg->v_float = seed_value_to_float (ctx, value, exception);
+ *arg = &(garg->v_float);
+ break;
+ case G_TYPE_DOUBLE:
+ return_type = &ffi_type_double;
+ garg->v_double = seed_value_to_double (ctx, value, exception);
+ *arg = &(garg->v_double);
+ break;
+ case G_TYPE_LONG:
+ return_type = &ffi_type_slong;
+ garg->v_uint = seed_value_to_uint (ctx, value, exception);
+ *arg = &(garg->v_uint);
+ break;
+ case G_TYPE_ULONG:
+ return_type = &ffi_type_ulong;
+ garg->v_ulong = seed_value_to_ulong (ctx, value, exception);
+ *arg = &(garg->v_ulong);
+ break;
+ case G_TYPE_INT64:
+ return_type = &ffi_type_sint64;
+ garg->v_int64 = seed_value_to_int64 (ctx, value, exception);
+ *arg = &(garg->v_int64);
+ break;
+ case G_TYPE_UINT64:
+ return_type = &ffi_type_uint64;
+ garg->v_uint64 = seed_value_to_uint64 (ctx, value, exception);
+ *arg = &(garg->v_uint64);
+ break;
+ default:
+ g_warning ("Unsupported fundamental type: %s", g_type_name (type));
+ return_type = &ffi_type_pointer;
+ garg->v_pointer = NULL;
+ *arg = &(garg->v_pointer);
+ break;
+ }
+ return return_type;
+}
+
+static ffi_type *
+return_type_to_ffi_type (GType otype)
+{
+ GType type = g_type_fundamental (otype);
+ g_assert (type != G_TYPE_INVALID);
+
+ switch (type)
+ {
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_CHAR:
+ case G_TYPE_INT:
+ return &ffi_type_sint;
+ break;
+ case G_TYPE_UCHAR:
+ case G_TYPE_UINT:
+ return &ffi_type_uint;
+ break;
+ case G_TYPE_STRING:
+ return &ffi_type_pointer;
+ break;
+ case G_TYPE_OBJECT:
+ // case G_TYPE_BOXED:
+ // case G_TYPE_POINTER:
+ return &ffi_type_pointer;
+ break;
+ case G_TYPE_FLOAT:
+ return &ffi_type_float;
+ break;
+ case G_TYPE_DOUBLE:
+ return &ffi_type_double;
+ break;
+ case G_TYPE_LONG:
+ return &ffi_type_slong;
+ break;
+ case G_TYPE_ULONG:
+ return &ffi_type_ulong;
+ break;
+ case G_TYPE_INT64:
+ return &ffi_type_sint64;
+ break;
+ case G_TYPE_UINT64:
+ return &ffi_type_uint64;
+ break;
+ default:
+ g_warning ("Unsupported fundamental type: %s", g_type_name (type));
+ return &ffi_type_pointer;
+ break;
+ }
+}
+
static SeedValue
seed_ffi_get_signature (SeedContext ctx,
SeedObject this_object,
@@ -136,6 +265,8 @@ seed_ffi_function_finalize (SeedObject obj)
}
g_free (priv->name);
+ g_free (priv);
+
seed_value_unprotect (eng->context, priv->module_obj);
}
@@ -153,6 +284,62 @@ seed_ffi_make_function (SeedContext ctx, SeedObject module_obj, gpointer symbol,
}
static SeedValue
+value_from_ffi_type (SeedContext ctx,
+ GType otype,
+ gpointer *value,
+ SeedException *exception)
+{
+ switch (g_type_fundamental (otype))
+ {
+ case G_TYPE_INT:
+ return seed_value_from_int (ctx, *(gint*)value, exception);
+ break;
+ case G_TYPE_FLOAT:
+ return seed_value_from_float (ctx, *(gfloat*)value, exception);
+ break;
+ case G_TYPE_DOUBLE:
+ return seed_value_from_double (ctx, *(gdouble*)value, exception);
+ break;
+ case G_TYPE_BOOLEAN:
+ return seed_value_from_boolean (ctx, *(gboolean*)value, exception);
+ break;
+ case G_TYPE_STRING:
+ return seed_value_from_string (ctx, *(gchar**)value, exception);
+ break;
+ case G_TYPE_CHAR:
+ return seed_value_from_char (ctx, *(gchar*)value, exception);
+ break;
+ case G_TYPE_UCHAR:
+ return seed_value_from_uchar (ctx, *(guchar*)value, exception);
+ break;
+ case G_TYPE_UINT:
+ return seed_value_from_uint (ctx, *(guint*)value, exception);
+ break;
+ // case G_TYPE_POINTER:
+ // return seed_ (ctx, *(gpointer*)value, exception);
+ // break;
+ case G_TYPE_LONG:
+ return seed_value_from_long (ctx, *(glong*)value, exception);
+ break;
+ case G_TYPE_ULONG:
+ return seed_value_from_ulong (ctx, *(gulong*)value, exception);
+ break;
+ case G_TYPE_INT64:
+ return seed_value_from_int64 (ctx, *(gint64*)value, exception);
+ break;
+ case G_TYPE_UINT64:
+ return seed_value_from_uint64 (ctx, *(guint64*)value, exception);
+ break;
+ case G_TYPE_NONE:
+ return seed_make_null (ctx);
+ default:
+ g_warning ("Unsupported fundamental type: %s",
+ g_type_name(g_type_fundamental (otype)));
+ return seed_make_null (ctx);
+ }
+}
+
+static SeedValue
seed_ffi_function_call (SeedContext ctx,
SeedObject function,
SeedObject this_object,
@@ -160,15 +347,15 @@ seed_ffi_function_call (SeedContext ctx,
const SeedValue arguments[],
SeedException *exception)
{
+ GArgument *gargs;
ffi_type *rtype;
void *rvalue;
- int n_args;
ffi_type **atypes;
void **args;
int i;
ffi_cif cif;
- seed_ffi_function_priv *priv = seed_object_get_private (this_object);
+ seed_ffi_function_priv *priv = seed_object_get_private (function);
if (argument_count != priv->n_args)
{
@@ -176,6 +363,23 @@ seed_ffi_function_call (SeedContext ctx,
priv->name, priv->n_args, argument_count);
return seed_make_null (ctx);
}
+ atypes = g_alloca (sizeof (ffi_type *) * (argument_count+1));
+ args = g_alloca (sizeof (gpointer) * (argument_count+1));
+ gargs = g_alloca (sizeof (GArgument) * (argument_count+1));
+
+ for (i = 0; i < argument_count; i++)
+ {
+ atypes[i] = gtype_to_ffi_type (ctx, arguments[i], priv->args[i], &gargs[i], args[i],exception);
+ }
+ rtype = return_type_to_ffi_type (priv->ret_val);
+
+ ffi_prep_cif (&cif, FFI_DEFAULT_ABI, argument_count, rtype, atypes);
+
+ rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg)));
+
+ ffi_call (&cif, priv->symbol, rvalue, args);
+
+ return value_from_ffi_type (ctx, priv->ret_val, rvalue, exception);
}
static SeedValue
@@ -213,15 +417,18 @@ seed_ffi_construct_library (SeedContext ctx,
SeedObject ret;
gchar *filename;
- if (argument_count != 1)
+ if (argument_count != 1 && argument_count != 0)
{
seed_make_exception (ctx, exception,
"ArgumentError",
- "ffi.Library constructor expects 1 argument (filename), got %d",
+ "ffi.Library constructor expects 1 argument (filename, or none to use NULL GModule), got %d",
argument_count);
return seed_make_null (ctx);
}
- filename = seed_value_to_string (ctx, arguments[0], exception);
+ if (argument_count == 1)
+ filename = seed_value_to_string (ctx, arguments[0], exception);
+ else
+ filename = NULL;
mod = g_module_open (filename, G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY);
if (!mod)
@@ -229,11 +436,14 @@ seed_ffi_construct_library (SeedContext ctx,
seed_make_exception (ctx, exception, "GModuleError",
"Opening module (%s) failed with: %s",
filename, g_module_error ());
+ g_free (filename);
return seed_make_null (ctx);
}
ret = seed_make_object (ctx, ffi_library_class, mod);
+ g_free (filename);
+
return ret;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]