[gobject-introspection/wip/gobj-kitchen-sink: 1/5] girffi: Add new g_function_invoker_new_for_address



commit 8e34268de5c57095a0dfb89df4f77480bc823a84
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Nov 28 14:51:04 2011 -0500

    girffi: Add new g_function_invoker_new_for_address
    
    This is a new method designed to make a GIFunctionInvoker for
    any GICallableInfo*, for bindings to use.

 girepository/girffi.c |   79 ++++++++++++++++++++++++++++++++++++++++---------
 girepository/girffi.h |    5 +++
 2 files changed, 70 insertions(+), 14 deletions(-)
---
diff --git a/girepository/girffi.c b/girepository/girffi.c
index 3bddb72..2e8fe33 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 a5cc9e4..3b3e9c7 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);
 
 



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