[gifunctioninfo] Move over invoke function
authorJohan Dahlin <johan@gnome.org>
Sun, 6 Jun 2010 16:22:29 +0000 (13:22 -0300)
committerJohan Dahlin <johan@gnome.org>
Sun, 6 Jun 2010 16:27:16 +0000 (13:27 -0300)
Move over g_function_info_invoke to gifunctioninfo.c

girepository/gifunctioninfo.c
girepository/ginvoke.c

index 07e0ec6..1bda54d 100644 (file)
@@ -24,8 +24,7 @@
 #include <girepository.h>
 #include "girepository-private.h"
 #include "gitypelib-internal.h"
-
-/* GIFunctionInfo functions */
+#include "girffi.h"
 
 /**
  * SECTION:gifunctioninfo
@@ -167,3 +166,226 @@ g_function_info_get_vfunc (GIFunctionInfo *info)
   return g_interface_info_get_vfunc (container, blob->index);
 }
 
+GQuark
+g_invoke_error_quark (void)
+{
+  static GQuark quark = 0;
+  if (quark == 0)
+    quark = g_quark_from_static_string ("g-invoke-error-quark");
+  return quark;
+}
+
+/**
+ * g_function_info_invoke:
+ * @info: a #GIFunctionInfo describing the function to invoke
+ * @in_args: an array of #GArgument<!-- -->s, one for each in
+ *    parameter of @info. If there are no in parameter, @in_args
+ *    can be %NULL
+ * @n_in_args: the length of the @in_args array
+ * @out_args: an array of #GArgument<!-- -->s, one for each out
+ *    parameter of @info. If there are no out parameters, @out_args
+ *    may be %NULL
+ * @n_out_args: the length of the @out_args array
+ * @return_value: return location for the return value of the
+ *    function. If the function returns void, @return_value may be
+ *    %NULL
+ * @error: return location for detailed error information, or %NULL
+ *
+ * Invokes the function described in @info with the given
+ * arguments. Note that inout parameters must appear in both
+ * argument lists. This function uses dlsym() to obtain a pointer
+ * to the function, so the library or shared object containing the
+ * described function must either be linked to the caller, or must
+ * have been g_module_symbol()<!-- -->ed before calling this function.
+ *
+ * Returns: %TRUE if the function has been invoked, %FALSE if an
+ *   error occurred.
+ */
+gboolean
+g_function_info_invoke (GIFunctionInfo *info,
+                       const GArgument  *in_args,
+                       int               n_in_args,
+                       const GArgument  *out_args,
+                       int               n_out_args,
+                       GArgument        *return_value,
+                       GError          **error)
+{
+  ffi_cif cif;
+  ffi_type *rtype;
+  ffi_type **atypes;
+  const gchar *symbol;
+  gpointer func;
+  GITypeInfo *tinfo;
+  GIArgInfo *ainfo;
+  gboolean is_method;
+  gboolean throws;
+  gint n_args, n_invoke_args, in_pos, out_pos, i;
+  gpointer *args;
+  gboolean success = FALSE;
+  GError *local_error = NULL;
+  gpointer error_address = &local_error;
+
+  symbol = g_function_info_get_symbol (info);
+
+  if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info),
+                         symbol, &func))
+    {
+      g_set_error (error,
+                   G_INVOKE_ERROR,
+                   G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
+                   "Could not locate %s: %s", symbol, g_module_error ());
+
+      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;
+
+  tinfo = g_callable_info_get_return_type ((GICallableInfo *)info);
+  rtype = g_type_info_get_ffi_type (tinfo);
+  g_base_info_unref ((GIBaseInfo *)tinfo);
+
+  in_pos = 0;
+  out_pos = 0;
+
+  n_args = g_callable_info_get_n_args ((GICallableInfo *)info);
+  if (is_method)
+    {
+      if (n_in_args == 0)
+       {
+         g_set_error (error,
+                      G_INVOKE_ERROR,
+                      G_INVOKE_ERROR_ARGUMENT_MISMATCH,
+                      "Too few \"in\" arguments (handling this)");
+         goto out;
+       }
+      n_invoke_args = n_args+1;
+      in_pos++;
+    }
+  else
+    n_invoke_args = n_args;
+
+  if (throws)
+    /* Add an argument for the GError */
+    n_invoke_args ++;
+
+  atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args);
+  args = g_alloca (sizeof (gpointer) * n_invoke_args);
+
+  if (is_method)
+    {
+      atypes[0] = &ffi_type_pointer;
+      args[0] = (gpointer) &in_args[0];
+    }
+  for (i = 0; i < n_args; i++)
+    {
+      int offset = (is_method ? 1 : 0);
+      ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i);
+      switch (g_arg_info_get_direction (ainfo))
+       {
+       case GI_DIRECTION_IN:
+         tinfo = g_arg_info_get_type (ainfo);
+         atypes[i+offset] = g_type_info_get_ffi_type (tinfo);
+         g_base_info_unref ((GIBaseInfo *)tinfo);
+
+         if (in_pos >= n_in_args)
+           {
+             g_set_error (error,
+                          G_INVOKE_ERROR,
+                          G_INVOKE_ERROR_ARGUMENT_MISMATCH,
+                          "Too few \"in\" arguments (handling in)");
+             goto out;
+           }
+
+         args[i+offset] = (gpointer)&in_args[in_pos];
+         in_pos++;
+
+         break;
+       case GI_DIRECTION_OUT:
+         atypes[i+offset] = &ffi_type_pointer;
+
+         if (out_pos >= n_out_args)
+           {
+             g_set_error (error,
+                          G_INVOKE_ERROR,
+                          G_INVOKE_ERROR_ARGUMENT_MISMATCH,
+                          "Too few \"out\" arguments (handling out)");
+             goto out;
+           }
+
+         args[i+offset] = (gpointer)&out_args[out_pos];
+         out_pos++;
+         break;
+       case GI_DIRECTION_INOUT:
+         atypes[i+offset] = &ffi_type_pointer;
+
+         if (in_pos >= n_in_args)
+           {
+             g_set_error (error,
+                          G_INVOKE_ERROR,
+                          G_INVOKE_ERROR_ARGUMENT_MISMATCH,
+                          "Too few \"in\" arguments (handling inout)");
+             goto out;
+           }
+
+         if (out_pos >= n_out_args)
+           {
+             g_set_error (error,
+                          G_INVOKE_ERROR,
+                          G_INVOKE_ERROR_ARGUMENT_MISMATCH,
+                          "Too few \"out\" arguments (handling inout)");
+             goto out;
+           }
+
+         args[i+offset] = (gpointer)&in_args[in_pos];
+         in_pos++;
+         out_pos++;
+         break;
+       default:
+         g_assert_not_reached ();
+       }
+      g_base_info_unref ((GIBaseInfo *)ainfo);
+    }
+
+  if (throws)
+    {
+      args[n_invoke_args - 1] = &error_address;
+      atypes[n_invoke_args - 1] = &ffi_type_pointer;
+    }
+
+  if (in_pos < n_in_args)
+    {
+      g_set_error (error,
+                  G_INVOKE_ERROR,
+                  G_INVOKE_ERROR_ARGUMENT_MISMATCH,
+                  "Too many \"in\" arguments (at end)");
+      goto out;
+    }
+  if (out_pos < n_out_args)
+    {
+      g_set_error (error,
+                  G_INVOKE_ERROR,
+                  G_INVOKE_ERROR_ARGUMENT_MISMATCH,
+                  "Too many \"out\" arguments (at end)");
+      goto out;
+    }
+
+  if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK)
+    goto out;
+
+  g_return_val_if_fail (return_value, FALSE);
+  ffi_call (&cif, func, return_value, args);
+
+  if (local_error)
+    {
+      g_propagate_error (error, local_error);
+      success = FALSE;
+    }
+  else
+    {
+      success = TRUE;
+    }
+ out:
+  return success;
+}
index 3de6af4..0f9d22c 100644 (file)
 #include <glib.h>
 #include <glib-object.h>
 
