mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-09 19:06:15 +01:00
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:
parent
d2514073b9
commit
9921571eb0
@ -275,6 +275,32 @@ g_callable_info_get_caller_owns (GICallableInfo *info)
|
||||
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:
|
||||
* @info: a #GICallableInfo
|
||||
|
@ -73,6 +73,8 @@ gboolean g_callable_info_invoke (GICallableInfo *info,
|
||||
gboolean is_method,
|
||||
gboolean throws,
|
||||
GError **error);
|
||||
GITransfer g_callable_info_get_instance_ownership_transfer (GICallableInfo *info);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@ g_info_new
|
||||
g_callable_info_can_throw_gerror
|
||||
g_callable_info_get_arg
|
||||
g_callable_info_get_caller_owns
|
||||
g_callable_info_get_instance_ownership_transfer
|
||||
g_callable_info_get_n_args
|
||||
g_callable_info_get_return_attribute
|
||||
g_callable_info_get_return_type
|
||||
|
@ -1664,6 +1664,7 @@ _g_ir_node_build_typelib (GIrNode *node,
|
||||
blob2->caller_owns_return_value = function->result->transfer;
|
||||
blob2->caller_owns_return_container = function->result->shallow_transfer;
|
||||
blob2->skip_return = function->result->skip;
|
||||
blob2->instance_transfer_ownership = function->instance_transfer_full;
|
||||
blob2->reserved = 0;
|
||||
blob2->n_arguments = n;
|
||||
|
||||
@ -1762,6 +1763,7 @@ _g_ir_node_build_typelib (GIrNode *node,
|
||||
blob2->may_return_null = signal->result->nullable;
|
||||
blob2->caller_owns_return_value = signal->result->transfer;
|
||||
blob2->caller_owns_return_container = signal->result->shallow_transfer;
|
||||
blob2->instance_transfer_ownership = signal->instance_transfer_full;
|
||||
blob2->reserved = 0;
|
||||
blob2->n_arguments = n;
|
||||
|
||||
@ -1820,6 +1822,7 @@ _g_ir_node_build_typelib (GIrNode *node,
|
||||
blob2->may_return_null = vfunc->result->nullable;
|
||||
blob2->caller_owns_return_value = vfunc->result->transfer;
|
||||
blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
|
||||
blob2->instance_transfer_ownership = vfunc->instance_transfer_full;
|
||||
blob2->reserved = 0;
|
||||
blob2->n_arguments = n;
|
||||
|
||||
|
@ -100,6 +100,7 @@ struct _GIrNodeFunction
|
||||
gboolean is_constructor;
|
||||
gboolean wraps_vfunc;
|
||||
gboolean throws;
|
||||
gboolean instance_transfer_full;
|
||||
|
||||
gchar *symbol;
|
||||
|
||||
@ -188,6 +189,7 @@ struct _GIrNodeSignal
|
||||
gboolean detailed;
|
||||
gboolean action;
|
||||
gboolean no_hooks;
|
||||
gboolean instance_transfer_full;
|
||||
|
||||
gboolean has_class_closure;
|
||||
gboolean true_stops_emit;
|
||||
@ -208,6 +210,7 @@ struct _GIrNodeVFunc
|
||||
gboolean must_not_be_implemented;
|
||||
gboolean is_class_closure;
|
||||
gboolean throws;
|
||||
gboolean instance_transfer_full;
|
||||
|
||||
char *invoker;
|
||||
|
||||
|
74
girparser.c
74
girparser.c
@ -1046,6 +1046,71 @@ parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *n
|
||||
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
|
||||
start_parameter (GMarkupParseContext *context,
|
||||
const gchar *element_name,
|
||||
@ -2848,11 +2913,10 @@ start_element_handler (GMarkupParseContext *context,
|
||||
attribute_names, attribute_values,
|
||||
ctx, error))
|
||||
goto out;
|
||||
else if (strcmp (element_name, "instance-parameter") == 0)
|
||||
{
|
||||
state_switch (ctx, STATE_PASSTHROUGH);
|
||||
goto out;
|
||||
}
|
||||
else if (start_instance_parameter (context, element_name,
|
||||
attribute_names, attribute_values,
|
||||
ctx, error))
|
||||
goto out;
|
||||
else if (strcmp (element_name, "c:include") == 0)
|
||||
{
|
||||
state_switch (ctx, STATE_C_INCLUDE);
|
||||
|
@ -465,6 +465,8 @@ typedef struct {
|
||||
* freeing the container, but not its contents.
|
||||
* @skip_return: Indicates that the return value is only useful in C and should
|
||||
* be skipped.
|
||||
* @instance_transfer_ownership: When calling, the function assumes ownership of
|
||||
* the instance parameter.
|
||||
* @reserved: Reserved for future use.
|
||||
* @n_arguments: The number of arguments that this function expects, also the
|
||||
* length of the array of ArgBlobs.
|
||||
@ -479,7 +481,8 @@ typedef struct {
|
||||
guint16 caller_owns_return_value : 1;
|
||||
guint16 caller_owns_return_container : 1;
|
||||
guint16 skip_return : 1;
|
||||
guint16 reserved :12;
|
||||
guint16 instance_transfer_ownership : 1;
|
||||
guint16 reserved :11;
|
||||
|
||||
guint16 n_arguments;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user