[seed] Reimplement class_init closures without using FFI.
- From: Robert Carr <racarr src gnome org>
- To: svn-commits-list gnome org
- Subject: [seed] Reimplement class_init closures without using FFI.
- Date: Thu, 23 Apr 2009 01:54:56 -0400 (EDT)
commit 3b3374ad0b2abdb9d14a8f7ffba3d0297eb014c9
Author: Robert Carr <racarr svn gnome org>
Date: Thu Apr 23 01:54:12 2009 -0400
Reimplement class_init closures without using FFI.
---
libseed/seed-gtype.c | 160 ++++++++++++++++++++++---------------------------
1 files changed, 72 insertions(+), 88 deletions(-)
diff --git a/libseed/seed-gtype.c b/libseed/seed-gtype.c
index ddb67cb..8ee54f6 100644
--- a/libseed/seed-gtype.c
+++ b/libseed/seed-gtype.c
@@ -28,6 +28,12 @@ GQuark qgetter;
GQuark qsetter;
GQuark qiinit;
+GQuark qcinit;
+
+typedef struct _SeedGClassPrivates {
+ JSObjectRef constructor;
+ JSObjectRef func;
+} SeedGClassPrivates;
static JSValueRef
seed_property_method_invoked (JSContextRef ctx,
@@ -288,84 +294,6 @@ seed_attach_methods_to_class_object (JSContextRef ctx,
static void
-seed_handle_class_init_closure (ffi_cif * cif,
- void *result,
- void **args,
- void *userdata)
-{
- JSObjectRef function = (JSObjectRef) userdata;
- JSValueRef jsargs[2];
- GType type;
- JSValueRef exception = 0;
- JSContextRef ctx = JSGlobalContextCreateInGroup (context_group,
- 0);
- GObjectClass *klass = *(GObjectClass **) args[0];
- GIBaseInfo *class_info;
-
- seed_prepare_global_context (ctx);
-
- klass->get_property = seed_gtype_get_property;
- klass->set_property = seed_gtype_set_property;
-
- type = (GType) JSObjectGetPrivate (*(JSObjectRef *) args[1]);
-
- class_info = seed_get_class_info_for_type (type);
-
- jsargs[0] = seed_make_struct (ctx, *(gpointer *) args[0], class_info);
- jsargs[1] = seed_gobject_get_prototype_for_gtype (type);
-
- seed_attach_methods_to_class_object (ctx, (JSObjectRef)jsargs[0],
- &exception);
-
- g_base_info_unref ((GIBaseInfo *) class_info);
-
- SEED_NOTE (GTYPE, "Marshalling class init closure for type: %s",
- g_type_name (type));
-
- // TODO:
- // Should probably have a custom type for class, and have it auto convert.
- seed_object_set_property (ctx, (JSObjectRef) jsargs[0],
- "type", seed_value_from_int (ctx, type, 0));
- seed_object_set_property (ctx, (JSObjectRef) jsargs[0],
- "property_count", seed_value_from_int (ctx, 1,
- 0));
-
- JSObjectCallAsFunction (ctx, function, 0, 2, jsargs, &exception);
- if (exception)
- {
- gchar *mes = seed_exception_to_string (ctx, exception);
- g_warning ("Exception in class init closure. %s \n", mes);
- }
-
- JSGlobalContextRelease ((JSGlobalContextRef) ctx);
-}
-
-
-static ffi_closure *
-seed_make_class_init_closure (JSObjectRef function)
-{
- ffi_cif *cif;
- ffi_closure *closure;
- ffi_type **arg_types;
-
- // Might need to protect function.
-
- cif = g_new0 (ffi_cif, 1);
- arg_types = g_new0 (ffi_type *, 3);
-
- arg_types[0] = &ffi_type_pointer;
- arg_types[1] = &ffi_type_uint;
- arg_types[2] = 0;
-
- closure = mmap (0, sizeof (ffi_closure), PROT_READ | PROT_WRITE |
- PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
-
- ffi_prep_cif (cif, FFI_DEFAULT_ABI, 2, &ffi_type_void, arg_types);
- ffi_prep_closure (closure, cif, seed_handle_class_init_closure, function);
- return closure;
-}
-
-static void
seed_gtype_instance_init (GTypeInstance *instance,
gpointer g_class)
{
@@ -400,6 +328,54 @@ seed_gtype_instance_init (GTypeInstance *instance,
JSGlobalContextRelease ((JSGlobalContextRef) ctx);
}
+static void
+seed_gtype_class_init (gpointer g_class,
+ gpointer class_data)
+{
+ SeedGClassPrivates *priv;
+ GIBaseInfo *class_info;
+ JSContextRef ctx;
+ JSValueRef jsargs[2];
+ GType type;
+ JSValueRef exception = 0;
+
+ priv = (SeedGClassPrivates *)class_data;
+
+ ctx = JSGlobalContextCreateInGroup (context_group, 0);
+ seed_prepare_global_context (ctx);
+
+ ((GObjectClass *)g_class)->get_property = seed_gtype_get_property;
+ ((GObjectClass *)g_class)->set_property = seed_gtype_set_property;
+
+ type = (GType) JSObjectGetPrivate (priv->constructor);
+ class_info = seed_get_class_info_for_type (type);
+
+ jsargs[0] = seed_make_struct (ctx, g_class, class_info);
+ jsargs[1] = seed_gobject_get_prototype_for_gtype (type);
+
+ seed_attach_methods_to_class_object (ctx, (JSObjectRef) jsargs[0], &exception);
+
+ g_base_info_unref ((GIBaseInfo *) class_info);
+
+ SEED_NOTE (GTYPE, "Marshalling class init for type: %s",
+ g_type_name (type));
+
+ seed_object_set_property (ctx, (JSObjectRef) jsargs[0],
+ "type", seed_value_from_int (ctx, type, 0));
+ seed_object_set_property (ctx, (JSObjectRef) jsargs[0],
+ "property_count", seed_value_from_int (ctx, 1,
+ 0));
+
+ JSObjectCallAsFunction (ctx, priv->func, 0, 2, jsargs, &exception);
+ if (exception)
+ {
+ gchar *mes = seed_exception_to_string (ctx, exception);
+ g_warning ("Exception in class init closure. %s \n", mes);
+ }
+
+ JSGlobalContextRelease ((JSGlobalContextRef) ctx);
+}
+
static JSObjectRef
seed_gtype_constructor_invoked (JSContextRef ctx,
JSObjectRef constructor,
@@ -421,9 +397,9 @@ seed_gtype_constructor_invoked (JSContextRef ctx,
0,
NULL
};
- ffi_closure *init_closure = 0;
GTypeQuery query;
JSObjectRef constructor_ref;
+ SeedGClassPrivates *priv;
if (argumentCount != 1)
{
@@ -459,13 +435,7 @@ seed_gtype_constructor_invoked (JSContextRef ctx,
return (JSObjectRef) JSValueMakeNull (ctx);
}
- if (!JSValueIsNull (ctx, class_init) &&
- JSValueIsObject (ctx, class_init) &&
- JSObjectIsFunction (ctx, (JSObjectRef) class_init))
- {
- init_closure = seed_make_class_init_closure ((JSObjectRef) class_init);
- JSValueProtect (ctx, class_init);
- }
+
parent_type = (GType) seed_value_to_int (ctx, parent_ref, exception);
@@ -475,14 +445,27 @@ seed_gtype_constructor_invoked (JSContextRef ctx,
g_type_query (parent_type, &query);
type_info.class_size = query.class_size;
type_info.instance_size = query.instance_size;
- type_info.class_init = (GClassInitFunc) init_closure;
+ type_info.class_init = seed_gtype_class_init;
type_info.instance_init = seed_gtype_instance_init;
+
+ priv = g_slice_alloc (sizeof (SeedGClassPrivates));
+
+ if (!JSValueIsNull (ctx, class_init) &&
+ JSValueIsObject (ctx, class_init) &&
+ JSObjectIsFunction (ctx, (JSObjectRef) class_init))
+ {
+ priv->func = (gpointer) class_init;
+ JSValueProtect (ctx, class_init);
+ }
+
constructor_ref = JSObjectMake (ctx, gobject_constructor_class,
(gpointer) 0);
JSValueProtect (ctx, constructor_ref);
- type_info.class_data = constructor_ref;
+ priv->constructor = constructor_ref;
+
+ type_info.class_data = priv;
new_type = g_type_register_static (parent_type, new_name, &type_info, 0);
seed_gobject_get_class_for_gtype (ctx, new_type);
@@ -607,6 +590,7 @@ seed_gtype_init (SeedEngine * local_eng)
qgetter = g_quark_from_static_string ("js-getter");
qsetter = g_quark_from_static_string ("js-setter");
qiinit = g_quark_from_static_string("js-instance-init");
+ qcinit = g_quark_from_static_string("js-class-init");
seed_define_gtype_functions (local_eng->context);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]