-#include "girepository.h"
+#include <girepository.h>
 #include "girffi.h"
-#include "gitypelib-internal.h"
 #include "config.h"
 
-GQuark
-g_invoke_error_quark (void)
-{
-  static GQuark quark = 0;
-  if (quark == 0)
-    quark = g_quark_from_static_string ("g-invoke-error-quark");
-  return quark;
-}
-
-/**
- * g_function_info_invoke:
- * @info: a #GIFunctionInfo describing the function to invoke
- * @in_args: an array of #GArgument<!-- -->s, one for each in
- *    parameter of @info. If there are no in parameter, @in_args
- *    can be %NULL
- * @n_in_args: the length of the @in_args array
- * @out_args: an array of #GArgument<!-- -->s, one for each out
- *    parameter of @info. If there are no out parameters, @out_args
- *    may be %NULL
- * @n_out_args: the length of the @out_args array
- * @return_value: return location for the return value of the
- *    function. If the function returns void, @return_value may be
- *    %NULL
- * @error: return location for detailed error information, or %NULL
- *
- * Invokes the function described in @info with the given
- * arguments. Note that inout parameters must appear in both
- * argument lists. This function uses dlsym() to obtain a pointer
- * to the function, so the library or shared object containing the
- * described function must either be linked to the caller, or must
- * have been g_module_symbol()<!-- -->ed before calling this function.
- *
- * Returns: %TRUE if the function has been invoked, %FALSE if an
- *   error occurred.
- */
-gboolean
-g_function_info_invoke (GIFunctionInfo *info,
-                       const GArgument  *in_args,
-                       int               n_in_args,
-                       const GArgument  *out_args,
-                       int               n_out_args,
-                       GArgument        *return_value,
-                       GError          **error)
-{
-  ffi_cif cif;
-  ffi_type *rtype;
-  ffi_type **atypes;
-  const gchar *symbol;
-  gpointer func;
-  GITypeInfo *tinfo;
-  GIArgInfo *ainfo;
-  gboolean is_method;
-  gboolean throws;
-  gint n_args, n_invoke_args, in_pos, out_pos, i;
-  gpointer *args;
-  gboolean success = FALSE;
-  GError *local_error = NULL;
-  gpointer error_address = &local_error;
-
-  symbol = g_function_info_get_symbol (info);
-
-  if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info),
-                         symbol, &func))
-    {
-      g_set_error (error,
-                   G_INVOKE_ERROR,
-                   G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
-                   "Could not locate %s: %s", symbol, g_module_error ());
-
-      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;
-
-  tinfo = g_callable_info_get_return_type ((GICallableInfo *)info);
-  rtype = g_type_info_get_ffi_type (tinfo);
-  g_base_info_unref ((GIBaseInfo *)tinfo);
-
-  in_pos = 0;
-  out_pos = 0;
-
-  n_args = g_callable_info_get_n_args ((GICallableInfo *)info);
-  if (is_method)
-    {
-      if (n_in_args == 0)
-       {
-         g_set_error (error,
-                      G_INVOKE_ERROR,
-                      G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-                      "Too few \"in\" arguments (handling this)");
-         goto out;
-       }
-      n_invoke_args = n_args+1;
-      in_pos++;
-    }
-  else
-    n_invoke_args = n_args;
-
-  if (throws)
-    /* Add an argument for the GError */
-    n_invoke_args ++;
-
-  atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args);
-  args = g_alloca (sizeof (gpointer) * n_invoke_args);
-
-  if (is_method)
-    {
-      atypes[0] = &ffi_type_pointer;
-      args[0] = (gpointer) &in_args[0];
-    }
-  for (i = 0; i < n_args; i++)
-    {
-      int offset = (is_method ? 1 : 0);
-      ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i);
-      switch (g_arg_info_get_direction (ainfo))
-       {
-       case GI_DIRECTION_IN:
-         tinfo = g_arg_info_get_type (ainfo);
-         atypes[i+offset] = g_type_info_get_ffi_type (tinfo);
-         g_base_info_unref ((GIBaseInfo *)tinfo);
-
-         if (in_pos >= n_in_args)
-           {
-             g_set_error (error,
-                          G_INVOKE_ERROR,
-                          G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-                          "Too few \"in\" arguments (handling in)");
-             goto out;
-           }
-
-         args[i+offset] = (gpointer)&in_args[in_pos];
-         in_pos++;
-
-         break;
-       case GI_DIRECTION_OUT:
-         atypes[i+offset] = &ffi_type_pointer;
-
-         if (out_pos >= n_out_args)
-           {
-             g_set_error (error,
-                          G_INVOKE_ERROR,
-                          G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-                          "Too few \"out\" arguments (handling out)");
-             goto out;
-           }
-
-         args[i+offset] = (gpointer)&out_args[out_pos];
-         out_pos++;
-         break;
-       case GI_DIRECTION_INOUT:
-         atypes[i+offset] = &ffi_type_pointer;
-
-         if (in_pos >= n_in_args)
-           {
-             g_set_error (error,
-                          G_INVOKE_ERROR,
-                          G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-                          "Too few \"in\" arguments (handling inout)");
-             goto out;
-           }
-
-         if (out_pos >= n_out_args)
-           {
-             g_set_error (error,
-                          G_INVOKE_ERROR,
-                          G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-                          "Too few \"out\" arguments (handling inout)");
-             goto out;
-           }
-
-         args[i+offset] = (gpointer)&in_args[in_pos];
-         in_pos++;
-         out_pos++;
-         break;
-       default:
-         g_assert_not_reached ();
-       }
-      g_base_info_unref ((GIBaseInfo *)ainfo);
-    }
-
-  if (throws)
-    {
-      args[n_invoke_args - 1] = &error_address;
-      atypes[n_invoke_args - 1] = &ffi_type_pointer;
-    }
-
-  if (in_pos < n_in_args)
-    {
-      g_set_error (error,
-                  G_INVOKE_ERROR,
-                  G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-                  "Too many \"in\" arguments (at end)");
-      goto out;
-    }
-  if (out_pos < n_out_args)
-    {
-      g_set_error (error,
-                  G_INVOKE_ERROR,
-                  G_INVOKE_ERROR_ARGUMENT_MISMATCH,
-                  "Too many \"out\" arguments (at end)");
-      goto out;
-    }
-
-  if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK)
-    goto out;
-
-  g_return_val_if_fail (return_value, FALSE);
-  ffi_call (&cif, func, return_value, args);
-
-  if (local_error)
-    {
-      g_propagate_error (error, local_error);
-      success = FALSE;
-    }
-  else
-    {
-      success = TRUE;
-    }
- out:
-  return success;
-}
-
 static ffi_type *
 value_to_ffi_type (const GValue *gvalue, gpointer *value)
 {