Commit ffa28a90 authored by Christian Hergert's avatar Christian Hergert

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.
parent 01918ae7
......@@ -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;
}
......
......@@ -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 */
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment