[gobject-introspection/ebassi/rebased-girffi-exec-fix: 4/8] Create new API for libffi closures




commit 55a18f528e490f17c7fd5d790cca6075bb375c51
Author: Cimbali <me cimba li>
Date:   Mon Nov 1 17:22:50 2021 +0100

    Create new API for libffi closures
    
    Deprecate the previous API as per discussion in !283.

 girepository/girffi.c          | 75 +++++++++++++++++++++++++++++++++++-------
 girepository/girffi.h          | 21 +++++++++---
 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__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]