Bug 557241 – "throws" flag for functions

2008-10-21  Johan Bilien  <jobi@via.ecp.fr>

	Bug 557241 – "throws" flag for functions

	* tests/scanner/drawable-1.0-expected.gir,
	tests/scanner/drawable-injected-1.0-expected.gir,
	tests/scanner/drawable.[ch]: add simple test for throwing
	function (has GError ** as last argument)

	* giscanner/ast.py: add a 'throws' flag to Function
	* giscanner/glibtransformer.py: if a function's last paramerter is
	a GError, set the 'throws' flag and remove that parameter
	* giscanner/girwriter.py: write out the 'throws' attribute
	* giscanner/girparser.py: support parsing the 'throws' attribute

	* tests/repository/gitestthrows.c: add a simple test to check the
	throws flag in a typelib and invoke the function

	* girepository/ginfo.c, girepository/girnode.[ch],
	girepository/girnode.h, girepository/girparser.c,
	girepository/girepository.h: Add and parse the GI_FUNCTION_THROWS flag

	* girepository/ginvoke.c: if a function throws, add a GError as last
	arguments, and propagate the error to the invoker.


svn path=/trunk/; revision=773
This commit is contained in:
Johan Bilien 2008-10-21 17:04:11 +00:00 committed by Johan Bilien
parent c3330c06c7
commit 727bb01805
7 changed files with 43 additions and 6 deletions

View File

@ -492,6 +492,9 @@ g_function_info_get_flags (GIFunctionInfo *info)
if (blob->wraps_vfunc)
flags = flags | GI_FUNCTION_WRAPS_VFUNC;
if (blob->throws)
flags = flags | GI_FUNCTION_THROWS;
return flags;
}

View File

@ -159,9 +159,11 @@ g_function_info_invoke (GIFunctionInfo *info,
GITypeInfo *tinfo;
GIArgInfo *ainfo;
gboolean is_method;
gboolean throws;
gint n_args, n_invoke_args, in_pos, out_pos, i;
gpointer *args;
gboolean success = FALSE;
GError *local_error;
symbol = g_function_info_get_symbol (info);
@ -178,6 +180,7 @@ g_function_info_invoke (GIFunctionInfo *info,
is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0
&& (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0;
throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS;
tinfo = g_callable_info_get_return_type ((GICallableInfo *)info);
rtype = get_ffi_type (tinfo);
@ -202,6 +205,11 @@ g_function_info_invoke (GIFunctionInfo *info,
}
else
n_invoke_args = n_args;
if (throws)
/* Add an argument for the GError */
n_invoke_args ++;
atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args);
args = g_alloca (sizeof (gpointer) * n_invoke_args);
@ -279,6 +287,15 @@ g_function_info_invoke (GIFunctionInfo *info,
}
g_base_info_unref ((GIBaseInfo *)ainfo);
}
local_error = NULL;
if (throws)
{
gpointer address = &local_error;
args[n_invoke_args - 1] = &address;
atypes[n_invoke_args - 1] = &ffi_type_pointer;
}
if (in_pos < n_in_args)
{
g_set_error (error,
@ -301,7 +318,15 @@ g_function_info_invoke (GIFunctionInfo *info,
ffi_call (&cif, func, return_value, args);
success = TRUE;
if (local_error)
{
g_propagate_error (error, local_error);
success = FALSE;
}
else
{
success = TRUE;
}
out:
return success;
}

View File

@ -190,7 +190,8 @@ typedef enum
GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1,
GI_FUNCTION_IS_GETTER = 1 << 2,
GI_FUNCTION_IS_SETTER = 1 << 3,
GI_FUNCTION_WRAPS_VFUNC = 1 << 4
GI_FUNCTION_WRAPS_VFUNC = 1 << 4,
GI_FUNCTION_THROWS = 1 << 5
} GIFunctionInfoFlags;
const gchar * g_function_info_get_symbol (GIFunctionInfo *info);

View File

@ -1477,7 +1477,7 @@ g_ir_node_build_typelib (GIrNode *node,
blob->getter = function->is_getter;
blob->constructor = function->is_constructor;
blob->wraps_vfunc = function->wraps_vfunc;
blob->reserved = 0;
blob->throws = function->throws;
blob->index = 0;
blob->name = write_string (node->name, strings, data, offset2);
blob->symbol = write_string (function->symbol, strings, data, offset2);

View File

@ -92,6 +92,7 @@ struct _GIrNodeFunction
gboolean is_getter;
gboolean is_constructor;
gboolean wraps_vfunc;
gboolean throws;
gchar *symbol;

View File

@ -527,6 +527,7 @@ start_function (GMarkupParseContext *context,
const gchar *name;
const gchar *symbol;
const gchar *deprecated;
const gchar *throws;
GIrNodeFunction *function;
gboolean found = FALSE;
@ -557,6 +558,7 @@ start_function (GMarkupParseContext *context,
name = find_attribute ("name", attribute_names, attribute_values);
symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
throws = find_attribute ("throws", attribute_names, attribute_values);
if (name == NULL)
{
@ -598,7 +600,12 @@ start_function (GMarkupParseContext *context,
if (strcmp (element_name, "callback") == 0)
((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
}
if (throws && strcmp (throws, "1") == 0)
function->throws = TRUE;
else
function->throws = FALSE;
if (ctx->current_node == NULL)
{
ctx->current_module->entries =

View File

@ -166,11 +166,11 @@ typedef struct
guint16 blob_type; /* 1 */
guint16 deprecated : 1;
guint16 setter : 1;
guint16 setter : 1;
guint16 getter : 1;
guint16 constructor : 1;
guint16 wraps_vfunc : 1;
guint16 reserved : 1;
guint16 throws : 1;
guint16 index :10;
guint32 name;