<pre style='margin:0'>
Michael Dickens (michaelld) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/36b3f88e0593140ae0f5639681f35a76b2a52c32">https://github.com/macports/macports-ports/commit/36b3f88e0593140ae0f5639681f35a76b2a52c32</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new 36b3f88e059 py-gobject3: add patch to address closure / tramp on ARM64
</span>36b3f88e059 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit 36b3f88e0593140ae0f5639681f35a76b2a52c32
</span>Author: Michael Dickens <michaelld@macports.org>
AuthorDate: Sat Sep 25 15:39:18 2021 -0400

<span style='display:block; white-space:pre;color:#404040;'>    py-gobject3: add patch to address closure / tramp on ARM64
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    NOTE: This patch is not official! It is a "best effort" workaround for the issue, and for the Python interface to GObject-Introspection only.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Closes: https://trac.macports.org/ticket/62180
</span>---
 python/py-gobject3/Portfile                        |   7 +-
 .../patch-pygobject_fix_arm64_closure_exec.diff    | 620 +++++++++++++++++++++
 2 files changed, 626 insertions(+), 1 deletion(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/python/py-gobject3/Portfile b/python/py-gobject3/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index acc66987b06..1f8af4ea942 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/python/py-gobject3/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/python/py-gobject3/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -7,7 +7,7 @@ PortGroup           meson 1.0
</span> name                py-gobject3
 set my_name         pygobject
 version             3.38.0
<span style='display:block; white-space:pre;background:#ffe0e0;'>-revision            1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision            2
</span> set branch          [join [lrange [split ${version} .] 0 1] .]
 categories-append   gnome
 license             LGPL-2.1+
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -39,6 +39,11 @@ if {${name} ne ${subport}} {
</span> 
     compiler.c_standard     2011
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    # https://github.com/Damenly/pygobject/commit/01013b1003bac67061e595cd857be9cf7b69d7fd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # this patch is designed to work around PyGObject's use of GOI's use of LIBFFI
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    patchfiles              patch-pygobject_fix_arm64_closure_exec.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    patch.pre_args -p1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>     use_configure           yes
 
     configure.pkg_config_path \
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/python/py-gobject3/files/patch-pygobject_fix_arm64_closure_exec.diff b/python/py-gobject3/files/patch-pygobject_fix_arm64_closure_exec.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..dbfc90aa770
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/python/py-gobject3/files/patch-pygobject_fix_arm64_closure_exec.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,620 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From 01013b1003bac67061e595cd857be9cf7b69d7fd Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Su Yue <l@damenly.su>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Fri, 3 Sep 2021 20:38:20 +0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] Hack for segmentation faults on Apple Silicon(Macos arm64)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+There are bugs in pyobject and gobject-introspection.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The API g_callable_info_prepare_closure() only returns the address
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+of exec not closure.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+On linux arm64 and x86_64 platforms, exec address is same as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+closure. However, on Macos arm64, it is not true. Then segmentation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fault happens while calling g_callable_info_free_closure() on exec ptr.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Try the C code:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+========================================================================
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void puts_binding(ffi_cif *cif, void *ret, void* args[],
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                  void *stream)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef int (*puts_t)(char *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int main()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ffi_cif cif;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ffi_type *args[1];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ffi_closure *closure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  void *bound_puts;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int rc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Allocate closure and bound_puts */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (closure)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      /* Initialize the argument info vectors */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      args[0] = &ffi_type_pointer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      /* Initialize the cif */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                       &ffi_type_sint, args) == FFI_OK)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          /* Initialize the closure, setting stream to stdout */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          if (ffi_prep_closure_loc(closure, &cif, puts_binding,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   stdout, bound_puts) == FFI_OK)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              rc = ((puts_t)bound_puts)("");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              /* rc now holds the result of the call to fputs */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  printf("closure:%p exec: %p\n", closure, bound_puts);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Deallocate both closure, and bound_puts */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ffi_closure_free(closure);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+========================================================================
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+I tried to fix it but there are some bugs in pyobject which also cause
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+segmentation faults.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+I'm not a pundit in these messy code so just do hacks in pyobject to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fix it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Link: https://gitlab.gnome.org/GNOME/pygobject/-/issues/455
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Link: https://github.com/jeffreywildman/homebrew-virt-manager/pull/166#issuecomment-911881113
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Signed-off-by: Su Yue <l@damenly.su>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gi/girffi_alter.h | 485 ++++++++++++++++++++++++++++++++++++++++++++++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gi/pygi-closure.c |  12 +-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gi/pygi-closure.h |   3 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 3 files changed, 496 insertions(+), 4 deletions(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ create mode 100644 gi/girffi_alter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/gi/girffi_alter.h b/gi/girffi_alter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 00000000..b8b7f2f0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/gi/girffi_alter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,485 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GObject introspection: Helper functions for ffi integration
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright (C) 2008 Red Hat, Inc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * This library is free software; you can redistribute it and/or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * modify it under the terms of the GNU Lesser General Public
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * License as published by the Free Software Foundation; either
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * version 2 of the License, or (at your option) any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * This library is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Lesser General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU Lesser General Public
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * License along with this library; if not, write to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02111-1307, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef __GIRFFI_ALTER_H__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define __GIRFFI_ALTER_H__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <ffi.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <girffi.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gitypes.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define INVALID_REFCOUNT 0x7FFFFFFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct _GITypelib {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  /* <private> */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guchar *data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gsize len;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gboolean owns_memory;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GMappedFile *mfile;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GList *modules;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gboolean open_attempted;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ffi_closure ffi_closure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gpointer writable_self;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++} GIClosureWrapper;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef void (*GIFFIClosureCallback) (ffi_cif *,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                      void *,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                      void **,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                      void *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct _GIRealInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  /* Keep this part in sync with GIUnresolvedInfo below */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gint32 type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  volatile gint ref_count;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GIRepository *repository;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GIBaseInfo *container;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  /* Resolved specific */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GITypelib *typelib;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 type_is_embedded : 1; /* Used by GITypeInfo */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 reserved : 31;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gpointer reserved2[4];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gchar   magic[16];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint8  major_version;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint8  minor_version;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 reserved;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 n_entries;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 n_local_entries;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 directory;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 n_attributes;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 attributes;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 dependencies;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 namespace;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 nsversion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 shared_library;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 c_prefix;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 entry_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 function_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 callback_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 signal_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 vfunc_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 arg_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 property_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 field_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 value_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 attribute_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 constant_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 error_domain_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 signature_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 enum_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 struct_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 object_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 interface_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 union_blob_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 sections;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 padding[6];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++} Header;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef struct _GIRealInfo GIRealInfo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * FunctionBlob:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @blob_type: #BLOB_TYPE_FUNCTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @deprecated: The function is deprecated.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @setter: The function is a setter for a property. Language bindings may
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   prefer to not bind individual setters and rely on the generic
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   g_object_set().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @getter: The function is a getter for a property. Language bindings may
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   prefer to not bind individual getters and rely on the generic
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   g_object_get().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @constructor: The function acts as a constructor for the object it is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   contained in.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @wraps_vfunc: The function is a simple wrapper for a virtual function.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @throws: This is now additionally stored in the #SignatureBlob. (deprecated)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @index: Index of the property that this function is a setter or getter of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   in the array of properties of the containing interface, or index
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   of the virtual function that this function wraps.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @name: TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @symbol: The symbol which can be used to obtain the function pointer with
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   dlsym().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @signature: Offset of the SignatureBlob describing the parameter types and the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   return value type.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @is_static: The function is a "static method"; in other words it's a pure
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   function whose name is conceptually scoped to the object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @reserved: Reserved for future use.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @reserved2: Reserved for future use.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 blob_type;  /* 1 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 deprecated  : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 setter      : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 getter      : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 constructor : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 wraps_vfunc : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 throws      : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 index       :10;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  /* Note the bits above need to match CommonBlob
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   * and are thus exhausted, extend things using
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   * the reserved block below. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 symbol;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 signature;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 is_static   : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 reserved    : 15;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 reserved2   : 16;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++} FunctionBlob;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 must_chain_up           : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 must_be_implemented     : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 must_not_be_implemented : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 class_closure           : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 throws                  : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 reserved                :11;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 signal;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 struct_offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 invoker : 10; /* Number of bits matches @index in FunctionBlob */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 reserved2 : 6;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 reserved3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 signature;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++} VFuncBlob;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 blob_type;  /* 2 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 deprecated : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 reserved   :15;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 signature;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++} CallbackBlob;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * SignalBlob:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @deprecated: TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @run_first: TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @run_last: TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @run_cleanup: TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @no_recurse: TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @detailed: TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @action: TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @no_hooks: The flags used when registering the signal.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @has_class_closure: Set if the signal has a class closure.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @true_stops_emit: Whether the signal has true-stops-emit semantics
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @reserved: Reserved for future use.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @class_closure: The index of the class closure in the list of virtual
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   functions of the object or interface on which the signal is defined.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @name: The name of the signal.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @reserved2: Reserved for future use.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @signature: Offset of the SignatureBlob describing the parameter types
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   and the return value type.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 deprecated        : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 run_first         : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 run_last          : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 run_cleanup       : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 no_recurse        : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 detailed          : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 action            : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 no_hooks          : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 has_class_closure : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 true_stops_emit   : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 reserved          : 6;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint16 class_closure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 reserved2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  guint32 signature;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++} SignalBlob;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static guint32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++signature_offset (GICallableInfo *info)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GIRealInfo *rinfo = (GIRealInfo*)info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int sigoff = -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  switch (rinfo->type)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case GI_INFO_TYPE_FUNCTION:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      sigoff = G_STRUCT_OFFSET (FunctionBlob, signature);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case GI_INFO_TYPE_VFUNC:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      sigoff = G_STRUCT_OFFSET (VFuncBlob, signature);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case GI_INFO_TYPE_CALLBACK:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      sigoff = G_STRUCT_OFFSET (CallbackBlob, signature);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case GI_INFO_TYPE_SIGNAL:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      sigoff = G_STRUCT_OFFSET (SignalBlob, signature);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      g_assert_not_reached ();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (sigoff >= 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return *(guint32 *)&rinfo->typelib->data[rinfo->offset + sigoff];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++_g_info_init (GIRealInfo     *info,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              GIInfoType      type,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              GIRepository   *repository,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              GIBaseInfo     *container,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              GITypelib       *typelib,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              guint32         offset)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  memset (info, 0, sizeof (GIRealInfo));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  /* Invalid refcount used to flag stack-allocated infos */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  info->ref_count = INVALID_REFCOUNT;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  info->type = type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  info->typelib = typelib;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  info->offset = offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (container)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    info->container = container;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  g_assert (G_IS_IREPOSITORY (repository));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  info->repository = repository;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * g_callable_info_load_arg:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @info: a #GICallableInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @n: the argument index to fetch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @arg: (out caller-allocates): Initialize with argument number @n
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Obtain information about a particular argument of this callable; this
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * function is a variant of g_callable_info_get_arg() designed for stack
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * allocation.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * The initialized @arg must not be referenced after @info is deallocated.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++g_callable_info_load_arg (GICallableInfo *info,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          gint            n,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          GIArgInfo      *arg)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GIRealInfo *rinfo = (GIRealInfo *)info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  Header *header;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gint offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  g_return_if_fail (info != NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  g_return_if_fail (GI_IS_CALLABLE_INFO (info));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  offset = signature_offset (info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  header = (Header *)rinfo->typelib->data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                offset + header->signature_blob_size + n * header->arg_blob_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * g_callable_info_get_ffi_arg_types:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @callable_info: a callable info from a typelib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @n_args_p: (out): The number of arguments
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Returns: an array of ffi_type*. The array itself
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * should be freed using g_free() after use.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static ffi_type **
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                   int            *n_args_p)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ffi_type **arg_types;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    gboolean is_method, throws;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    gint n_args, n_invoke_args, i, offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    g_return_val_if_fail (callable_info != NULL, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    n_args = g_callable_info_get_n_args (callable_info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    is_method = g_callable_info_is_method (callable_info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    throws = g_callable_info_can_throw_gerror (callable_info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    offset = is_method ? 1 : 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    n_invoke_args = n_args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (is_method)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      n_invoke_args++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (throws)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      n_invoke_args++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (n_args_p)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      *n_args_p = n_invoke_args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    arg_types = (ffi_type **) g_new0 (ffi_type *, n_invoke_args + 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (is_method)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      arg_types[0] = &ffi_type_pointer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (throws)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      arg_types[n_invoke_args - 1] = &ffi_type_pointer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    for (i = 0; i < n_args; ++i)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        GIArgInfo arg_info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        GITypeInfo arg_type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        g_callable_info_load_arg (callable_info, i, &arg_info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        g_arg_info_load_type (&arg_info, &arg_type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        switch (g_arg_info_get_direction (&arg_info))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            case GI_DIRECTION_IN:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              arg_types[i + offset] = g_type_info_get_ffi_type (&arg_type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            case GI_DIRECTION_OUT:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            case GI_DIRECTION_INOUT:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              arg_types[i + offset] = &ffi_type_pointer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              g_assert_not_reached ();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    arg_types[n_invoke_args] = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return arg_types;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * g_callable_info_get_ffi_return_type:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @callable_info: a callable info from a typelib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Fetches the ffi_type for a corresponding return value of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * a #GICallableInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Returns: the ffi_type for the return value
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static ffi_type *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++g_callable_info_get_ffi_return_type (GICallableInfo *callable_info)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GITypeInfo *return_type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ffi_type *return_ffi_type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  g_return_val_if_fail (callable_info != NULL, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return_type = g_callable_info_get_return_type (callable_info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return_ffi_type = g_type_info_get_ffi_type (return_type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  g_base_info_unref((GIBaseInfo*)return_type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return return_ffi_type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * g_callable_info_prepare_closure:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @callable_info: a callable info from a typelib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @cif: a ffi_cif structure
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @callback: the ffi callback
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @user_data: data to be passed into the callback
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @exec_ret: if no NULL, return with exec address
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Prepares a callback for ffi invocation.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Used for arm64(Apple Silicon).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Returns: the ffi_closure or NULL on error. The return value
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *     should be freed by calling g_callable_info_free_closure().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ffi_closure *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++g_callable_info_prepare_closure_v2 (GICallableInfo       *callable_info,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                              ffi_cif              *cif,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                              GIFFIClosureCallback  callback,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                              gpointer              user_data,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                              gpointer              *exec_ret)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gpointer exec_ptr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int n_args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ffi_type **atypes;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  GIClosureWrapper *closure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ffi_status status;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (callable_info == NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (cif == NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (callback == NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  closure = ffi_closure_alloc (sizeof (GIClosureWrapper), &exec_ptr);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (!closure)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      g_warning ("could not allocate closure\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  closure->writable_self = closure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  atypes = g_callable_info_get_ffi_arg_types (callable_info, &n_args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, n_args,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                         g_callable_info_get_ffi_return_type (callable_info),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                         atypes);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (status != FFI_OK)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      g_warning ("ffi_prep_cif failed: %d\n", status);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      ffi_closure_free (closure);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  status = ffi_prep_closure_loc (&closure->ffi_closure, cif, callback, user_data, exec_ptr);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (status != FFI_OK)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      g_warning ("ffi_prep_closure failed: %d\n", status);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      ffi_closure_free (closure);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (exec_ret)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    *exec_ret = exec_ptr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  /* For Macos arm64, the underlying memory is no sam as closure,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   * calling g_callable_info_free_closure() on it will cause a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   * segmentation fault.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return (ffi_closure *)closure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif /* __GIRFFI_ALTER_H__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 136eec64..49c425ae 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/gi/pygi-closure.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/gi/pygi-closure.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -23,6 +23,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "pygi-invoke.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "pygi-ccallback.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "pygi-info.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "girffi_alter.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ extern PyObject *_PyGIDefaultArgPlaceholder;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -633,7 +634,7 @@ void _pygi_invoke_closure_free (gpointer data)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyGICClosure* invoke_closure = (PyGICClosure *) data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     g_callable_info_free_closure (invoke_closure->info,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  invoke_closure->closure);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  invoke_closure->func);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (invoke_closure->info)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         g_base_info_unref ( (GIBaseInfo*) invoke_closure->info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -671,9 +672,12 @@ _pygi_make_native_closure (GICallableInfo* info,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     Py_XINCREF (closure->user_data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     fficlosure =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        g_callable_info_prepare_closure (info, &closure->cif, _pygi_closure_handle,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                         closure);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    closure->closure = fficlosure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        g_callable_info_prepare_closure_v2 (info, &closure->cif, _pygi_closure_handle,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                         closure, &closure->func);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    /* temp fix */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    closure->closure = closure->func;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    closure->func = fficlosure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* Give the closure the information it needs to determine when
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        to free itself later */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/gi/pygi-closure.h b/gi/pygi-closure.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 30da2cf7..99173ca0 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/gi/pygi-closure.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/gi/pygi-closure.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -35,6 +35,9 @@ typedef struct _PyGICClosure
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject *function;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     ffi_closure *closure;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    void *func;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     ffi_cif cif;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     GIScopeType scope;
</span></pre><pre style='margin:0'>

</pre>