<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>