[gjs] Don't copy boxed or struct types when passing them to a vfunc or callback



commit 8cd5e7bd9ec37edbf1bd45591e59627ee69c7204
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Feb 3 16:17:42 2012 -0500

    Don't copy boxed or struct types when passing them to a vfunc or callback
    
    At times, we do not want to copy boxed or struct types when passing them
    around - if we pass them to a virtual function or callback, the caller might
    be expecting that we modify the structure.

 gi/arg.c      |   35 ++++++++++++++++++++++++++---------
 gi/arg.h      |    3 ++-
 gi/boxed.c    |    3 ++-
 gi/function.c |   15 ++++++++++-----
 gi/param.c    |    2 +-
 gi/repo.c     |    2 +-
 gi/value.c    |    2 +-
 7 files changed, 43 insertions(+), 19 deletions(-)
---
diff --git a/gi/arg.c b/gi/arg.c
index 223f610..94f7128 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -1859,7 +1859,8 @@ gjs_array_from_g_list (JSContext  *context,
             arg.v_pointer = list->data;
 
             if (!gjs_value_from_g_argument(context, &elem,
-                                           param_info, &arg))
+                                           param_info, &arg,
+                                           TRUE))
                 goto out;
 
             if (!JS_DefineElement(context, obj,
@@ -1874,7 +1875,8 @@ gjs_array_from_g_list (JSContext  *context,
             arg.v_pointer = slist->data;
 
             if (!gjs_value_from_g_argument(context, &elem,
-                                           param_info, &arg))
+                                           param_info, &arg,
+                                           TRUE))
                 goto out;
 
             if (!JS_DefineElement(context, obj,
@@ -1939,7 +1941,7 @@ gjs_array_from_carray_internal (JSContext  *context,
 #define ITERATE(type) \
     for (i = 0; i < length; i++) { \
         arg.v_##type = *(((g##type*)array) + i);                         \
-        if (!gjs_value_from_g_argument(context, &elem, param_info, &arg)) \
+        if (!gjs_value_from_g_argument(context, &elem, param_info, &arg, TRUE)) \
           goto finally; \
         if (!JS_DefineElement(context, obj, i, elem, NULL, NULL, \
               JSPROP_ENUMERATE)) \
@@ -2119,7 +2121,7 @@ gjs_array_from_zero_terminated_c_array (JSContext  *context,
         g##type *array = c_array; \
         for (i = 0; array[i]; i++) { \
             arg.v_##type = array[i]; \
-            if (!gjs_value_from_g_argument(context, &elem, param_info, &arg)) \
+            if (!gjs_value_from_g_argument(context, &elem, param_info, &arg, TRUE)) \
                 goto finally; \
             if (!JS_DefineElement(context, obj, i, elem, NULL, NULL, \
                                   JSPROP_ENUMERATE)) \
@@ -2227,7 +2229,8 @@ gjs_object_from_g_hash (JSContext  *context,
     while (g_hash_table_iter_next
            (&iter, &keyarg.v_pointer, &valarg.v_pointer)) {
         if (!gjs_value_from_g_argument(context, &keyjs,
-                                       key_param_info, &keyarg))
+                                       key_param_info, &keyarg,
+                                       TRUE))
             goto out;
 
         keystr = JS_ValueToString(context, keyjs);
@@ -2238,7 +2241,8 @@ gjs_object_from_g_hash (JSContext  *context,
             goto out;
 
         if (!gjs_value_from_g_argument(context, &valjs,
-                                       val_param_info, &valarg))
+                                       val_param_info, &valarg,
+                                       TRUE))
             goto out;
 
         if (!JS_DefineProperty(context, obj, keyutf8, valjs,
@@ -2265,7 +2269,8 @@ JSBool
 gjs_value_from_g_argument (JSContext  *context,
                            jsval      *value_p,
                            GITypeInfo *type_info,
-                           GArgument  *arg)
+                           GArgument  *arg,
+                           gboolean    copy_structs)
 {
     GITypeTag type_tag;
 
@@ -2431,8 +2436,20 @@ gjs_value_from_g_argument (JSContext  *context,
 
             if (interface_type == GI_INFO_TYPE_STRUCT || interface_type == GI_INFO_TYPE_BOXED) {
                 JSObject *obj;
-                obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)interface_info, arg->v_pointer,
-                                              GJS_BOXED_CREATION_NONE);
+                GjsBoxedCreationFlags flags;
+
+                if (copy_structs)
+                    flags = GJS_BOXED_CREATION_NONE;
+                else if (g_type_is_a(gtype, G_TYPE_VARIANT))
+                    flags = GJS_BOXED_CREATION_NONE;
+                else
+                    flags = GJS_BOXED_CREATION_NO_COPY;
+
+                obj = gjs_boxed_from_c_struct(context,
+                                              (GIStructInfo *)interface_info,
+                                              arg->v_pointer,
+                                              flags);
+
                 if (obj)
                     value = OBJECT_TO_JSVAL(obj);
 
diff --git a/gi/arg.h b/gi/arg.h
index 45fa604..f89a748 100644
--- a/gi/arg.h
+++ b/gi/arg.h
@@ -69,7 +69,8 @@ JSBool gjs_value_to_g_argument (JSContext      *context,
 JSBool gjs_value_from_g_argument (JSContext  *context,
                                   jsval      *value_p,
                                   GITypeInfo *type_info,
-                                  GArgument  *arg);
+                                  GArgument  *arg,
+                                  gboolean    copy_structs);
 JSBool gjs_value_from_explicit_array (JSContext  *context,
                                       jsval      *value_p,
                                       GITypeInfo *type_info,
diff --git a/gi/boxed.c b/gi/boxed.c
index ef80395..c9b5e84 100644
--- a/gi/boxed.c
+++ b/gi/boxed.c
@@ -667,7 +667,8 @@ boxed_field_getter (JSContext *context,
 
     if (!gjs_value_from_g_argument (context, value,
                                     type_info,
-                                    &arg))
+                                    &arg,
+                                    TRUE))
         goto out;
 
     success = TRUE;
diff --git a/gi/function.c b/gi/function.c
index 9fecf86..05b4416 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -250,7 +250,8 @@ gjs_callback_closure(ffi_cif *cif,
         if (!gjs_value_from_g_argument(context,
                                        &jsargs[n_jsargs++],
                                        &type_info,
-                                       args[i]))
+                                       args[i],
+                                       FALSE))
             goto out;
     }
 
@@ -837,7 +838,8 @@ gjs_invoke_c_function(JSContext      *context,
                 array_length_pos += is_method ? 1 : 0;
                 arg_failed = !gjs_value_from_g_argument(context, &length,
                                                         &arg_type_info,
-                                                        &out_arg_cvalues[array_length_pos]);
+                                                        &out_arg_cvalues[array_length_pos],
+                                                        TRUE);
                 if (!arg_failed) {
                     arg_failed = !gjs_value_from_explicit_array(context,
                                                                 &return_values[next_rval],
@@ -854,7 +856,8 @@ gjs_invoke_c_function(JSContext      *context,
                     failed = TRUE;
             } else {
                 arg_failed = !gjs_value_from_g_argument(context, &return_values[next_rval],
-                                                        &return_info, &return_gargument);
+                                                        &return_info, &return_gargument,
+                                                        TRUE);
                 /* Free GArgument, the jsval should have ref'd or copied it */
                 if (!arg_failed &&
                     !gjs_g_argument_release(context,
@@ -974,7 +977,8 @@ release:
                 array_length_pos += is_method ? 1 : 0;
                 arg_failed = !gjs_value_from_g_argument(context, &array_length,
                                                         &array_length_type_info,
-                                                        &out_arg_cvalues[array_length_pos]);
+                                                        &out_arg_cvalues[array_length_pos],
+                                                        TRUE);
                 if (!arg_failed) {
                     arg_failed = !gjs_value_from_explicit_array(context,
                                                                 &return_values[next_rval],
@@ -986,7 +990,8 @@ release:
                 arg_failed = !gjs_value_from_g_argument(context,
                                                         &return_values[next_rval],
                                                         &arg_type_info,
-                                                        arg);
+                                                        arg,
+                                                        TRUE);
             }
 
             if (arg_failed)
diff --git a/gi/param.c b/gi/param.c
index b1f1c05..2e2c201 100644
--- a/gi/param.c
+++ b/gi/param.c
@@ -131,7 +131,7 @@ param_get_prop(JSContext *context,
         goto out;
     }
 
-    if (!gjs_value_from_g_argument(context, value_p, type_info, &arg))
+    if (!gjs_value_from_g_argument(context, value_p, type_info, &arg, TRUE))
         goto out;
 
     success = JS_TRUE;
diff --git a/gi/repo.c b/gi/repo.c
index 08a6d4a..9d2d601 100644
--- a/gi/repo.c
+++ b/gi/repo.c
@@ -365,7 +365,7 @@ gjs_define_constant(JSContext      *context,
     type_info = g_constant_info_get_type(info);
     g_constant_info_get_value(info, &garg);
 
-    if (!gjs_value_from_g_argument(context, &value, type_info, &garg))
+    if (!gjs_value_from_g_argument(context, &value, type_info, &garg, TRUE))
         goto out;
 
     name = g_base_info_get_name((GIBaseInfo*) info);
diff --git a/gi/value.c b/gi/value.c
index 6e86493..3439132 100644
--- a/gi/value.c
+++ b/gi/value.c
@@ -719,7 +719,7 @@ gjs_value_from_g_value_internal(JSContext    *context,
 
         arg.v_pointer = g_value_get_pointer(gvalue);
 
-        res = gjs_value_from_g_argument(context, value_p, &type_info, &arg);
+        res = gjs_value_from_g_argument(context, value_p, &type_info, &arg, TRUE);
 
         g_base_info_unref((GIBaseInfo*)arg_info);
         g_base_info_unref((GIBaseInfo*)signal_info);



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