diff options
-rw-r--r-- | girepository/girffi.c | 79 | ||||
-rw-r--r-- | girepository/girffi.h | 5 |
2 files changed, 70 insertions, 14 deletions
diff --git a/girepository/girffi.c b/girepository/girffi.c index 3bddb724..2e8fe337 100644 --- a/girepository/girffi.c +++ b/girepository/girffi.c @@ -230,13 +230,7 @@ g_function_info_prep_invoker (GIFunctionInfo *info, GError **error) { const char *symbol; - ffi_type *rtype; - ffi_type **atypes; - GITypeInfo *tinfo; - GIArgInfo *ainfo; - gboolean is_method; - gboolean throws; - gint n_args, n_invoke_args, i; + gpointer addr; g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (invoker != NULL, FALSE); @@ -244,7 +238,7 @@ g_function_info_prep_invoker (GIFunctionInfo *info, symbol = g_function_info_get_symbol ((GIFunctionInfo*) info); if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), - symbol, &(invoker->native_address))) + symbol, &addr)) { g_set_error (error, G_INVOKE_ERROR, @@ -254,15 +248,72 @@ g_function_info_prep_invoker (GIFunctionInfo *info, return FALSE; } - 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; + return g_function_invoker_new_for_address (addr, info, invoker, error); +} + +/** + * g_function_invoker_new_for_address: + * @addr: The address + * @info: A #GICallableInfo + * @invoker: Output invoker structure + * @error: A #GError + * + * Initialize the caller-allocated @invoker structure with a cache + * of information needed to invoke the C function corresponding to + * @info with the platform's default ABI. + * + * A primary intent of this function is that a dynamic structure allocated + * by a language binding could contain a #GIFunctionInvoker structure + * inside the binding's function mapping. + * + * Returns: %TRUE on success, %FALSE otherwise with @error set. + */ +gboolean +g_function_invoker_new_for_address (gpointer addr, + GICallableInfo *info, + GIFunctionInvoker *invoker, + GError **error) +{ + ffi_type *rtype; + ffi_type **atypes; + GITypeInfo *tinfo; + GIArgInfo *ainfo; + GIInfoType info_type; + gboolean is_method; + gboolean throws; + gint n_args, n_invoke_args, i; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (invoker != NULL, FALSE); + + invoker->native_address = addr; + + info_type = g_base_info_get_type ((GIBaseInfo *) info); + + switch (info_type) + { + case GI_INFO_TYPE_FUNCTION: + { + GIFunctionInfoFlags flags; + flags = g_function_info_get_flags ((GIFunctionInfo *)info); + is_method = (flags & GI_FUNCTION_IS_METHOD) != 0; + throws = (flags & GI_FUNCTION_THROWS) != 0; + } + break; + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_VFUNC: + is_method = TRUE; + throws = FALSE; + break; + default: + g_assert_not_reached (); + } - tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); + tinfo = g_callable_info_get_return_type (info); rtype = g_type_info_get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); - n_args = g_callable_info_get_n_args ((GICallableInfo *)info); + n_args = g_callable_info_get_n_args (info); if (is_method) n_invoke_args = n_args+1; else @@ -282,7 +333,7 @@ g_function_info_prep_invoker (GIFunctionInfo *info, for (i = 0; i < n_args; i++) { int offset = (is_method ? 1 : 0); - ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); + ainfo = g_callable_info_get_arg (info, i); switch (g_arg_info_get_direction (ainfo)) { case GI_DIRECTION_IN: diff --git a/girepository/girffi.h b/girepository/girffi.h index a5cc9e46..3b3e9c74 100644 --- a/girepository/girffi.h +++ b/girepository/girffi.h @@ -53,6 +53,11 @@ gboolean g_function_info_prep_invoker (GIFunctionInfo *info, GIFunctionInvoker *invoker, GError **error); +gboolean g_function_invoker_new_for_address (gpointer addr, + GICallableInfo *info, + GIFunctionInvoker *invoker, + GError **error); + void g_function_invoker_destroy (GIFunctionInvoker *invoker); |