[gjs] GI: Allow creating boxed wrapper without copy



commit 1de7be955cb1672dd30d03e384c68225e64d70f5
Author: Johan Bilien <jobi litl com>
Date:   Tue Mar 24 15:08:39 2009 +0000

    GI: Allow creating boxed wrapper without copy
---
 gi/arg.c   |    2 +-
 gi/boxed.c |   22 +++++++++++++++++-----
 gi/boxed.h |    3 ++-
 gi/value.c |    2 +-
 4 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/gi/arg.c b/gi/arg.c
index 13c3441..24c525a 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -933,7 +933,7 @@ gjs_value_from_g_argument (JSContext  *context,
 
             if (symbol_type == GI_INFO_TYPE_STRUCT || symbol_type == GI_INFO_TYPE_BOXED) {
                 JSObject *obj;
-                obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)symbol_info, arg->v_pointer);
+                obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)symbol_info, arg->v_pointer, FALSE);
                 if (obj)
                     value = OBJECT_TO_JSVAL(obj);
 
diff --git a/gi/boxed.c b/gi/boxed.c
index c24f366..9304723 100644
--- a/gi/boxed.c
+++ b/gi/boxed.c
@@ -43,13 +43,15 @@ typedef struct {
     void *gboxed; /* NULL if we are the prototype and not an instance */
     guint can_allocate_directly : 1;
     guint allocated_directly : 1;
-    guint has_parent : 1; /* If set, this boxed doesn't have an independent allocation */
+    guint not_owning_gboxed : 1; /* if set, the JS wrapper does not own
+                                    the reference to the C gboxed */
 } Boxed;
 
 typedef struct {
     GIBoxedInfo *info;
     void *gboxed;
     jsval parent_jsval;
+    gboolean no_copy;
 } BoxedConstructInfo;
 
 static gboolean struct_is_simple(GIStructInfo *info);
@@ -59,7 +61,7 @@ static JSBool boxed_set_field_from_value(JSContext   *context,
                                          GIFieldInfo *field_info,
                                          jsval        value);
 
-static BoxedConstructInfo unthreadsafe_template_for_constructor = { NULL, NULL, JSVAL_NULL };
+static BoxedConstructInfo unthreadsafe_template_for_constructor = { NULL, NULL, JSVAL_NULL, FALSE };
 
 static struct JSClass gjs_boxed_class;
 
@@ -506,7 +508,7 @@ boxed_constructor(JSContext *context,
             /* A structure nested inside a parent object; doens't have an independent allocation */
 
             priv->gboxed = unthreadsafe_template_for_constructor.gboxed;
-            priv->has_parent = TRUE;
+            priv->not_owning_gboxed = TRUE;
 
             /* We never actually read the reserved slot, but we put the parent object
              * into it to hold onto the parent object.
@@ -516,6 +518,14 @@ boxed_constructor(JSContext *context,
 
             unthreadsafe_template_for_constructor.parent_jsval = JSVAL_NULL;
             unthreadsafe_template_for_constructor.gboxed = NULL;
+        } else if (unthreadsafe_template_for_constructor.no_copy) {
+            /* we need to create a JS Boxed which references the
+             * original C struct, not a copy of it. Used for
+             * G_SIGNAL_TYPE_STATIC_SCOPE
+             */
+            priv->gboxed = unthreadsafe_template_for_constructor.gboxed;
+            priv->not_owning_gboxed = TRUE;
+            unthreadsafe_template_for_constructor.gboxed = NULL;
         } else {
             GType gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
 
@@ -556,7 +566,7 @@ boxed_finalize(JSContext *context,
     if (priv == NULL)
         return; /* wrong class? */
 
-    if (priv->gboxed && !priv->has_parent) {
+    if (priv->gboxed && !priv->not_owning_gboxed) {
         if (priv->allocated_directly) {
             g_slice_free1(g_struct_info_get_size (priv->info), priv->gboxed);
         } else {
@@ -1212,7 +1222,8 @@ gjs_define_boxed_class(JSContext    *context,
 JSObject*
 gjs_boxed_from_c_struct(JSContext    *context,
                         GIStructInfo *info,
-                        void         *gboxed)
+                        void         *gboxed,
+                        gboolean      no_copy)
 {
     JSObject *proto;
 
@@ -1229,6 +1240,7 @@ gjs_boxed_from_c_struct(JSContext    *context,
     unthreadsafe_template_for_constructor.info = info;
     unthreadsafe_template_for_constructor.gboxed = gboxed;
     unthreadsafe_template_for_constructor.parent_jsval = JSVAL_NULL;
+    unthreadsafe_template_for_constructor.no_copy = no_copy;
 
     return gjs_construct_object_dynamic(context, proto,
                                         0, NULL);
diff --git a/gi/boxed.h b/gi/boxed.h
index b5c68dd..1f81b03 100644
--- a/gi/boxed.h
+++ b/gi/boxed.h
@@ -50,7 +50,8 @@ void*     gjs_c_struct_from_boxed      (JSContext    *context,
                                         JSObject     *obj);
 JSObject* gjs_boxed_from_c_struct      (JSContext    *context,
                                         GIStructInfo *info,
-                                        void         *gboxed);
+                                        void         *gboxed,
+                                        gboolean      no_copy);
 
 G_END_DECLS
 
diff --git a/gi/value.c b/gi/value.c
index ce81c14..d7f6499 100644
--- a/gi/value.c
+++ b/gi/value.c
@@ -510,7 +510,7 @@ gjs_value_from_g_value(JSContext    *context,
         switch (g_base_info_get_type(info)) {
         case GI_INFO_TYPE_BOXED:
         case GI_INFO_TYPE_STRUCT:
-            obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)info, gboxed);
+            obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)info, gboxed, FALSE);
             break;
         case GI_INFO_TYPE_UNION:
             obj = gjs_union_from_c_union(context, (GIUnionInfo *)info, gboxed);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]