summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCimbali <me@cimba.li>2021-11-01 17:22:50 +0100
committerEmmanuele Bassi <ebassi@gnome.org>2021-11-23 23:04:26 +0000
commit55a18f528e490f17c7fd5d790cca6075bb375c51 (patch)
tree0b673cdecceec4d1c0d35fd7b39402686c3c413d
parent2a4dede7c2fdc3e6a6a5b063449ab3a8c58c11c0 (diff)
downloadgobject-introspection-55a18f528e490f17c7fd5d790cca6075bb375c51.tar.gz
Create new API for libffi closures
Deprecate the previous API as per discussion in !283.
-rw-r--r--girepository/girffi.c75
-rw-r--r--girepository/girffi.h21
-rw-r--r--girepository/giversionmacros.h14
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__ */