mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 03:02:10 +01:00
Create new API for libffi closures
Deprecate the previous API as per discussion in !283.
This commit is contained in:
parent
5e053279b5
commit
8e96029a32
75
girffi.c
75
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");
|
||||
}
|
||||
|
21
girffi.h
21
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
|
||||
|
||||
|
@ -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__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user