diff options
-rw-r--r-- | girepository/girffi.c | 75 | ||||
-rw-r--r-- | girepository/girffi.h | 21 | ||||
-rw-r--r-- | girepository/giversionmacros.h | 14 |
3 files changed, 94 insertions, 16 deletions
diff --git a/girepository/girffi.c b/girepository/girffi.c index 12770203..85165132 100644 --- a/girepository/girffi.c +++ b/girepository/girffi.c @@ -353,7 +353,7 @@ typedef struct { } GIClosureWrapper; /** - * g_callable_info_prepare_closure: + * g_callable_info_create_closure: * @callable_info: a callable info from a typelib * @cif: a ffi_cif structure * @callback: the ffi callback @@ -362,13 +362,13 @@ typedef struct { * Prepares a callback for ffi invocation. * * Returns: the ffi_closure or NULL on error. The return value - * should be freed by calling g_callable_info_free_closure(). + * should be freed by calling g_callable_info_destroy_closure(). */ ffi_closure * -g_callable_info_prepare_closure (GICallableInfo *callable_info, - ffi_cif *cif, - GIFFIClosureCallback callback, - gpointer user_data) +g_callable_info_create_closure (GICallableInfo *callable_info, + ffi_cif *cif, + GIFFIClosureCallback callback, + gpointer user_data) { gpointer exec_ptr; int n_args; @@ -389,6 +389,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, closure->writable_self = closure; closure->native_address = exec_ptr; + atypes = g_callable_info_get_ffi_arg_types (callable_info, &n_args); status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, n_args, g_callable_info_get_ffi_return_type (callable_info), @@ -416,7 +417,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, * @callable_info: a callable info from a typelib * @closure: ffi closure * - * Gets callable code from ffi_closure prepared by g_callable_info_prepare_closure() + * Gets callable code from ffi_closure prepared by g_callable_info_create_closure() */ gpointer * g_callable_info_get_closure_native_address (GICallableInfo *callable_info, @@ -427,18 +428,70 @@ g_callable_info_get_closure_native_address (GICallableInfo *callable_info, } /** - * g_callable_info_free_closure: + * g_callable_info_destroy_closure: * @callable_info: a callable info from a typelib * @closure: ffi closure * - * Frees a ffi_closure returned from g_callable_info_prepare_closure() + * Frees a ffi_closure returned from g_callable_info_create_closure() */ void -g_callable_info_free_closure (GICallableInfo *callable_info, - ffi_closure *closure) +g_callable_info_destroy_closure (GICallableInfo *callable_info, + ffi_closure *closure) { GIClosureWrapper *wrapper = (GIClosureWrapper *)closure; g_free (wrapper->ffi_closure.cif->arg_types); ffi_closure_free (wrapper->writable_self); } + +/** + * g_callable_info_prepare_closure: + * @callable_info: a callable info from a typelib + * @cif: a ffi_cif structure + * @callback: the ffi callback + * @user_data: data to be passed into the callback + * + * Prepares a callback for ffi invocation. Deprecated + * + * Returns: the native address of the closre or NULL on error. The return value + * should be freed by calling g_callable_info_free_closure(). + */ +ffi_closure * +g_callable_info_prepare_closure (GICallableInfo *callable_info, + ffi_cif *cif, + GIFFIClosureCallback callback, + gpointer user_data) +{ + ffi_closure * closure; + + closure = g_callable_info_create_closure(callable_info, cif, callback, user_data); + if (!closure) + { + return NULL; + } + + g_warning ("g_callable_info_prepare_closure is deprecated, use g_callable_info_create_closure instead\n"); + + /* Return the native pointer which, on some systems and ffi versions without static exec trampolines, + * points to the same underlying memory as closure, but via an executable-non-writable mapping. + * Deprecated, and kept for backwards compatibility only. Risks segfaults on freeing the closure. + */ + return (ffi_closure *) g_callable_info_get_closure_native_address(callable_info, closure); +} + +/** + * g_callable_info_free_closure: + * @callable_info: a callable info from a typelib + * @closure: ffi closure + * + * Does nothing. (Leaks memory!) Use g_callable_info_destroy_closure() instead, + * in conjunction with g_callable_info_create_closure(). + * + * Should free a ffi_closure returned from g_callable_info_prepare_closure(), + * which may cause a segfault because the native address is returned instead + * of the closure address. + */ +void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure) +{ + g_warning ("g_callable_info_free_closure is deprecated and leaks memory\n"); +} diff --git a/girepository/girffi.h b/girepository/girffi.h index c6cb5e91..2bbc97ac 100644 --- a/girepository/girffi.h +++ b/girepository/girffi.h @@ -90,19 +90,30 @@ GI_AVAILABLE_IN_ALL void g_function_invoker_destroy (GIFunctionInvoker *invoker); -GI_AVAILABLE_IN_ALL +GI_DEPRECATED_IN_1_72_FOR(g_callable_info_create_closure) ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, ffi_cif *cif, GIFFIClosureCallback callback, gpointer user_data); -GI_AVAILABLE_IN_1_70 +GI_DEPRECATED_IN_1_72_FOR(g_callable_info_destroy_closure) +void g_callable_info_free_closure (GICallableInfo *callable_info, + ffi_closure *closure); + + +GI_AVAILABLE_IN_1_72 +ffi_closure * g_callable_info_create_closure (GICallableInfo *callable_info, + ffi_cif *cif, + GIFFIClosureCallback callback, + gpointer user_data); + +GI_AVAILABLE_IN_1_72 gpointer * g_callable_info_get_closure_native_address (GICallableInfo *callable_info, ffi_closure *closure); -GI_AVAILABLE_IN_ALL -void g_callable_info_free_closure (GICallableInfo *callable_info, - ffi_closure *closure); +GI_AVAILABLE_IN_1_72 +void g_callable_info_destroy_closure (GICallableInfo *callable_info, + ffi_closure *closure); G_END_DECLS diff --git a/girepository/giversionmacros.h b/girepository/giversionmacros.h index 273af725..d1b1733c 100644 --- a/girepository/giversionmacros.h +++ b/girepository/giversionmacros.h @@ -171,4 +171,18 @@ # define GI_AVAILABLE_IN_1_70 _GI_EXTERN #endif +#if defined(GLIB_VERSION_2_72) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_72 +# define GI_DEPRECATED_IN_1_72 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_72_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_72 _GI_EXTERN +# define GI_DEPRECATED_IN_1_72_FOR(f) _GI_EXTERN +#endif + +#if defined(GLIB_VERSION_2_72) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_72 +# define GI_AVAILABLE_IN_1_72 GLIB_UNAVAILABLE(2, 72) +#else +# define GI_AVAILABLE_IN_1_72 _GI_EXTERN +#endif + #endif /* __GIVERSIONMACROS_H__ */ |