[seed] [ffi] Add support for pointer types to FFI. Also avoid recreating FFIFunction objects and cache them
- From: Robert Carr <racarr src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [seed] [ffi] Add support for pointer types to FFI. Also avoid recreating FFIFunction objects and cache them
- Date: Mon, 3 Aug 2009 01:21:10 +0000 (UTC)
commit f3e1f631102409a8cdc5c31652a854347a3a6587
Author: Robert Carr <racarr gnome org>
Date: Sun Aug 2 21:20:02 2009 -0400
[ffi] Add support for pointer types to FFI. Also avoid recreating FFIFunction objects and cache them in a GHashTable in the new seed_ffi_library_priv struct.
modules/ffi/seed-ffi.c | 51 ++++++++++++++++++++++++++++++++-----------
modules/ffi/test-strdup.js | 12 ++++++++++
modules/ffi/test-xlib.js | 24 ++++++++++++++++++++
3 files changed, 74 insertions(+), 13 deletions(-)
---
diff --git a/modules/ffi/seed-ffi.c b/modules/ffi/seed-ffi.c
index ef98446..854df44 100644
--- a/modules/ffi/seed-ffi.c
+++ b/modules/ffi/seed-ffi.c
@@ -41,6 +41,11 @@ typedef struct _seed_ffi_function_priv {
SeedObject module_obj;
} seed_ffi_function_priv;
+typedef struct _seed_ffi_library_priv {
+ GModule *mod;
+ GHashTable *symbols;
+} seed_ffi_library_priv;
+
static ffi_type *
gtype_to_ffi_type (SeedContext ctx,
SeedValue value,
@@ -75,9 +80,9 @@ gtype_to_ffi_type (SeedContext ctx,
break;
case G_TYPE_OBJECT:
// case G_TYPE_BOXED:
- // case G_TYPE_POINTER:
+ case G_TYPE_POINTER:
return_type = &ffi_type_pointer;
- garg->v_pointer = seed_value_to_object (ctx, value, exception);
+ garg->v_pointer = seed_pointer_get_pointer (ctx, value);
*arg = (gpointer)garg;
break;
case G_TYPE_FLOAT:
@@ -142,7 +147,7 @@ return_type_to_ffi_type (GType otype)
break;
case G_TYPE_OBJECT:
// case G_TYPE_BOXED:
- // case G_TYPE_POINTER:
+ case G_TYPE_POINTER:
return &ffi_type_pointer;
break;
case G_TYPE_FLOAT:
@@ -271,8 +276,9 @@ seed_ffi_function_finalize (SeedObject obj)
}
static SeedObject
-seed_ffi_make_function (SeedContext ctx, SeedObject module_obj, gpointer symbol, const gchar *name)
+seed_ffi_make_function (SeedContext ctx, SeedObject module_obj, gpointer symbol, const gchar *name, GHashTable *symbols)
{
+ SeedValue ret;
seed_ffi_function_priv *priv =
g_slice_alloc0 (sizeof (seed_ffi_function_priv));
@@ -280,7 +286,11 @@ seed_ffi_make_function (SeedContext ctx, SeedObject module_obj, gpointer symbol,
priv->module_obj = module_obj;
priv->name = g_strdup (name);
- return seed_make_object (ctx, ffi_function_class, priv);
+ ret = seed_make_object (ctx, ffi_function_class, priv);
+ seed_value_protect (ctx, ret);
+
+ g_hash_table_insert (symbols, g_strdup (name), ret);
+ return ret;
}
static SeedValue
@@ -315,9 +325,9 @@ value_from_ffi_type (SeedContext ctx,
case G_TYPE_UINT:
return seed_value_from_uint (ctx, value->v_uint, exception);
break;
- // case G_TYPE_POINTER:
- // return seed_ (ctx, *(gpointer*)value, exception);
- // break;
+ case G_TYPE_POINTER:
+ return seed_make_pointer (ctx, value->v_pointer);
+ break;
case G_TYPE_LONG:
return seed_value_from_long (ctx, value->v_long, exception);
break;
@@ -387,21 +397,27 @@ seed_ffi_library_get_property (SeedContext ctx,
SeedString property_name,
SeedException *exception)
{
+ SeedValue ret;
GModule *mod;
gchar *prop;
gsize len = seed_string_get_maximum_size (property_name);
gpointer symbol;
+ seed_ffi_library_priv *priv;
prop = g_alloca (len);
seed_string_to_utf8_buffer (property_name, prop, len);
- mod = seed_object_get_private (this_object);
+ priv = seed_object_get_private (this_object);
+ mod = priv->mod;
+ if ((ret = g_hash_table_lookup (priv->symbols, prop)))
+ return ret;
+
if (!g_module_symbol (mod, prop, &symbol))
{
return NULL;
}
- return seed_ffi_make_function (ctx, this_object, symbol, prop);
+ return seed_ffi_make_function (ctx, this_object, symbol, prop, priv->symbols);
}
@@ -415,6 +431,7 @@ seed_ffi_construct_library (SeedContext ctx,
GModule *mod;
SeedObject ret;
gchar *filename;
+ seed_ffi_library_priv *priv;
if (argument_count != 1 && argument_count != 0)
{
@@ -439,7 +456,14 @@ seed_ffi_construct_library (SeedContext ctx,
return seed_make_null (ctx);
}
- ret = seed_make_object (ctx, ffi_library_class, mod);
+ priv = g_slice_alloc (sizeof (seed_ffi_library_priv));
+ priv->mod = mod;
+
+ // TODO: Value destroy function.
+ priv->symbols = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ ret = seed_make_object (ctx, ffi_library_class, priv);
g_free (filename);
@@ -449,9 +473,10 @@ seed_ffi_construct_library (SeedContext ctx,
static void
seed_ffi_library_finalize (SeedObject obj)
{
- GModule *mod = seed_object_get_private (obj);
+ seed_ffi_library_priv *priv;
+ priv = seed_object_get_private (obj);
- g_module_close (mod);
+ g_module_close (priv->mod);
}
seed_static_value ffi_function_values [] = {
diff --git a/modules/ffi/test-strdup.js b/modules/ffi/test-strdup.js
new file mode 100755
index 0000000..1c9ced1
--- /dev/null
+++ b/modules/ffi/test-strdup.js
@@ -0,0 +1,12 @@
+#!/usr/bin/env seed
+GObject = imports.gi.GObject;
+ffi = imports.ffi;
+
+var app = new ffi.Library();
+var strdup = app.strdup;
+
+strdup.signature = {arguments: [GObject.TYPE_STRING],
+ returns: GObject.TYPE_STRING};
+
+print(strdup("Hi"));
+
diff --git a/modules/ffi/test-xlib.js b/modules/ffi/test-xlib.js
new file mode 100755
index 0000000..20f17b9
--- /dev/null
+++ b/modules/ffi/test-xlib.js
@@ -0,0 +1,24 @@
+#!/usr/bin/env seed
+GObject = imports.gi.GObject;
+ffi = imports.ffi;
+
+signatures = {
+ "XOpenDisplay": {arguments: [GObject.TYPE_STRING],
+ returns: GObject.TYPE_POINTER},
+ "XDefaultScreen": {arguments: [GObject.TYPE_POINTER],
+ returns: GObject.TYPE_INT}
+};
+
+var XLib = new ffi.Library("/usr/lib/libX11.so");
+
+var XOpenDisplay = XLib.XOpenDisplay;
+var XDefaultScreen = XLib.XDefaultScreen;
+
+for (var i in signatures){
+ XLib[i].signature = signatures[i];
+}
+
+display = XOpenDisplay(":0.0");
+print(display);
+
+print(XDefaultScreen(display));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]