summaryrefslogtreecommitdiff
path: root/girepository/ginvoke.c
diff options
context:
space:
mode:
authorJohan Bilien <jobi@via.ecp.fr>2008-10-21 17:04:11 +0000
committerJohan Bilien <jobi@src.gnome.org>2008-10-21 17:04:11 +0000
commitefcca1bcac888b214b80fe2451edacbb3b224be3 (patch)
tree1f781e2fb232e65cc48731d19de4254d3bdb5f49 /girepository/ginvoke.c
parent05d588fc2d77ad6068ec992915d23afdfed1b7b4 (diff)
downloadgobject-introspection-efcca1bcac888b214b80fe2451edacbb3b224be3.tar.gz
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
Diffstat (limited to 'girepository/ginvoke.c')
-rw-r--r--girepository/ginvoke.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/girepository/ginvoke.c b/girepository/ginvoke.c
index d5182dbf..2626a956 100644
--- a/girepository/ginvoke.c
+++ b/girepository/ginvoke.c
@@ -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;
}