Parse and expose ownership transfer for instance parameters

Knowing the ownership transfer for instance parameters is
necessary for correct memory management of functions which
"eat" their instance argument, such as g_dbus_method_invocation_return_*.
Parse this information from the gir file and store in the
typelib, and then provide new API on GICallableInfo to
retrieve this.

https://bugzilla.gnome.org/show_bug.cgi?id=729662
This commit is contained in:
Giovanni Campagna 2014-05-06 18:53:21 +02:00
parent d2514073b9
commit 9921571eb0
7 changed files with 108 additions and 6 deletions

View File

@ -275,6 +275,32 @@ g_callable_info_get_caller_owns (GICallableInfo *info)
return GI_TRANSFER_NOTHING; return GI_TRANSFER_NOTHING;
} }
/**
* g_callable_info_get_instance_ownership_transfer:
* @info: a #GICallableInfo
*
* Obtains the ownership transfer for the instance argument.
* #GITransfer contains a list of possible transfer values.
*
* Returns: the transfer
*/
GITransfer
g_callable_info_get_instance_ownership_transfer (GICallableInfo *info)
{
GIRealInfo *rinfo = (GIRealInfo*) info;
SignatureBlob *blob;
g_return_val_if_fail (info != NULL, -1);
g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1);
blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)];
if (blob->instance_transfer_ownership)
return GI_TRANSFER_EVERYTHING;
else
return GI_TRANSFER_NOTHING;
}
/** /**
* g_callable_info_get_n_args: * g_callable_info_get_n_args:
* @info: a #GICallableInfo * @info: a #GICallableInfo

View File

@ -73,6 +73,8 @@ gboolean g_callable_info_invoke (GICallableInfo *info,
gboolean is_method, gboolean is_method,
gboolean throws, gboolean throws,
GError **error); GError **error);
GITransfer g_callable_info_get_instance_ownership_transfer (GICallableInfo *info);
G_END_DECLS G_END_DECLS

View File

@ -26,6 +26,7 @@ g_info_new
g_callable_info_can_throw_gerror g_callable_info_can_throw_gerror
g_callable_info_get_arg g_callable_info_get_arg
g_callable_info_get_caller_owns g_callable_info_get_caller_owns
g_callable_info_get_instance_ownership_transfer
g_callable_info_get_n_args g_callable_info_get_n_args
g_callable_info_get_return_attribute g_callable_info_get_return_attribute
g_callable_info_get_return_type g_callable_info_get_return_type

View File

@ -1664,6 +1664,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->caller_owns_return_value = function->result->transfer; blob2->caller_owns_return_value = function->result->transfer;
blob2->caller_owns_return_container = function->result->shallow_transfer; blob2->caller_owns_return_container = function->result->shallow_transfer;
blob2->skip_return = function->result->skip; blob2->skip_return = function->result->skip;
blob2->instance_transfer_ownership = function->instance_transfer_full;
blob2->reserved = 0; blob2->reserved = 0;
blob2->n_arguments = n; blob2->n_arguments = n;
@ -1762,6 +1763,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->may_return_null = signal->result->nullable; blob2->may_return_null = signal->result->nullable;
blob2->caller_owns_return_value = signal->result->transfer; blob2->caller_owns_return_value = signal->result->transfer;
blob2->caller_owns_return_container = signal->result->shallow_transfer; blob2->caller_owns_return_container = signal->result->shallow_transfer;
blob2->instance_transfer_ownership = signal->instance_transfer_full;
blob2->reserved = 0; blob2->reserved = 0;
blob2->n_arguments = n; blob2->n_arguments = n;
@ -1820,6 +1822,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->may_return_null = vfunc->result->nullable; blob2->may_return_null = vfunc->result->nullable;
blob2->caller_owns_return_value = vfunc->result->transfer; blob2->caller_owns_return_value = vfunc->result->transfer;
blob2->caller_owns_return_container = vfunc->result->shallow_transfer; blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
blob2->instance_transfer_ownership = vfunc->instance_transfer_full;
blob2->reserved = 0; blob2->reserved = 0;
blob2->n_arguments = n; blob2->n_arguments = n;

View File

@ -100,6 +100,7 @@ struct _GIrNodeFunction
gboolean is_constructor; gboolean is_constructor;
gboolean wraps_vfunc; gboolean wraps_vfunc;
gboolean throws; gboolean throws;
gboolean instance_transfer_full;
gchar *symbol; gchar *symbol;
@ -188,6 +189,7 @@ struct _GIrNodeSignal
gboolean detailed; gboolean detailed;
gboolean action; gboolean action;
gboolean no_hooks; gboolean no_hooks;
gboolean instance_transfer_full;
gboolean has_class_closure; gboolean has_class_closure;
gboolean true_stops_emit; gboolean true_stops_emit;
@ -208,6 +210,7 @@ struct _GIrNodeVFunc
gboolean must_not_be_implemented; gboolean must_not_be_implemented;
gboolean is_class_closure; gboolean is_class_closure;
gboolean throws; gboolean throws;
gboolean instance_transfer_full;
char *invoker; char *invoker;

View File

@ -1046,6 +1046,71 @@ parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *n
return TRUE; return TRUE;
} }
static gboolean
start_instance_parameter (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
ParseContext *ctx,
GError **error)
{
const gchar *transfer;
gboolean transfer_full;
if (!(strcmp (element_name, "instance-parameter") == 0 &&
ctx->state == STATE_FUNCTION_PARAMETERS))
return FALSE;
transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
state_switch (ctx, STATE_PASSTHROUGH);
if (strcmp (transfer, "full") == 0)
transfer_full = TRUE;
else if (strcmp (transfer, "none") == 0)
transfer_full = FALSE;
else
{
g_set_error (error, G_MARKUP_ERROR,
G_MARKUP_ERROR_INVALID_CONTENT,
"invalid value for 'transfer-ownership' for instance parameter: %s", transfer);
return FALSE;
}
switch (CURRENT_NODE (ctx)->type)
{
case G_IR_NODE_FUNCTION:
case G_IR_NODE_CALLBACK:
{
GIrNodeFunction *func;
func = (GIrNodeFunction *)CURRENT_NODE (ctx);
func->instance_transfer_full = transfer_full;
}
break;
case G_IR_NODE_SIGNAL:
{
GIrNodeSignal *signal;
signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
signal->instance_transfer_full = transfer_full;
}
break;
case G_IR_NODE_VFUNC:
{
GIrNodeVFunc *vfunc;
vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
vfunc->instance_transfer_full = transfer_full;
}
break;
default:
g_assert_not_reached ();
}
return TRUE;
}
static gboolean static gboolean
start_parameter (GMarkupParseContext *context, start_parameter (GMarkupParseContext *context,
const gchar *element_name, const gchar *element_name,
@ -2848,11 +2913,10 @@ start_element_handler (GMarkupParseContext *context,
attribute_names, attribute_values, attribute_names, attribute_values,
ctx, error)) ctx, error))
goto out; goto out;
else if (strcmp (element_name, "instance-parameter") == 0) else if (start_instance_parameter (context, element_name,
{ attribute_names, attribute_values,
state_switch (ctx, STATE_PASSTHROUGH); ctx, error))
goto out; goto out;
}
else if (strcmp (element_name, "c:include") == 0) else if (strcmp (element_name, "c:include") == 0)
{ {
state_switch (ctx, STATE_C_INCLUDE); state_switch (ctx, STATE_C_INCLUDE);

View File

@ -465,6 +465,8 @@ typedef struct {
* freeing the container, but not its contents. * freeing the container, but not its contents.
* @skip_return: Indicates that the return value is only useful in C and should * @skip_return: Indicates that the return value is only useful in C and should
* be skipped. * be skipped.
* @instance_transfer_ownership: When calling, the function assumes ownership of
* the instance parameter.
* @reserved: Reserved for future use. * @reserved: Reserved for future use.
* @n_arguments: The number of arguments that this function expects, also the * @n_arguments: The number of arguments that this function expects, also the
* length of the array of ArgBlobs. * length of the array of ArgBlobs.
@ -479,7 +481,8 @@ typedef struct {
guint16 caller_owns_return_value : 1; guint16 caller_owns_return_value : 1;
guint16 caller_owns_return_container : 1; guint16 caller_owns_return_container : 1;
guint16 skip_return : 1; guint16 skip_return : 1;
guint16 reserved :12; guint16 instance_transfer_ownership : 1;
guint16 reserved :11;
guint16 n_arguments; guint16 n_arguments;