diff options
author | Giovanni Campagna <gcampagna@src.gnome.org> | 2014-05-06 18:53:21 +0200 |
---|---|---|
committer | Giovanni Campagna <gcampagna@src.gnome.org> | 2014-07-03 10:31:17 +0200 |
commit | a4c9d09d7a89d3c80b4465a5c2ae0efa24158b24 (patch) | |
tree | f56b061a761dd45ed64d9015c8a7cf00b46be710 /girepository | |
parent | b2bf49eae922bffddc952fcc22e4acbd7d40c5f3 (diff) | |
download | gobject-introspection-a4c9d09d7a89d3c80b4465a5c2ae0efa24158b24.tar.gz |
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
Diffstat (limited to 'girepository')
-rw-r--r-- | girepository/gicallableinfo.c | 26 | ||||
-rw-r--r-- | girepository/gicallableinfo.h | 2 | ||||
-rw-r--r-- | girepository/girepository.symbols | 1 | ||||
-rw-r--r-- | girepository/girnode.c | 3 | ||||
-rw-r--r-- | girepository/girnode.h | 3 | ||||
-rw-r--r-- | girepository/girparser.c | 74 | ||||
-rw-r--r-- | girepository/gitypelib-internal.h | 5 |
7 files changed, 108 insertions, 6 deletions
diff --git a/girepository/gicallableinfo.c b/girepository/gicallableinfo.c index e69e3e9d..702e16cd 100644 --- a/girepository/gicallableinfo.c +++ b/girepository/gicallableinfo.c @@ -276,6 +276,32 @@ g_callable_info_get_caller_owns (GICallableInfo *info) } /** + * 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 * diff --git a/girepository/gicallableinfo.h b/girepository/gicallableinfo.h index 71f9d0c6..f273d290 100644 --- a/girepository/gicallableinfo.h +++ b/girepository/gicallableinfo.h @@ -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 diff --git a/girepository/girepository.symbols b/girepository/girepository.symbols index 5f01adff..48fb0d90 100644 --- a/girepository/girepository.symbols +++ b/girepository/girepository.symbols @@ -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 diff --git a/girepository/girnode.c b/girepository/girnode.c index 53385c26..a7a77e31 100644 --- a/girepository/girnode.c +++ b/girepository/girnode.c @@ -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; diff --git a/girepository/girnode.h b/girepository/girnode.h index 4beef7f8..02196e7f 100644 --- a/girepository/girnode.h +++ b/girepository/girnode.h @@ -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; diff --git a/girepository/girparser.c b/girepository/girparser.c index 6c768669..f928c2e2 100644 --- a/girepository/girparser.c +++ b/girepository/girparser.c @@ -1047,6 +1047,71 @@ parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *n } 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, const gchar **attribute_names, @@ -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); diff --git a/girepository/gitypelib-internal.h b/girepository/gitypelib-internal.h index 93d621b2..5ccb6173 100644 --- a/girepository/gitypelib-internal.h +++ b/girepository/gitypelib-internal.h @@ -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; |