girepository: Support GError exceptions on callbacks

Generalize "throws" attribute to SignatureBlob which can be used by all
callable blob types. Keep FunctionBlob and VFuncBlob throw attributes
around and functional for compatibility. Refactor girwriter.c to write
out throws attribute for all callable types.

Based on a patch by Simon Feltman.

https://bugzilla.gnome.org/show_bug.cgi?id=729543
This commit is contained in:
Garrett Regier 2015-06-03 05:24:21 -07:00
parent 6eaa308869
commit 96deb9ede5
4 changed files with 25 additions and 13 deletions

View File

@ -96,6 +96,17 @@ gboolean
g_callable_info_can_throw_gerror (GICallableInfo *info) g_callable_info_can_throw_gerror (GICallableInfo *info)
{ {
GIRealInfo *rinfo = (GIRealInfo*)info; GIRealInfo *rinfo = (GIRealInfo*)info;
SignatureBlob *signature;
signature = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)];
if (signature->throws)
return TRUE;
/* Functions and VFuncs store "throws" in their own blobs.
* This info was additionally added to the SignatureBlob
* to support the other callables. For Functions and VFuncs,
* also check their legacy flag for compatibility.
*/
switch (rinfo->type) { switch (rinfo->type) {
case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_FUNCTION:
{ {

View File

@ -1641,7 +1641,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob->getter = function->is_getter; blob->getter = function->is_getter;
blob->constructor = function->is_constructor; blob->constructor = function->is_constructor;
blob->wraps_vfunc = function->wraps_vfunc; blob->wraps_vfunc = function->wraps_vfunc;
blob->throws = function->throws; blob->throws = function->throws; /* Deprecated. Also stored in SignatureBlob. */
blob->index = 0; blob->index = 0;
blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->name = _g_ir_write_string (node->name, strings, data, offset2);
blob->symbol = _g_ir_write_string (function->symbol, strings, data, offset2); blob->symbol = _g_ir_write_string (function->symbol, strings, data, offset2);
@ -1667,6 +1667,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->instance_transfer_ownership = function->instance_transfer_full; blob2->instance_transfer_ownership = function->instance_transfer_full;
blob2->reserved = 0; blob2->reserved = 0;
blob2->n_arguments = n; blob2->n_arguments = n;
blob2->throws = function->throws;
signature += 4; signature += 4;
@ -1708,6 +1709,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->caller_owns_return_container = function->result->shallow_transfer; blob2->caller_owns_return_container = function->result->shallow_transfer;
blob2->reserved = 0; blob2->reserved = 0;
blob2->n_arguments = n; blob2->n_arguments = n;
blob2->throws = function->throws;
signature += 4; signature += 4;
@ -1797,7 +1799,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob->must_be_implemented = 0; /* FIXME */ blob->must_be_implemented = 0; /* FIXME */
blob->must_not_be_implemented = 0; /* FIXME */ blob->must_not_be_implemented = 0; /* FIXME */
blob->class_closure = 0; /* FIXME */ blob->class_closure = 0; /* FIXME */
blob->throws = vfunc->throws; blob->throws = vfunc->throws; /* Deprecated. Also stored in SignatureBlob. */
blob->reserved = 0; blob->reserved = 0;
if (vfunc->invoker) if (vfunc->invoker)
@ -1825,6 +1827,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->instance_transfer_ownership = vfunc->instance_transfer_full; blob2->instance_transfer_ownership = vfunc->instance_transfer_full;
blob2->reserved = 0; blob2->reserved = 0;
blob2->n_arguments = n; blob2->n_arguments = n;
blob2->throws = vfunc->throws;
signature += 4; signature += 4;

View File

@ -454,6 +454,9 @@ write_callable_info (const gchar *namespace,
GITypeInfo *type; GITypeInfo *type;
gint i; gint i;
if (g_callable_info_can_throw_gerror (info))
xml_printf (file, " throws=\"1\"");
write_attributes (file, (GIBaseInfo*) info); write_attributes (file, (GIBaseInfo*) info);
type = g_callable_info_get_return_type (info); type = g_callable_info_get_return_type (info);
@ -558,13 +561,11 @@ write_function_info (const gchar *namespace,
const gchar *name; const gchar *name;
const gchar *symbol; const gchar *symbol;
gboolean deprecated; gboolean deprecated;
gboolean throws;
flags = g_function_info_get_flags (info); flags = g_function_info_get_flags (info);
name = g_base_info_get_name ((GIBaseInfo *)info); name = g_base_info_get_name ((GIBaseInfo *)info);
symbol = g_function_info_get_symbol (info); symbol = g_function_info_get_symbol (info);
deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
throws = flags & GI_FUNCTION_THROWS;
if (flags & GI_FUNCTION_IS_CONSTRUCTOR) if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
tag = "constructor"; tag = "constructor";
@ -585,9 +586,6 @@ write_function_info (const gchar *namespace,
if (deprecated) if (deprecated)
xml_printf (file, " deprecated=\"1\""); xml_printf (file, " deprecated=\"1\"");
if (throws)
xml_printf (file, " throws=\"1\"");
write_callable_info (namespace, (GICallableInfo*)info, file); write_callable_info (namespace, (GICallableInfo*)info, file);
xml_end_element (file, tag); xml_end_element (file, tag);
} }
@ -914,9 +912,6 @@ write_vfunc_info (const gchar *namespace,
else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE) else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
xml_printf (file, " override=\"never\""); xml_printf (file, " override=\"never\"");
if (flags & GI_VFUNC_THROWS)
xml_printf (file, " throws=\"1\"");
xml_printf (file, " offset=\"%d\"", offset); xml_printf (file, " offset=\"%d\"", offset);
if (invoker) if (invoker)

View File

@ -467,6 +467,8 @@ typedef struct {
* be skipped. * be skipped.
* @instance_transfer_ownership: When calling, the function assumes ownership of * @instance_transfer_ownership: When calling, the function assumes ownership of
* the instance parameter. * the instance parameter.
* @throws: Denotes the signature takes an additional #GError argument beyond
* the annotated arguments.
* @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.
@ -482,7 +484,8 @@ typedef struct {
guint16 caller_owns_return_container : 1; guint16 caller_owns_return_container : 1;
guint16 skip_return : 1; guint16 skip_return : 1;
guint16 instance_transfer_ownership : 1; guint16 instance_transfer_ownership : 1;
guint16 reserved :11; guint16 throws : 1;
guint16 reserved :10;
guint16 n_arguments; guint16 n_arguments;
@ -522,7 +525,7 @@ typedef struct {
* @constructor: The function acts as a constructor for the object it is * @constructor: The function acts as a constructor for the object it is
* contained in. * contained in.
* @wraps_vfunc: The function is a simple wrapper for a virtual function. * @wraps_vfunc: The function is a simple wrapper for a virtual function.
* @throws: TODO * @throws: (deprecated): This is now additionally stored in the #SignatureBlob.
* @index: Index of the property that this function is a setter or getter of * @index: Index of the property that this function is a setter or getter of
* in the array of properties of the containing interface, or index * in the array of properties of the containing interface, or index
* of the virtual function that this function wraps. * of the virtual function that this function wraps.
@ -990,7 +993,7 @@ typedef struct {
* virtual function. * virtual function.
* @class_closure: Set if this virtual function is the class closure of a * @class_closure: Set if this virtual function is the class closure of a
* signal. * signal.
* @throws: TODO * @throws: (deprecated): This is now additionally stored in the #SignatureBlob.
* @reserved: Reserved for future use. * @reserved: Reserved for future use.
* @signal: The index of the signal in the list of signals of the object or * @signal: The index of the signal in the list of signals of the object or
* interface to which this virtual function belongs. * interface to which this virtual function belongs.