[seed: 5/7] ffi: Implement signature reading/building of internal representation for function signatures
- From: Robert Carr <racarr src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [seed: 5/7] ffi: Implement signature reading/building of internal representation for function signatures
- Date: Sun, 2 Aug 2009 01:28:58 +0000 (UTC)
commit 5681c3843e90c76b85dd69d43980c89a31cf7aae
Author: Robert Carr <racarr gnome org>
Date: Sat Aug 1 18:27:21 2009 -0400
ffi: Implement signature reading/building of internal representation for function signatures
modules/ffi/seed-ffi.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 134 insertions(+), 1 deletions(-)
---
diff --git a/modules/ffi/seed-ffi.c b/modules/ffi/seed-ffi.c
index 8772afc..adbaed0 100644
--- a/modules/ffi/seed-ffi.c
+++ b/modules/ffi/seed-ffi.c
@@ -24,6 +24,128 @@ SeedEngine *eng;
SeedObject namespace_ref;
SeedClass ffi_library_class;
+SeedClass ffi_function_class;
+
+typedef struct _seed_ffi_function_priv {
+ gpointer symbol;
+
+ GType *args;
+ gint n_args;
+
+ GType ret_val;
+
+ SeedObject signature_obj;
+ SeedObject module_obj;
+} seed_ffi_function_priv;
+
+static SeedValue
+seed_ffi_get_signature (SeedContext ctx,
+ SeedObject this_object,
+ SeedString property_name,
+ SeedException *exception)
+{
+ seed_ffi_function_priv *priv = seed_object_get_private (this_object);
+
+ if (priv->signature_obj)
+ return priv->signature_obj;
+ else
+ return seed_make_null (ctx);
+}
+
+static gboolean
+seed_ffi_build_signature (SeedContext ctx,
+ seed_ffi_function_priv *priv,
+ SeedObject sig,
+ SeedException *exception)
+{
+ SeedObject arguments;
+ SeedValue ret_type_ref, length_ref;
+ guint length, i;
+
+ arguments = seed_object_get_property (ctx, sig, "arguments");
+ ret_type_ref = seed_object_get_property (ctx, sig, "returns");
+
+ if (!seed_value_is_object (ctx, arguments))
+ {
+ seed_make_exception (ctx, exception, "FFIError",
+ "Signature arguments member must be an array describing argument types");
+ return FALSE;
+ }
+ length_ref = seed_object_get_property (ctx, arguments, "length");
+
+ length = seed_value_to_uint (ctx, length_ref, exception);
+ priv->n_args = length;
+ priv->args = g_slice_alloc (length * sizeof (GType));
+
+ for (i = 0; i < length; i++)
+ {
+ SeedValue type = seed_object_get_property_at_index (ctx, arguments,
+ i, exception);
+ priv->args[i] = seed_value_to_uint (ctx, type, exception);
+ }
+ priv->ret_val = seed_value_to_uint (ctx, ret_type_ref, exception);
+
+ priv->signature_obj = sig;
+ seed_value_protect (ctx, sig);
+
+ return TRUE;
+}
+
+static gboolean
+seed_ffi_set_signature (SeedContext ctx,
+ SeedObject this_object,
+ SeedString property_name,
+ SeedValue value,
+ SeedException *exception)
+{
+ seed_ffi_function_priv *priv = seed_object_get_private (this_object);
+
+ if (priv->signature_obj)
+ {
+ seed_make_exception (ctx, exception, "FFIError",
+ "Can not reset signature of function once set");
+ return FALSE;
+ }
+ else if (!seed_value_is_object (ctx, value))
+ {
+ seed_make_exception (ctx, exception, "FFIError",
+ "Signature must be an object");
+ return FALSE;
+ }
+ else
+ {
+ if (!seed_ffi_build_signature (ctx, priv, (SeedObject) value, exception))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+seed_ffi_function_finalize (SeedObject obj)
+{
+ seed_ffi_function_priv *priv = seed_object_get_private (obj);
+
+ if (priv->signature_obj)
+ {
+ seed_value_unprotect (eng->context, priv->signature_obj);
+
+ g_slice_free1 (priv->n_args * sizeof(GType), priv->args);
+ }
+
+ seed_value_unprotect (eng->context, priv->module_obj);
+}
+
+static SeedObject
+seed_ffi_make_function (SeedContext ctx, SeedObject module_obj, gpointer symbol)
+{
+ seed_ffi_function_priv *priv =
+ g_slice_alloc0 (sizeof (seed_ffi_function_priv));
+
+ priv->symbol = symbol;
+ priv->module_obj = module_obj;
+
+ return seed_make_object (ctx, ffi_function_class, priv);
+}
static SeedValue
seed_ffi_library_get_property (SeedContext ctx,
@@ -45,7 +167,7 @@ seed_ffi_library_get_property (SeedContext ctx,
{
return NULL;
}
- return seed_value_from_boolean (ctx, TRUE, exception);
+ return seed_ffi_make_function (ctx, this_object, symbol);
}
@@ -92,17 +214,28 @@ seed_ffi_library_finalize (SeedObject obj)
g_module_close (mod);
}
+seed_static_value ffi_function_values [] = {
+ {"signature", seed_ffi_get_signature, seed_ffi_set_signature, SEED_PROPERTY_ATTRIBUTE_DONT_DELETE},
+ {0, 0, 0, 0}
+};
+
SeedObject
seed_module_init(SeedEngine *local_eng)
{
SeedObject library_constructor;
seed_class_definition ffi_library_def = seed_empty_class;
+ seed_class_definition ffi_function_def = seed_empty_class;
ffi_library_def.class_name = "FFILibrary";
ffi_library_def.finalize = seed_ffi_library_finalize;
ffi_library_def.get_property = seed_ffi_library_get_property;
+ ffi_function_def.class_name = "FFIFunction";
+ ffi_function_def.finalize = seed_ffi_function_finalize;
+ ffi_function_def.static_values = ffi_function_values;
+
ffi_library_class = seed_create_class (&ffi_library_def);
+ ffi_function_class = seed_create_class (&ffi_function_def);
eng = local_eng;
namespace_ref = seed_make_object (eng->context, NULL, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]