[template-glib] gi: improve transfer ownership for allocated types



commit ffa28a904df726f791b3b63497d2da7e0473ef5b
Author: Christian Hergert <chergert redhat com>
Date:   Wed Oct 25 00:08:02 2017 -0700

    gi: improve transfer ownership for allocated types
    
    This improves things a bit so we are less leaky. However, all of
    this really needs a clean implementation that tracks ownership
    for things like GList and friends wrt to transfer full with
    element values.

 src/tmpl-expr-eval.c  |    4 ++--
 src/tmpl-gi-private.h |    4 ++++
 src/tmpl-gi.c         |   20 +++++++++++++-------
 3 files changed, 19 insertions(+), 9 deletions(-)
---
diff --git a/src/tmpl-expr-eval.c b/src/tmpl-expr-eval.c
index 815a698..6c1502b 100644
--- a/src/tmpl-expr-eval.c
+++ b/src/tmpl-expr-eval.c
@@ -917,7 +917,7 @@ apply_args:
 
   for (i = 0; i < n_args; i++)
     {
-      GIArgInfo *arg_info = g_callable_info_get_arg ((GICallableInfo *)function, i);
+      g_autoptr(GIArgInfo) arg_info = g_callable_info_get_arg ((GICallableInfo *)function, i);
       GIArgument *arg = &g_array_index (in_args, GIArgument, i + 1);
       GValue *value = &g_array_index (values, GValue, i);
       GITypeInfo type_info = { 0 };
@@ -958,7 +958,7 @@ apply_args:
 
       g_arg_info_load_type (arg_info, &type_info);
 
-      if (!tmpl_gi_argument_from_g_value (value, &type_info, arg, error))
+      if (!tmpl_gi_argument_from_g_value (value, &type_info, arg_info, arg, error))
         goto cleanup;
     }
 
diff --git a/src/tmpl-gi-private.h b/src/tmpl-gi-private.h
index 02c95ee..ed73d17 100644
--- a/src/tmpl-gi-private.h
+++ b/src/tmpl-gi-private.h
@@ -28,6 +28,7 @@ GType    tmpl_typelib_get_type         (void);
 GType    tmpl_base_info_get_type       (void);
 gboolean tmpl_gi_argument_from_g_value (const GValue  *value,
                                         GITypeInfo    *type_info,
+                                        GIArgInfo     *arg_info,
                                         GIArgument    *arg,
                                         GError       **error);
 gboolean tmpl_gi_argument_to_g_value   (GValue        *value,
@@ -36,6 +37,9 @@ gboolean tmpl_gi_argument_to_g_value   (GValue        *value,
                                         GITransfer     xfer,
                                         GError       **error);
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GIBaseInfo, g_base_info_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GIArgInfo, g_base_info_unref)
+
 G_END_DECLS
 
 #endif /* TMPL_GI_PRIVATE_H */
diff --git a/src/tmpl-gi.c b/src/tmpl-gi.c
index 2a94f05..709e49e 100644
--- a/src/tmpl-gi.c
+++ b/src/tmpl-gi.c
@@ -26,7 +26,6 @@ typedef struct GIBaseInfo TmplBaseInfo;
 G_DEFINE_BOXED_TYPE (TmplBaseInfo, tmpl_base_info,
                      (GBoxedCopyFunc)g_base_info_ref,
                      (GBoxedFreeFunc)g_base_info_unref)
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (GIBaseInfo, g_base_info_unref)
 
 #define return_type_mismatch(value, type)                          \
   G_STMT_START {                                                   \
@@ -69,10 +68,12 @@ find_enum_value (GIEnumInfo  *info,
 gboolean
 tmpl_gi_argument_from_g_value (const GValue  *value,
                                GITypeInfo    *type_info,
+                               GIArgInfo     *arg_info,
                                GIArgument    *arg,
                                GError       **error)
 {
   GITypeTag type_tag = g_type_info_get_tag (type_info);
+  GITransfer xfer = g_arg_info_get_ownership_transfer (arg_info);
 
   /* For the long handling: long can be equivalent to
    * int32 or int64, depending on the architecture, but
@@ -182,7 +183,12 @@ tmpl_gi_argument_from_g_value (const GValue  *value,
       /* Callers are responsible for ensuring the GValue stays alive
        * long enough for the string to be copied. */
       if (G_VALUE_HOLDS (value, G_TYPE_STRING))
-        arg->v_string = (char *)g_value_get_string (value);
+        {
+          if (xfer == GI_TRANSFER_NOTHING)
+            arg->v_string = (char *)g_value_get_string (value);
+          else
+            arg->v_string = g_value_dup_string (value);
+        }
       else
         return_type_mismatch (value, G_TYPE_STRING);
       return TRUE;
@@ -236,18 +242,18 @@ tmpl_gi_argument_from_g_value (const GValue  *value,
           case GI_INFO_TYPE_INTERFACE:
           case GI_INFO_TYPE_OBJECT:
             if (G_VALUE_HOLDS_PARAM (value))
-              arg->v_pointer = g_value_get_param (value);
+              arg->v_pointer = xfer == GI_TRANSFER_NOTHING ? g_value_get_param (value) : g_value_dup_param 
(value);
             else
-              arg->v_pointer = g_value_get_object (value);
+              arg->v_pointer = xfer == GI_TRANSFER_NOTHING ? g_value_get_object (value) : g_value_dup_object 
(value);
             return TRUE;
 
           case GI_INFO_TYPE_BOXED:
           case GI_INFO_TYPE_STRUCT:
           case GI_INFO_TYPE_UNION:
             if (G_VALUE_HOLDS (value, G_TYPE_BOXED))
-              arg->v_pointer = g_value_get_boxed (value);
+              arg->v_pointer = xfer == GI_TRANSFER_NOTHING ? g_value_get_boxed (value) : g_value_dup_boxed 
(value);
             else if (G_VALUE_HOLDS (value, G_TYPE_VARIANT))
-              arg->v_pointer = g_value_get_variant (value);
+              arg->v_pointer = xfer == GI_TRANSFER_NOTHING ? g_value_get_variant (value) : 
g_value_dup_variant (value);
             else if (G_VALUE_HOLDS (value, G_TYPE_POINTER))
               arg->v_pointer = g_value_get_pointer (value);
             else
@@ -288,7 +294,7 @@ tmpl_gi_argument_from_g_value (const GValue  *value,
 
     case GI_TYPE_TAG_ERROR:
       if (G_VALUE_HOLDS (value, G_TYPE_ERROR))
-        arg->v_pointer = g_value_get_boxed (value);
+        arg->v_pointer = xfer == GI_TRANSFER_NOTHING ? g_value_get_boxed (value) : g_value_dup_boxed (value);
       else
         return_type_mismatch (value, G_TYPE_ERROR);
       return TRUE;


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