Skip to content

Instantly share code, notes, and snippets.

@satori99
Forked from kleisauke/Dockerfile
Created June 4, 2021 11:58
Show Gist options
  • Select an option

  • Save satori99/d0ced83bba3133a51a1800390f5f6b27 to your computer and use it in GitHub Desktop.

Select an option

Save satori99/d0ced83bba3133a51a1800390f5f6b27 to your computer and use it in GitHub Desktop.

Revisions

  1. @kleisauke kleisauke revised this gist May 25, 2021. 3 changed files with 61 additions and 40 deletions.
    2 changes: 1 addition & 1 deletion Dockerfile
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    FROM emscripten/emsdk:2.0.20
    FROM emscripten/emsdk:2.0.21

    RUN apt-get update \
    && apt-get install -qqy \
    39 changes: 30 additions & 9 deletions glib-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 14:00:00 +0200
    Subject: [PATCH 1/10] Revert "Meson: Extract objects from convenience libraries
    Subject: [PATCH 1/11] Revert "Meson: Extract objects from convenience libraries
    to link them"

    This reverts commit 62af03bda8a1d649b079a0e77d3687695d0ab7d3.
    @@ -140,7 +140,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 30 Sep 2020 14:00:00 +0200
    Subject: [PATCH 2/10] Explicitly link gio and gobject against pthread
    Subject: [PATCH 2/11] Explicitly link gio and gobject against pthread

    To ensure that the compiled code uses the "atomics" target feature of WASM.

    @@ -177,7 +177,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:00:00 +0200
    Subject: [PATCH 3/10] LLVM doesn't define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
    Subject: [PATCH 3/11] LLVM doesn't define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4

    See: https://bugs.llvm.org/show_bug.cgi?id=11174

    @@ -200,7 +200,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:20:00 +0200
    Subject: [PATCH 4/10] posix_spawn isn't usable in WASM
    Subject: [PATCH 4/11] posix_spawn isn't usable in WASM

    Upstream-Status: Pending

    @@ -220,7 +220,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:40:00 +0200
    Subject: [PATCH 5/10] Network libs are not available in WASM
    Subject: [PATCH 5/11] Network libs are not available in WASM

    Upstream-Status: Pending

    @@ -241,7 +241,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 22 Apr 2020 12:11:28 +0200
    Subject: [PATCH 6/10] Ensure separate checks are also done for Emscripten
    Subject: [PATCH 6/11] Ensure separate checks are also done for Emscripten

    Upstream-Status: Pending

    @@ -279,7 +279,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Tue, 13 Apr 2021 15:30:00 +0200
    Subject: [PATCH 7/10] Use vsnpintf/snprintf/printf from musl libc
    Subject: [PATCH 7/11] Use vsnpintf/snprintf/printf from musl libc

    The C99 semantics of these functions is well supported in musl libc.

    @@ -306,7 +306,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 15 Nov 2019 11:00:00 +0100
    Subject: [PATCH 8/10] Implement g_get_num_processors for Emscripten
    Subject: [PATCH 8/11] Implement g_get_num_processors for Emscripten

    Upstream-Status: Pending

    @@ -337,10 +337,31 @@ index 1111111..2222222 100644
    SYSTEM_INFO sysinfo;
    DWORD_PTR process_cpus;

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Tue, 25 May 2021 11:00:00 +0200
    Subject: [PATCH 9/11] Disable GModule implementation on Emscripten

    Upstream-Status: Pending

    diff --git a/gmodule/meson.build b/gmodule/meson.build
    index 1111111..2222222 100644
    --- a/gmodule/meson.build
    +++ b/gmodule/meson.build
    @@ -13,7 +13,8 @@ if host_system == 'windows'
    # dlopen() filepath must be of the form /path/libname.a(libname.so)
    elif host_system == 'aix'
    g_module_impl = 'G_MODULE_IMPL_AR'
    -elif have_dlopen_dlsym
    +# Dynamic linking should be avoided whenever possible on Emscripten
    +elif have_dlopen_dlsym and host_system != 'emscripten'
    g_module_impl = 'G_MODULE_IMPL_DL'
    endif

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Tue, 8 Oct 2019 11:30:00 +0200
    Subject: [PATCH 9/10] Do not build executables
    Subject: [PATCH 10/11] Do not build executables

    We're only interested in the libraries.

    60 changes: 30 additions & 30 deletions glib-function-pointers.patch
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 20 Sep 2019 16:05:00 +0200
    Subject: [PATCH 10/10] Fix function pointer cast issues
    Subject: [PATCH 11/11] Fix function pointer cast issues

    It is undefined behavior in C and C++ to cast a function pointer
    to another type and call it that way. This does work in most native
    @@ -2150,7 +2150,7 @@ index 1111111..2222222 100644
    static void g_object_base_class_finalize (GObjectClass *class);
    -static void g_object_do_class_init (GObjectClass *class);
    +static void g_object_do_class_init (GObjectClass *class,
    + gpointer dummy);
    + gpointer class_data);
    static void g_object_init (GObject *object,
    GObjectClass *class);
    static GObject* g_object_constructor (GType type,
    @@ -2160,7 +2160,7 @@ index 1111111..2222222 100644
    static void
    -g_object_do_class_init (GObjectClass *class)
    +g_object_do_class_init (GObjectClass *class,
    + gpointer dummy)
    + gpointer class_data)
    {
    /* read the comment about typedef struct CArray; on why not to change this quark */
    quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
    @@ -2174,7 +2174,7 @@ index 1111111..2222222 100644
    guint16 n_preallocs; /* optional */
    - void (*instance_init) (GParamSpec *pspec); /* optional */
    + void (*instance_init) (GParamSpec *pspec, /* optional */
    + gpointer data);
    + gpointer class_data);

    /* class portion */
    GType value_type; /* obligatory */
    @@ -2188,7 +2188,7 @@ index 1111111..2222222 100644
    static void
    -param_char_init (GParamSpec *pspec)
    +param_char_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);

    @@ -2198,7 +2198,7 @@ index 1111111..2222222 100644
    static void
    -param_uchar_init (GParamSpec *pspec)
    +param_uchar_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);

    @@ -2208,7 +2208,7 @@ index 1111111..2222222 100644
    static void
    -param_int_init (GParamSpec *pspec)
    +param_int_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);

    @@ -2218,7 +2218,7 @@ index 1111111..2222222 100644
    static void
    -param_uint_init (GParamSpec *pspec)
    +param_uint_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);

    @@ -2228,7 +2228,7 @@ index 1111111..2222222 100644
    static void
    -param_long_init (GParamSpec *pspec)
    +param_long_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);

    @@ -2238,7 +2238,7 @@ index 1111111..2222222 100644
    static void
    -param_ulong_init (GParamSpec *pspec)
    +param_ulong_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);

    @@ -2248,7 +2248,7 @@ index 1111111..2222222 100644
    static void
    -param_int64_init (GParamSpec *pspec)
    +param_int64_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);

    @@ -2258,7 +2258,7 @@ index 1111111..2222222 100644
    static void
    -param_uint64_init (GParamSpec *pspec)
    +param_uint64_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);

    @@ -2268,7 +2268,7 @@ index 1111111..2222222 100644
    static void
    -param_unichar_init (GParamSpec *pspec)
    +param_unichar_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);

    @@ -2278,7 +2278,7 @@ index 1111111..2222222 100644
    static void
    -param_enum_init (GParamSpec *pspec)
    +param_enum_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);

    @@ -2288,7 +2288,7 @@ index 1111111..2222222 100644
    static void
    -param_flags_init (GParamSpec *pspec)
    +param_flags_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);

    @@ -2298,7 +2298,7 @@ index 1111111..2222222 100644
    static void
    -param_float_init (GParamSpec *pspec)
    +param_float_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);

    @@ -2308,7 +2308,7 @@ index 1111111..2222222 100644
    static void
    -param_double_init (GParamSpec *pspec)
    +param_double_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);

    @@ -2318,7 +2318,7 @@ index 1111111..2222222 100644
    static void
    -param_string_init (GParamSpec *pspec)
    +param_string_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);

    @@ -2328,7 +2328,7 @@ index 1111111..2222222 100644
    static void
    -param_param_init (GParamSpec *pspec)
    +param_param_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
    }
    @@ -2338,7 +2338,7 @@ index 1111111..2222222 100644
    static void
    -param_boxed_init (GParamSpec *pspec)
    +param_boxed_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
    }
    @@ -2348,7 +2348,7 @@ index 1111111..2222222 100644
    static void
    -param_pointer_init (GParamSpec *pspec)
    +param_pointer_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
    }
    @@ -2358,7 +2358,7 @@ index 1111111..2222222 100644
    static void
    -param_value_array_init (GParamSpec *pspec)
    +param_value_array_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);

    @@ -2368,7 +2368,7 @@ index 1111111..2222222 100644
    static void
    -param_object_init (GParamSpec *pspec)
    +param_object_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
    }
    @@ -2378,7 +2378,7 @@ index 1111111..2222222 100644
    static void
    -param_override_init (GParamSpec *pspec)
    +param_override_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
    }
    @@ -2388,7 +2388,7 @@ index 1111111..2222222 100644
    static void
    -param_gtype_init (GParamSpec *pspec)
    +param_gtype_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    }

    @@ -2398,7 +2398,7 @@ index 1111111..2222222 100644
    static void
    -param_variant_init (GParamSpec *pspec)
    +param_variant_init (GParamSpec *pspec,
    + gpointer dummy)
    + gpointer class_data)
    {
    GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);

    @@ -2421,7 +2421,7 @@ index 1111111..2222222 100644
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    -static void type_name##_class_intern_init (gpointer klass) \
    +static void type_name##_class_intern_init (gpointer klass, \
    + gpointer dummy) \
    + gpointer class_data) \
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    if (TypeName##_private_offset != 0) \
    @@ -2431,7 +2431,7 @@ index 1111111..2222222 100644
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    -static void type_name##_class_intern_init (gpointer klass) \
    +static void type_name##_class_intern_init (gpointer klass, \
    + gpointer dummy) \
    + gpointer class_data) \
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    type_name##_class_init ((TypeName##Class*) klass); \
    @@ -2440,7 +2440,7 @@ index 1111111..2222222 100644
    static void type_name##_init (TypeName *self); \
    static void type_name##_class_init (TypeName##Class *klass); \
    +static void type_name##_init_adapter (TypeName *self, \
    + gpointer dummy) \
    + gpointer class_data) \
    +{ \
    + type_name##_init (self); \
    +} \
    @@ -2466,7 +2466,7 @@ index 1111111..2222222 100644
    -static void type_name##_default_init (TypeName##Interface *klass); \
    +static void type_name##_default_init (TypeName##Interface *klass); \
    +static void type_name##_default_init_adapter (TypeName##Interface *klass, \
    + gpointer dummy) \
    + gpointer class_data) \
    +{ \
    + type_name##_default_init (klass); \
    +} \
  2. @kleisauke kleisauke revised this gist May 21, 2021. 1 changed file with 19 additions and 3 deletions.
    22 changes: 19 additions & 3 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -10,13 +10,29 @@ rm -rf $DEPS/
    mkdir $DEPS
    mkdir -p $TARGET

    # Define default arguments

    # JS BigInt to Wasm i64 integration, disabled by default
    WASM_BIGINT_FLAG=

    # Parse arguments
    while [ $# -gt 0 ]; do
    case $1 in
    --enable-wasm-bigint) WASM_BIGINT_FLAG="-s WASM_BIGINT" ;;
    *) echo "ERROR: Unknown parameter: $1" >&2; exit 1 ;;
    esac
    shift
    done

    # Get emscripten crossfile
    curl -Ls -o $SOURCE_DIR/emscripten-crossfile.meson https://github.com/kleisauke/wasm-vips/raw/vips-8.11/build/emscripten-crossfile.meson

    # Common compiler flags
    export CFLAGS="-O3"
    if [ -n "$WASM_BIGINT_FLAG" ]; then export CFLAGS+=" -DWASM_BIGINT"; fi
    export CXXFLAGS="$CFLAGS"
    export LDFLAGS="-L$TARGET/lib -O3"
    if [ -n "$WASM_BIGINT_FLAG" ]; then export EMMAKEN_CFLAGS="$WASM_BIGINT_FLAG"; fi

    # Build paths
    export CPATH="$TARGET/include"
    @@ -45,7 +61,7 @@ mkdir $DEPS/zlib
    curl -Ls http://zlib.net/zlib-$VERSION_ZLIB.tar.xz | tar xJC $DEPS/zlib --strip-components=1
    cd $DEPS/zlib
    emconfigure ./configure --prefix=$TARGET --static
    emmake make install
    make install

    mkdir $DEPS/ffi
    curl -Ls https://sourceware.org/pub/libffi/libffi-$VERSION_FFI.tar.gz | tar xzC $DEPS/ffi --strip-components=1
    @@ -54,7 +70,7 @@ curl -Ls $PATCH_FFI | patch -p1
    autoreconf -fiv
    emconfigure ./configure --host=$CHOST --prefix=$TARGET --enable-static --disable-shared --disable-dependency-tracking \
    --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-structs
    emmake make install
    make install

    mkdir $DEPS/glib
    curl -Lks https://download.gnome.org/sources/glib/$(without_patch $VERSION_GLIB)/glib-$VERSION_GLIB.tar.xz | tar xJC $DEPS/glib --strip-components=1
    @@ -64,4 +80,4 @@ curl -Ls $PATCH_GLIB_2 | patch -p1
    meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \
    -Diconv="libc" -Dselinux=disabled -Dxattr=false -Dlibmount=disabled -Dnls=disabled -Dinternal_pcre=true \
    -Dtests=false -Dglib_assert=false -Dglib_checks=false
    emmake ninja -C _build install
    ninja -C _build install
  3. @kleisauke kleisauke revised this gist May 15, 2021. 4 changed files with 2565 additions and 317 deletions.
    6 changes: 5 additions & 1 deletion Dockerfile
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    FROM emscripten/emsdk:2.0.15
    FROM emscripten/emsdk:2.0.20

    RUN apt-get update \
    && apt-get install -qqy \
    @@ -12,3 +12,7 @@ RUN apt-get update \
    ninja-build \
    python3-pip \
    && pip3 install meson

    ARG MESON_PATCH=https://github.com/kleisauke/wasm-vips/raw/vips-8.11/build/patches/meson-emscripten.patch
    RUN cd $(dirname `python3 -c "import mesonbuild as _; print(_.__path__[0])"`) \
    && curl -Ls $MESON_PATCH | patch -p1
    10 changes: 6 additions & 4 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,7 @@ mkdir $DEPS
    mkdir -p $TARGET

    # Get emscripten crossfile
    curl -Ls -o $SOURCE_DIR/emscripten-crossfile.meson https://github.com/kleisauke/wasm-vips/raw/master/build/emscripten-crossfile.meson
    curl -Ls -o $SOURCE_DIR/emscripten-crossfile.meson https://github.com/kleisauke/wasm-vips/raw/vips-8.11/build/emscripten-crossfile.meson

    # Common compiler flags
    export CFLAGS="-O3"
    @@ -29,11 +29,12 @@ export MESON_CROSS="$SOURCE_DIR/emscripten-crossfile.meson"
    # Dependency version numbers
    VERSION_ZLIB=1.2.11
    VERSION_FFI=3.3
    VERSION_GLIB=2.68.0
    VERSION_GLIB=2.68.2

    # Patches
    PATCH_GLIB=https://github.com/kleisauke/wasm-vips/raw/master/build/patches/glib-emscripten.patch
    PATCH_FFI=https://github.com/kleisauke/wasm-vips/raw/master/build/patches/libffi-emscripten.patch
    PATCH_GLIB=https://github.com/kleisauke/wasm-vips/raw/vips-8.11/build/patches/glib-emscripten.patch
    PATCH_GLIB_2=https://github.com/kleisauke/wasm-vips/raw/vips-8.11/build/patches/glib-function-pointers.patch
    PATCH_FFI=https://github.com/kleisauke/wasm-vips/raw/vips-8.11/build/patches/libffi-emscripten.patch

    # Remove patch version component
    without_patch() {
    @@ -59,6 +60,7 @@ mkdir $DEPS/glib
    curl -Lks https://download.gnome.org/sources/glib/$(without_patch $VERSION_GLIB)/glib-$VERSION_GLIB.tar.xz | tar xJC $DEPS/glib --strip-components=1
    cd $DEPS/glib
    curl -Ls $PATCH_GLIB | patch -p1
    curl -Ls $PATCH_GLIB_2 | patch -p1
    meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \
    -Diconv="libc" -Dselinux=disabled -Dxattr=false -Dlibmount=disabled -Dnls=disabled -Dinternal_pcre=true \
    -Dtests=false -Dglib_assert=false -Dglib_checks=false
    339 changes: 27 additions & 312 deletions glib-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 14:00:00 +0200
    Subject: [PATCH 1/9] Revert "Meson: Extract objects from convenience libraries
    Subject: [PATCH 1/10] Revert "Meson: Extract objects from convenience libraries
    to link them"

    This reverts commit 62af03bda8a1d649b079a0e77d3687695d0ab7d3.
    @@ -140,7 +140,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 30 Sep 2020 14:00:00 +0200
    Subject: [PATCH 2/9] Explicitly link gio and gobject against pthread
    Subject: [PATCH 2/10] Explicitly link gio and gobject against pthread

    To ensure that the compiled code uses the "atomics" target feature of WASM.

    @@ -177,7 +177,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:00:00 +0200
    Subject: [PATCH 3/9] LLVM doesn't define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
    Subject: [PATCH 3/10] LLVM doesn't define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4

    See: https://bugs.llvm.org/show_bug.cgi?id=11174

    @@ -200,7 +200,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:20:00 +0200
    Subject: [PATCH 4/9] posix_spawn isn't usable in WASM
    Subject: [PATCH 4/10] posix_spawn isn't usable in WASM

    Upstream-Status: Pending

    @@ -220,7 +220,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:40:00 +0200
    Subject: [PATCH 5/9] Network libs are not available in WASM
    Subject: [PATCH 5/10] Network libs are not available in WASM

    Upstream-Status: Pending

    @@ -241,7 +241,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 22 Apr 2020 12:11:28 +0200
    Subject: [PATCH 6/9] Ensure separate checks are also done for Emscripten
    Subject: [PATCH 6/10] Ensure separate checks are also done for Emscripten

    Upstream-Status: Pending

    @@ -278,320 +278,35 @@ index 1111111..2222222 100644

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 20 Sep 2019 16:05:00 +0200
    Subject: [PATCH 7/9] Fix function pointer cast issues
    Date: Tue, 13 Apr 2021 15:30:00 +0200
    Subject: [PATCH 7/10] Use vsnpintf/snprintf/printf from musl libc

    It is undefined behavior in C and C++ to cast a function pointer
    to another type and call it that way. This does work in most native
    platforms, however, despite it being UB, but in WASM it can fail.

    See:
    https://emscripten.org/docs/porting/guidelines/function_pointer_issues.html
    The C99 semantics of these functions is well supported in musl libc.

    Upstream-Status: Pending

    diff --git a/gobject/gobject.c b/gobject/gobject.c
    index 1111111..2222222 100644
    --- a/gobject/gobject.c
    +++ b/gobject/gobject.c
    @@ -189,7 +189,8 @@ G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, qdata) == G_STRUCT_OFFSET(GObjectReal,
    /* --- prototypes --- */
    static void g_object_base_class_init (GObjectClass *class);
    static void g_object_base_class_finalize (GObjectClass *class);
    -static void g_object_do_class_init (GObjectClass *class);
    +static void g_object_do_class_init (GObjectClass *class,
    + gpointer dummy);
    static void g_object_init (GObject *object,
    GObjectClass *class);
    static GObject* g_object_constructor (GType type,
    @@ -496,7 +497,7 @@ g_object_base_class_finalize (GObjectClass *class)
    }

    static void
    -g_object_do_class_init (GObjectClass *class)
    +g_object_do_class_init (GObjectClass *class, gpointer dummy)
    {
    /* read the comment about typedef struct CArray; on why not to change this quark */
    quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
    diff --git a/gobject/gparam.h b/gobject/gparam.h
    index 1111111..2222222 100644
    --- a/gobject/gparam.h
    +++ b/gobject/gparam.h
    @@ -378,7 +378,8 @@ struct _GParamSpecTypeInfo
    /* type system portion */
    guint16 instance_size; /* obligatory */
    guint16 n_preallocs; /* optional */
    - void (*instance_init) (GParamSpec *pspec); /* optional */
    + void (*instance_init) (GParamSpec *pspec, /* optional */
    + gpointer data);

    /* class portion */
    GType value_type; /* obligatory */
    diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c
    index 1111111..2222222 100644
    --- a/gobject/gparamspecs.c
    +++ b/gobject/gparamspecs.c
    @@ -61,7 +61,7 @@

    /* --- param spec functions --- */
    static void
    -param_char_init (GParamSpec *pspec)
    +param_char_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);

    @@ -90,7 +90,7 @@ param_char_validate (GParamSpec *pspec,
    }

    static void
    -param_uchar_init (GParamSpec *pspec)
    +param_uchar_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);

    @@ -137,7 +137,7 @@ param_boolean_validate (GParamSpec *pspec,
    }

    static void
    -param_int_init (GParamSpec *pspec)
    +param_int_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);

    @@ -177,7 +177,7 @@ param_int_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_uint_init (GParamSpec *pspec)
    +param_uint_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);

    @@ -217,7 +217,7 @@ param_uint_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_long_init (GParamSpec *pspec)
    +param_long_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);

    @@ -262,7 +262,7 @@ param_long_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_ulong_init (GParamSpec *pspec)
    +param_ulong_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);

    @@ -306,7 +306,7 @@ param_ulong_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_int64_init (GParamSpec *pspec)
    +param_int64_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);

    @@ -346,7 +346,7 @@ param_int64_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_uint64_init (GParamSpec *pspec)
    +param_uint64_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);

    @@ -386,7 +386,7 @@ param_uint64_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_unichar_init (GParamSpec *pspec)
    +param_unichar_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);

    @@ -428,7 +428,7 @@ param_unichar_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_enum_init (GParamSpec *pspec)
    +param_enum_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);

    @@ -473,7 +473,7 @@ param_enum_validate (GParamSpec *pspec,
    }

    static void
    -param_flags_init (GParamSpec *pspec)
    +param_flags_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);

    @@ -519,7 +519,7 @@ param_flags_validate (GParamSpec *pspec,
    }

    static void
    -param_float_init (GParamSpec *pspec)
    +param_float_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);

    @@ -562,7 +562,7 @@ param_float_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_double_init (GParamSpec *pspec)
    +param_double_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);

    @@ -605,7 +605,7 @@ param_double_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_string_init (GParamSpec *pspec)
    +param_string_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);

    @@ -713,7 +713,7 @@ param_string_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_param_init (GParamSpec *pspec)
    +param_param_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
    }
    @@ -744,7 +744,7 @@ param_param_validate (GParamSpec *pspec,
    }

    static void
    -param_boxed_init (GParamSpec *pspec)
    +param_boxed_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
    }
    @@ -782,7 +782,7 @@ param_boxed_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_pointer_init (GParamSpec *pspec)
    +param_pointer_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
    }
    @@ -818,7 +818,7 @@ param_pointer_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_value_array_init (GParamSpec *pspec)
    +param_value_array_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);

    @@ -969,7 +969,7 @@ param_value_array_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_object_init (GParamSpec *pspec)
    +param_object_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
    }
    @@ -1013,7 +1013,7 @@ param_object_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_override_init (GParamSpec *pspec)
    +param_override_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
    }
    @@ -1062,7 +1062,7 @@ param_override_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_gtype_init (GParamSpec *pspec)
    +param_gtype_init (GParamSpec *pspec, gpointer dummy)
    {
    }

    @@ -1106,7 +1106,7 @@ param_gtype_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_variant_init (GParamSpec *pspec)
    +param_variant_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);

    diff --git a/gobject/gtype.h b/gobject/gtype.h
    index 1111111..2222222 100644
    --- a/gobject/gtype.h
    +++ b/gobject/gtype.h
    @@ -1957,7 +1957,8 @@ guint g_type_get_type_registration_serial (void);
    */
    #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    -static void type_name##_class_intern_init (gpointer klass) \
    +static void type_name##_class_intern_init (gpointer klass, \
    + gpointer dummy) \
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    if (TypeName##_private_offset != 0) \
    @@ -1967,7 +1968,8 @@ static void type_name##_class_intern_init (gpointer klass) \

    #else
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    -static void type_name##_class_intern_init (gpointer klass) \
    +static void type_name##_class_intern_init (gpointer klass, \
    + gpointer dummy) \
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    type_name##_class_init ((TypeName##Class*) klass); \
    @@ -1979,6 +1981,11 @@ static void type_name##_class_intern_init (gpointer klass) \
    \
    static void type_name##_init (TypeName *self); \
    static void type_name##_class_init (TypeName##Class *klass); \
    +static void type_name##_init_adapter (TypeName *self, \
    + gpointer dummy) \
    +{ \
    + type_name##_init (self); \
    +} \
    static GType type_name##_get_type_once (void); \
    static gpointer type_name##_parent_class = NULL; \
    static gint TypeName##_private_offset; \
    @@ -2018,7 +2025,7 @@ type_name##_get_type_once (void) \
    sizeof (TypeName##Class), \
    (GClassInitFunc)(void (*)(void)) type_name##_class_intern_init, \
    sizeof (TypeName), \
    - (GInstanceInitFunc)(void (*)(void)) type_name##_init, \
    + (GInstanceInitFunc)(void (*)(void)) type_name##_init_adapter, \
    (GTypeFlags) flags); \
    { /* custom code follows */
    #define _G_DEFINE_TYPE_EXTENDED_END() \
    diff --git a/gobject/gtypemodule.h b/gobject/gtypemodule.h
    diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/gobject/gtypemodule.h
    +++ b/gobject/gtypemodule.h
    @@ -209,7 +209,7 @@ type_name##_register_type (GTypeModule *type_module) \
    NULL, /* class_data */ \
    sizeof (TypeName), \
    0, /* n_preallocs */ \
    - (GInstanceInitFunc)(void (*)(void)) type_name##_init, \
    + (GInstanceInitFunc)(void (*)(void)) type_name##_init_adapter, \
    NULL /* value_table */ \
    }; \
    type_name##_type_id = g_type_module_register_type (type_module, \
    --- a/meson.build
    +++ b/meson.build
    @@ -944,9 +944,9 @@ if host_system == 'windows' and (cc.get_id() == 'msvc' or cc.get_id() == 'clang-
    glib_conf.set('HAVE_C99_SNPRINTF', false)
    glib_conf.set('HAVE_C99_VSNPRINTF', false)
    glib_conf.set('HAVE_UNIX98_PRINTF', false)
    -elif not cc_can_run and host_system in ['ios', 'darwin']
    - # All these are true when compiling natively on macOS, so we should use good
    - # defaults when building for iOS and tvOS.
    +elif not cc_can_run and host_system in ['ios', 'darwin', 'emscripten']
    + # All these are true when compiling natively on macOS, or when compiling with
    + # Emscripten (which uses musl libc internally).
    glib_conf.set('HAVE_C99_SNPRINTF', true)
    glib_conf.set('HAVE_C99_VSNPRINTF', true)
    glib_conf.set('HAVE_UNIX98_PRINTF', true)

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 15 Nov 2019 11:00:00 +0100
    Subject: [PATCH 8/9] Implement g_get_num_processors for Emscripten
    Subject: [PATCH 8/10] Implement g_get_num_processors for Emscripten

    Upstream-Status: Pending

    @@ -625,7 +340,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Tue, 8 Oct 2019 11:30:00 +0200
    Subject: [PATCH 9/9] Do not build executables
    Subject: [PATCH 9/10] Do not build executables

    We're only interested in the libraries.

    2,527 changes: 2,527 additions & 0 deletions glib-function-pointers.patch
    2,527 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
  4. @kleisauke kleisauke revised this gist Mar 19, 2021. 4 changed files with 22 additions and 21 deletions.
    2 changes: 1 addition & 1 deletion Dockerfile
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    FROM emscripten/emsdk:2.0.12
    FROM emscripten/emsdk:2.0.15

    RUN apt-get update \
    && apt-get install -qqy \
    2 changes: 1 addition & 1 deletion build.sh
    Original file line number Diff line number Diff line change
    @@ -29,7 +29,7 @@ export MESON_CROSS="$SOURCE_DIR/emscripten-crossfile.meson"
    # Dependency version numbers
    VERSION_ZLIB=1.2.11
    VERSION_FFI=3.3
    VERSION_GLIB=2.67.2
    VERSION_GLIB=2.68.0

    # Patches
    PATCH_GLIB=https://github.com/kleisauke/wasm-vips/raw/master/build/patches/glib-emscripten.patch
    35 changes: 18 additions & 17 deletions glib-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,8 @@
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 14:00:00 +0200
    Subject: [PATCH 1/8] Revert "Meson: Extract objects from convenience libraries to
    link them"
    Subject: [PATCH 1/9] Revert "Meson: Extract objects from convenience libraries
    to link them"

    This reverts commit 62af03bda8a1d649b079a0e77d3687695d0ab7d3.

    @@ -13,7 +13,7 @@ diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -337,12 +337,6 @@ local_sources = files(
    @@ -341,12 +341,6 @@ local_sources = files(

    platform_deps = []
    internal_deps = []
    @@ -26,15 +26,15 @@ index 1111111..2222222 100644
    appinfo_sources = []
    contenttype_sources = []
    portal_sources = []
    @@ -413,7 +407,6 @@ if host_system != 'windows'
    @@ -418,7 +412,6 @@ if host_system != 'windows'

    subdir('xdgmime')
    internal_deps += [xdgmime_lib]
    - internal_objects += [xdgmime_lib.extract_all_objects()]

    install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio')

    @@ -749,20 +742,17 @@ gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h, glib_enumtypes_
    @@ -754,20 +747,17 @@ gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h, glib_enumtypes_
    if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1
    subdir('inotify')
    internal_deps += [ inotify_lib ]
    @@ -55,7 +55,7 @@ index 1111111..2222222 100644
    endif

    if have_bash
    @@ -787,12 +777,12 @@ endif
    @@ -803,12 +793,12 @@ endif
    libgio = library('gio-2.0',
    gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources,
    gio_dtrace_hdr, gio_dtrace_obj,
    @@ -130,9 +130,9 @@ index 1111111..2222222 100644
    # intl.lib is not compatible with SAFESEH
    link_args : [noseh_link_args, glib_link_flags, win32_ldflags],
    include_directories : configinc,
    - dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + gnulib_libm_dependency + [libsysprof_capture_dep],
    - dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep],
    + link_with : [charset_lib, gnulib_lib],
    + dependencies : [pcre, thread_dep, librt] + libintl_deps + libiconv + platform_deps + [libsysprof_capture_dep],
    + dependencies : [pcre, thread_dep, librt] + libintl_deps + libiconv + platform_deps + [libm, libsysprof_capture_dep],
    c_args : glib_c_args,
    objc_args : glib_c_args,
    )
    @@ -151,7 +151,7 @@ diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -784,7 +784,7 @@ libgio = library('gio-2.0',
    @@ -800,7 +800,7 @@ libgio = library('gio-2.0',
    include_directories : [configinc, gioinc],
    link_with : internal_deps,
    # '$(gio_win32_res_ldflag)',
    @@ -187,7 +187,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -1792,7 +1792,7 @@ atomicdefine = '''
    @@ -1815,7 +1815,7 @@ atomicdefine = '''
    # We know that we can always use real ("lock free") atomic operations with MSVC
    if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' or cc.links(atomictest, name : 'atomic ops')
    have_atomic_lock_free = true
    @@ -208,7 +208,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -625,7 +625,7 @@ if host_system != 'windows' and cc.has_function('posix_memalign', prefix : '#inc
    @@ -637,7 +637,7 @@ if host_system != 'windows' and cc.has_function('posix_memalign', prefix : '#inc
    endif

    # Check that posix_spawn() is usable; must use header
    @@ -228,7 +228,7 @@ diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -33,7 +33,7 @@ endif
    @@ -34,7 +34,7 @@ endif

    network_libs = [ ]
    network_args = [ ]
    @@ -249,7 +249,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -408,7 +408,7 @@ foreach m : struct_members
    @@ -419,7 +419,7 @@ foreach m : struct_members
    endforeach

    # Compiler flags
    @@ -258,7 +258,7 @@ index 1111111..2222222 100644
    warning_c_args = [
    '-Wduplicated-branches',
    '-Wimplicit-fallthrough',
    @@ -1442,13 +1442,13 @@ g_sizet_compatibility = {
    @@ -1458,13 +1458,13 @@ g_sizet_compatibility = {
    'long long': sizet_size == long_long_size,
    }

    @@ -636,7 +636,7 @@ diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -895,100 +895,6 @@ gconstructor_as_data_h = custom_target('gconstructor_as_data.h',
    @@ -911,101 +911,6 @@ gconstructor_as_data_h = custom_target('gconstructor_as_data.h',
    output : ['gconstructor_as_data.h'],
    command : [python, '@INPUT0@', '@INPUT1@', 'gconstructor_code', '@OUTPUT@'])

    @@ -684,7 +684,7 @@ index 1111111..2222222 100644
    - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -
    -glib_compile_schemas = executable('glib-compile-schemas',
    - [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-schemas.c'],
    - ['gvdb/gvdb-builder.c', 'glib-compile-schemas.c'],
    - install : true,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    @@ -704,6 +704,7 @@ index 1111111..2222222 100644
    -if not meson.is_cross_build()
    - meson.override_find_program('glib-compile-schemas', glib_compile_schemas)
    - meson.override_find_program('glib-compile-resources', glib_compile_resources)
    - meson.override_find_program('gio-querymodules', gio_querymodules)
    -endif
    -
    -executable('gsettings', 'gsettings-tool.c',
    @@ -769,7 +770,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -2300,7 +2300,6 @@ subdir('gobject')
    @@ -2330,7 +2330,6 @@ subdir('gobject')
    subdir('gthread')
    subdir('gmodule')
    subdir('gio')
    4 changes: 2 additions & 2 deletions libffi-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ emconfigure ./configure --host=wasm32-unknown-linux \
    --disable-structs CFLAGS=-DWASM_BIGINT
    emmake make
    EMMAKEN_JUST_CONFIGURE=1 emmake make check \
    RUNTESTFLAGS="CFLAGS_FOR_TARGET='-s WASM_BIGINT=1'"
    RUNTESTFLAGS="CFLAGS_FOR_TARGET='-s WASM_BIGINT'"

    Co-authored-by: Brion Vibber <[email protected]>

    @@ -361,7 +361,7 @@ index 1111111..2222222 100644

    + if { [string match "wasm32-*" $target_triplet] } {
    + # emscripten sometimes doesn't see the filesystem which breaks the tests using stdout
    + lappend options "additional_flags=-s FORCE_FILESYSTEM=1"
    + lappend options "additional_flags=-s FORCE_FILESYSTEM"
    + }
    +
    verbose "options: $options"
  5. @kleisauke kleisauke revised this gist Jan 9, 2021. 4 changed files with 21 additions and 25 deletions.
    7 changes: 1 addition & 6 deletions Dockerfile
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    FROM emscripten/emsdk:2.0.9
    FROM emscripten/emsdk:2.0.12

    RUN apt-get update \
    && apt-get install -qqy \
    @@ -12,8 +12,3 @@ RUN apt-get update \
    ninja-build \
    python3-pip \
    && pip3 install meson

    # See: https://github.com/mesonbuild/meson/pull/7958
    ARG MESON_PATCH=https://github.com/mesonbuild/meson/pull/7958.patch
    RUN cd $(dirname `python3 -c "import mesonbuild as _; print(_.__path__[0])"`) \
    && curl -Ls $MESON_PATCH | patch -p1
    4 changes: 2 additions & 2 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -29,7 +29,7 @@ export MESON_CROSS="$SOURCE_DIR/emscripten-crossfile.meson"
    # Dependency version numbers
    VERSION_ZLIB=1.2.11
    VERSION_FFI=3.3
    VERSION_GLIB=2.67.0
    VERSION_GLIB=2.67.2

    # Patches
    PATCH_GLIB=https://github.com/kleisauke/wasm-vips/raw/master/build/patches/glib-emscripten.patch
    @@ -61,5 +61,5 @@ cd $DEPS/glib
    curl -Ls $PATCH_GLIB | patch -p1
    meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \
    -Diconv="libc" -Dselinux=disabled -Dxattr=false -Dlibmount=disabled -Dnls=disabled -Dinternal_pcre=true \
    -Dglib_assert=false -Dglib_checks=false
    -Dtests=false -Dglib_assert=false -Dglib_checks=false
    emmake ninja -C _build install
    33 changes: 17 additions & 16 deletions glib-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -34,7 +34,7 @@ index 1111111..2222222 100644

    install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio')

    @@ -744,20 +737,17 @@ gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h, glib_enumtypes_
    @@ -749,20 +742,17 @@ gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h, glib_enumtypes_
    if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1
    subdir('inotify')
    internal_deps += [ inotify_lib ]
    @@ -55,7 +55,7 @@ index 1111111..2222222 100644
    endif

    if have_bash
    @@ -782,12 +772,12 @@ endif
    @@ -787,12 +777,12 @@ endif
    libgio = library('gio-2.0',
    gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources,
    gio_dtrace_hdr, gio_dtrace_obj,
    @@ -82,7 +82,7 @@ diff --git a/glib/meson.build b/glib/meson.build
    index 1111111..2222222 100644
    --- a/glib/meson.build
    +++ b/glib/meson.build
    @@ -23,15 +23,8 @@ libsysprof_capture_dep = dependency('sysprof-capture-4',
    @@ -23,15 +23,8 @@ libsysprof_capture_dep = dependency('sysprof-capture-4', version: '>= 3.38.0',
    )
    glib_conf.set('HAVE_SYSPROF', libsysprof_capture_dep.found())

    @@ -151,14 +151,14 @@ diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -779,7 +779,7 @@ libgio = library('gio-2.0',
    @@ -784,7 +784,7 @@ libgio = library('gio-2.0',
    include_directories : [configinc, gioinc],
    link_with : internal_deps,
    # '$(gio_win32_res_ldflag)',
    - dependencies : [libz_dep, libdl_dep, libmount_dep, libglib_dep,
    + dependencies : [libz_dep, libdl_dep, libmount_dep, thread_dep, libglib_dep,
    libgobject_dep, libgmodule_dep, selinux_dep, xattr_dep,
    platform_deps, network_libs],
    platform_deps, network_libs, libsysprof_capture_dep],
    c_args : gio_c_args,
    diff --git a/gobject/meson.build b/gobject/meson.build
    index 1111111..2222222 100644
    @@ -187,7 +187,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -1788,7 +1788,7 @@ atomicdefine = '''
    @@ -1792,7 +1792,7 @@ atomicdefine = '''
    # We know that we can always use real ("lock free") atomic operations with MSVC
    if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' or cc.links(atomictest, name : 'atomic ops')
    have_atomic_lock_free = true
    @@ -208,7 +208,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -621,7 +621,7 @@ if host_system != 'windows' and cc.has_function('posix_memalign', prefix : '#inc
    @@ -625,7 +625,7 @@ if host_system != 'windows' and cc.has_function('posix_memalign', prefix : '#inc
    endif

    # Check that posix_spawn() is usable; must use header
    @@ -249,7 +249,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -407,7 +407,7 @@ foreach m : struct_members
    @@ -408,7 +408,7 @@ foreach m : struct_members
    endforeach

    # Compiler flags
    @@ -258,7 +258,7 @@ index 1111111..2222222 100644
    warning_c_args = [
    '-Wduplicated-branches',
    '-Wimplicit-fallthrough',
    @@ -1438,13 +1438,13 @@ g_sizet_compatibility = {
    @@ -1442,13 +1442,13 @@ g_sizet_compatibility = {
    'long long': sizet_size == long_long_size,
    }

    @@ -533,7 +533,7 @@ diff --git a/gobject/gtype.h b/gobject/gtype.h
    index 1111111..2222222 100644
    --- a/gobject/gtype.h
    +++ b/gobject/gtype.h
    @@ -1954,7 +1954,8 @@ guint g_type_get_type_registration_serial (void);
    @@ -1957,7 +1957,8 @@ guint g_type_get_type_registration_serial (void);
    */
    #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    @@ -543,7 +543,7 @@ index 1111111..2222222 100644
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    if (TypeName##_private_offset != 0) \
    @@ -1964,7 +1965,8 @@ static void type_name##_class_intern_init (gpointer klass) \
    @@ -1967,7 +1968,8 @@ static void type_name##_class_intern_init (gpointer klass) \

    #else
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    @@ -553,7 +553,7 @@ index 1111111..2222222 100644
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    type_name##_class_init ((TypeName##Class*) klass); \
    @@ -1976,6 +1978,11 @@ static void type_name##_class_intern_init (gpointer klass) \
    @@ -1979,6 +1981,11 @@ static void type_name##_class_intern_init (gpointer klass) \
    \
    static void type_name##_init (TypeName *self); \
    static void type_name##_class_init (TypeName##Class *klass); \
    @@ -565,7 +565,7 @@ index 1111111..2222222 100644
    static GType type_name##_get_type_once (void); \
    static gpointer type_name##_parent_class = NULL; \
    static gint TypeName##_private_offset; \
    @@ -2015,7 +2022,7 @@ type_name##_get_type_once (void) \
    @@ -2018,7 +2025,7 @@ type_name##_get_type_once (void) \
    sizeof (TypeName##Class), \
    (GClassInitFunc)(void (*)(void)) type_name##_class_intern_init, \
    sizeof (TypeName), \
    @@ -610,7 +610,7 @@ index 1111111..2222222 100644
    #include "gslice.h"
    #include "gstrfuncs.h"
    #include "gtestutils.h"
    @@ -1059,7 +1063,9 @@ g_thread_self (void)
    @@ -1065,7 +1069,9 @@ g_thread_self (void)
    guint
    g_get_num_processors (void)
    {
    @@ -636,7 +636,7 @@ diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -890,99 +890,6 @@ gconstructor_as_data_h = custom_target('gconstructor_as_data.h',
    @@ -895,100 +895,6 @@ gconstructor_as_data_h = custom_target('gconstructor_as_data.h',
    output : ['gconstructor_as_data.h'],
    command : [python, '@INPUT0@', '@INPUT1@', 'gconstructor_code', '@OUTPUT@'])

    @@ -647,6 +647,7 @@ index 1111111..2222222 100644
    - 'gio-tool-cat.c',
    - 'gio-tool-copy.c',
    - 'gio-tool-info.c',
    - 'gio-tool-launch.c',
    - 'gio-tool-list.c',
    - 'gio-tool-mime.c',
    - 'gio-tool-mkdir.c',
    @@ -768,7 +769,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -2295,7 +2295,6 @@ subdir('gobject')
    @@ -2300,7 +2300,6 @@ subdir('gobject')
    subdir('gthread')
    subdir('gmodule')
    subdir('gio')
    2 changes: 1 addition & 1 deletion libffi-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ https://github.com/brion/libffi/commits/emscripten-work
    Tested with:
    emconfigure ./configure --host=wasm32-unknown-linux \
    --enable-static --disable-builddir --disable-raw-api \
    CFLAGS=-DWASM_BIGINT
    --disable-structs CFLAGS=-DWASM_BIGINT
    emmake make
    EMMAKEN_JUST_CONFIGURE=1 emmake make check \
    RUNTESTFLAGS="CFLAGS_FOR_TARGET='-s WASM_BIGINT=1'"
  6. @kleisauke kleisauke revised this gist Nov 30, 2020. 6 changed files with 205 additions and 106 deletions.
    19 changes: 19 additions & 0 deletions Dockerfile
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    FROM emscripten/emsdk:2.0.9

    RUN apt-get update \
    && apt-get install -qqy \
    build-essential \
    prelink \
    autoconf \
    libtool \
    texinfo \
    pkgconf \
    # needed for Meson
    ninja-build \
    python3-pip \
    && pip3 install meson

    # See: https://github.com/mesonbuild/meson/pull/7958
    ARG MESON_PATCH=https://github.com/mesonbuild/meson/pull/7958.patch
    RUN cd $(dirname `python3 -c "import mesonbuild as _; print(_.__path__[0])"`) \
    && curl -Ls $MESON_PATCH | patch -p1
    7 changes: 7 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ```bash
    git clone https://gist.github.com/acfa1c09522705efa5eb0541d2d00887.git glib-emscripten
    cd glib-emscripten
    chmod +x ./build.sh
    docker build -t glib-emscripten .
    docker run --rm -v $(pwd):/src glib-emscripten ./build.sh
    ```
    17 changes: 7 additions & 10 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -11,13 +11,12 @@ mkdir $DEPS
    mkdir -p $TARGET

    # Get emscripten crossfile
    curl -Ls -o $SOURCE_DIR/emscripten-crossfile.meson https://gist.github.com/kleisauke/acfa1c09522705efa5eb0541d2d00887/raw/8b9d947eb704c3167f2e4cca4eda115123837f5a/emscripten-crossfile.meson
    curl -Ls -o $SOURCE_DIR/emscripten-crossfile.meson https://github.com/kleisauke/wasm-vips/raw/master/build/emscripten-crossfile.meson

    # Common compiler flags
    export CFLAGS="-O3"
    export CXXFLAGS="$CFLAGS"
    export LDFLAGS="-L$TARGET/lib -O3"
    export EMMAKEN_CFLAGS="-s USE_PTHREADS=1"

    # Build paths
    export CPATH="$TARGET/include"
    @@ -30,20 +29,17 @@ export MESON_CROSS="$SOURCE_DIR/emscripten-crossfile.meson"
    # Dependency version numbers
    VERSION_ZLIB=1.2.11
    VERSION_FFI=3.3
    VERSION_GLIB=2.64.2
    VERSION_GLIB=2.67.0

    # Patches
    PATCH_GLIB=https://gist.github.com/kleisauke/acfa1c09522705efa5eb0541d2d00887/raw/8b9d947eb704c3167f2e4cca4eda115123837f5a/glib-emscripten.patch
    PATCH_FFI=https://gist.github.com/kleisauke/acfa1c09522705efa5eb0541d2d00887/raw/8b9d947eb704c3167f2e4cca4eda115123837f5a/libffi-emscripten.patch
    PATCH_GLIB=https://github.com/kleisauke/wasm-vips/raw/master/build/patches/glib-emscripten.patch
    PATCH_FFI=https://github.com/kleisauke/wasm-vips/raw/master/build/patches/libffi-emscripten.patch

    # Remove patch version component
    without_patch() {
    echo "${1%.[[:digit:]]*}"
    }

    # The struct_info file must be built without modifications to EMMAKEN_CFLAGS
    EMMAKEN_CFLAGS= embuilder.py build struct_info

    mkdir $DEPS/zlib
    curl -Ls http://zlib.net/zlib-$VERSION_ZLIB.tar.xz | tar xJC $DEPS/zlib --strip-components=1
    cd $DEPS/zlib
    @@ -56,13 +52,14 @@ cd $DEPS/ffi
    curl -Ls $PATCH_FFI | patch -p1
    autoreconf -fiv
    emconfigure ./configure --host=$CHOST --prefix=$TARGET --enable-static --disable-shared --disable-dependency-tracking \
    --disable-builddir --disable-multi-os-directory --disable-raw-api
    --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-structs
    emmake make install

    mkdir $DEPS/glib
    curl -Lks https://download.gnome.org/sources/glib/$(without_patch $VERSION_GLIB)/glib-$VERSION_GLIB.tar.xz | tar xJC $DEPS/glib --strip-components=1
    cd $DEPS/glib
    curl -Ls $PATCH_GLIB | patch -p1
    meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \
    -Diconv="libc" -Dselinux=disabled -Dxattr=false -Dlibmount=disabled -Dnls=disabled -Dinternal_pcre=true
    -Diconv="libc" -Dselinux=disabled -Dxattr=false -Dlibmount=disabled -Dnls=disabled -Dinternal_pcre=true \
    -Dglib_assert=false -Dglib_checks=false
    emmake ninja -C _build install
    5 changes: 5 additions & 0 deletions emscripten-crossfile.meson
    Original file line number Diff line number Diff line change
    @@ -6,6 +6,11 @@ ar = 'emar'
    ranlib = 'emranlib'
    pkgconfig = ['emconfigure', 'pkg-config']

    # Ensure that `-s PTHREAD_POOL_SIZE=*` is not injected into .pc files
    [built-in options]
    c_thread_count = 0
    cpp_thread_count = 0

    [host_machine]
    system = 'emscripten'
    cpu_family = 'wasm32'
    164 changes: 100 additions & 64 deletions glib-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -7,13 +7,13 @@ Subject: [PATCH 1/8] Revert "Meson: Extract objects from convenience libraries t
    This reverts commit 62af03bda8a1d649b079a0e77d3687695d0ab7d3.

    Upstream-Status: Inappropriate [other]
    Upstream may still depend on an older Meson version.
    Upstream may still depend on Meson < 0.52.0.

    diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -344,12 +344,6 @@ local_sources = files(
    @@ -337,12 +337,6 @@ local_sources = files(

    platform_deps = []
    internal_deps = []
    @@ -26,15 +26,15 @@ index 1111111..2222222 100644
    appinfo_sources = []
    contenttype_sources = []
    portal_sources = []
    @@ -420,7 +414,6 @@ if host_system != 'windows'
    @@ -413,7 +407,6 @@ if host_system != 'windows'

    subdir('xdgmime')
    internal_deps += [xdgmime_lib]
    - internal_objects += [xdgmime_lib.extract_all_objects()]

    install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio')

    @@ -751,20 +744,17 @@ gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h, glib_enumtypes_
    @@ -744,20 +737,17 @@ gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h, glib_enumtypes_
    if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1
    subdir('inotify')
    internal_deps += [ inotify_lib ]
    @@ -55,7 +55,7 @@ index 1111111..2222222 100644
    endif

    if have_bash
    @@ -789,12 +779,12 @@ endif
    @@ -782,12 +772,12 @@ endif
    libgio = library('gio-2.0',
    gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources,
    gio_dtrace_hdr, gio_dtrace_obj,
    @@ -73,7 +73,7 @@ diff --git a/glib/gnulib/meson.build b/glib/gnulib/meson.build
    index 1111111..2222222 100644
    --- a/glib/gnulib/meson.build
    +++ b/glib/gnulib/meson.build
    @@ -340,4 +340,3 @@ gnulib_lib = static_library('gnulib', gnulib_sources,
    @@ -368,4 +368,3 @@ gnulib_lib = static_library('gnulib', gnulib_sources,
    pic : true,
    c_args : ['-DGCC_LINT=1', '-DLIBDIR="@0@"'.format(glib_libdir), '-DGLIB_COMPILATION', '-DG_LOG_DOMAIN="GLib"' ] + glib_hidden_visibility_args + extra_gnulib_args)

    @@ -82,9 +82,9 @@ diff --git a/glib/meson.build b/glib/meson.build
    index 1111111..2222222 100644
    --- a/glib/meson.build
    +++ b/glib/meson.build
    @@ -7,15 +7,8 @@ if not use_system_pcre
    subdir('pcre')
    endif
    @@ -23,15 +23,8 @@ libsysprof_capture_dep = dependency('sysprof-capture-4',
    )
    glib_conf.set('HAVE_SYSPROF', libsysprof_capture_dep.found())

    -# TODO: gnulib_objects, pcre_objects and pcre_deps are a workaround for
    -# <https://github.com/mesonbuild/meson/issues/3934> and
    @@ -98,15 +98,15 @@ index 1111111..2222222 100644
    glib_conf.set ('gl_unused', '')
    glib_conf.set ('gl_extern_inline', '')
    else
    @@ -104,7 +97,6 @@ else
    @@ -120,7 +113,6 @@ else
    endif

    subdir('gnulib')
    - gnulib_objects = [gnulib_lib.extract_all_objects()]
    endif

    glib_headers = files(
    @@ -336,19 +328,10 @@ if use_pcre_static_flag
    @@ -357,19 +349,10 @@ if use_pcre_static_flag
    pcre_static_args = ['-DPCRE_STATIC']
    endif

    @@ -126,21 +126,58 @@ index 1111111..2222222 100644
    version : library_version,
    soversion : soversion,
    darwin_versions : darwin_versions,
    @@ -356,7 +339,8 @@ libglib = library('glib-2.0',
    @@ -377,7 +360,8 @@ libglib = library('glib-2.0',
    # intl.lib is not compatible with SAFESEH
    link_args : [noseh_link_args, glib_link_flags, win32_ldflags],
    include_directories : configinc,
    - dependencies : pcre_deps + [thread_dep, libintl, librt] + libiconv + platform_deps + gnulib_libm_dependency,
    - dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + gnulib_libm_dependency + [libsysprof_capture_dep],
    + link_with : [charset_lib, gnulib_lib],
    + dependencies : [pcre, thread_dep, libintl, librt] + libiconv + platform_deps,
    + dependencies : [pcre, thread_dep, librt] + libintl_deps + libiconv + platform_deps + [libsysprof_capture_dep],
    c_args : glib_c_args,
    objc_args : glib_c_args,
    )

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 30 Sep 2020 14:00:00 +0200
    Subject: [PATCH 2/9] Explicitly link gio and gobject against pthread

    To ensure that the compiled code uses the "atomics" target feature of WASM.

    Upstream-Status: Inappropriate [Emscripten specific]
    Specific for Emscripten and not appropriate for native environments.

    diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -779,7 +779,7 @@ libgio = library('gio-2.0',
    include_directories : [configinc, gioinc],
    link_with : internal_deps,
    # '$(gio_win32_res_ldflag)',
    - dependencies : [libz_dep, libdl_dep, libmount_dep, libglib_dep,
    + dependencies : [libz_dep, libdl_dep, libmount_dep, thread_dep, libglib_dep,
    libgobject_dep, libgmodule_dep, selinux_dep, xattr_dep,
    platform_deps, network_libs],
    c_args : gio_c_args,
    diff --git a/gobject/meson.build b/gobject/meson.build
    index 1111111..2222222 100644
    --- a/gobject/meson.build
    +++ b/gobject/meson.build
    @@ -125,7 +125,7 @@ libgobject = library('gobject-2.0',
    darwin_versions : darwin_versions,
    install : true,
    include_directories : [configinc],
    - dependencies : [libffi_dep, libglib_dep],
    + dependencies : [libffi_dep, thread_dep, libglib_dep],
    c_args : ['-DG_LOG_DOMAIN="GLib-GObject"', '-DGOBJECT_COMPILATION'] + glib_hidden_visibility_args,
    link_args : glib_link_flags,
    )

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:00:00 +0200
    Subject: [PATCH 2/8] LLVM doesn't define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
    Subject: [PATCH 3/9] LLVM doesn't define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4

    See: https://bugs.llvm.org/show_bug.cgi?id=11174

    @@ -150,7 +187,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -1689,7 +1689,7 @@ atomicdefine = '''
    @@ -1788,7 +1788,7 @@ atomicdefine = '''
    # We know that we can always use real ("lock free") atomic operations with MSVC
    if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' or cc.links(atomictest, name : 'atomic ops')
    have_atomic_lock_free = true
    @@ -163,36 +200,36 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:20:00 +0200
    Subject: [PATCH 3/8] posix_spawn isn't usable in WASM
    Subject: [PATCH 4/9] posix_spawn isn't usable in WASM

    Upstream-Status: Pending

    diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -541,7 +541,7 @@ if cc.has_function('posix_memalign', prefix : '#include <stdlib.h>')
    @@ -621,7 +621,7 @@ if host_system != 'windows' and cc.has_function('posix_memalign', prefix : '#inc
    endif

    # Check that posix_spawn() is usable; must use header
    -if cc.has_function('posix_spawn', prefix : '#include <spawn.h>')
    +if host_system != 'emscripten' and cc.has_function('posix_spawn', prefix : '#include <spawn.h>')
    glib_conf.set('HAVE_POSIX_SPAWN', 1)
    endif

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:40:00 +0200
    Subject: [PATCH 4/8] Network libs are not available in WASM
    Subject: [PATCH 5/9] Network libs are not available in WASM

    Upstream-Status: Pending

    diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -39,7 +39,7 @@ endif

    @@ -33,7 +33,7 @@ endif
    network_libs = [ ]
    network_args = [ ]
    -if host_system != 'windows'
    @@ -204,15 +241,15 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 22 Apr 2020 12:11:28 +0200
    Subject: [PATCH 5/8] Ensure separate checks are also done for Emscripten
    Subject: [PATCH 6/9] Ensure separate checks are also done for Emscripten

    Upstream-Status: Pending

    diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -358,7 +358,7 @@ foreach m : struct_members
    @@ -407,7 +407,7 @@ foreach m : struct_members
    endforeach

    # Compiler flags
    @@ -221,7 +258,7 @@ index 1111111..2222222 100644
    warning_c_args = [
    '-Wduplicated-branches',
    '-Wimplicit-fallthrough',
    @@ -1327,13 +1327,13 @@ g_sizet_compatibility = {
    @@ -1438,13 +1438,13 @@ g_sizet_compatibility = {
    'long long': sizet_size == long_long_size,
    }

    @@ -242,7 +279,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 20 Sep 2019 16:05:00 +0200
    Subject: [PATCH 6/8] Fix function pointer cast issues
    Subject: [PATCH 7/9] Fix function pointer cast issues

    It is undefined behavior in C and C++ to cast a function pointer
    to another type and call it that way. This does work in most native
    @@ -294,7 +331,7 @@ diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c
    index 1111111..2222222 100644
    --- a/gobject/gparamspecs.c
    +++ b/gobject/gparamspecs.c
    @@ -59,7 +59,7 @@
    @@ -61,7 +61,7 @@

    /* --- param spec functions --- */
    static void
    @@ -303,7 +340,7 @@ index 1111111..2222222 100644
    {
    GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);

    @@ -88,7 +88,7 @@ param_char_validate (GParamSpec *pspec,
    @@ -90,7 +90,7 @@ param_char_validate (GParamSpec *pspec,
    }

    static void
    @@ -312,7 +349,7 @@ index 1111111..2222222 100644
    {
    GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);

    @@ -135,7 +135,7 @@ param_boolean_validate (GParamSpec *pspec,
    @@ -137,7 +137,7 @@ param_boolean_validate (GParamSpec *pspec,
    }

    static void
    @@ -321,7 +358,7 @@ index 1111111..2222222 100644
    {
    GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);

    @@ -175,7 +175,7 @@ param_int_values_cmp (GParamSpec *pspec,
    @@ -177,7 +177,7 @@ param_int_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -330,7 +367,7 @@ index 1111111..2222222 100644
    {
    GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);

    @@ -215,7 +215,7 @@ param_uint_values_cmp (GParamSpec *pspec,
    @@ -217,7 +217,7 @@ param_uint_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -339,7 +376,7 @@ index 1111111..2222222 100644
    {
    GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);

    @@ -260,7 +260,7 @@ param_long_values_cmp (GParamSpec *pspec,
    @@ -262,7 +262,7 @@ param_long_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -348,7 +385,7 @@ index 1111111..2222222 100644
    {
    GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);

    @@ -304,7 +304,7 @@ param_ulong_values_cmp (GParamSpec *pspec,
    @@ -306,7 +306,7 @@ param_ulong_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -357,7 +394,7 @@ index 1111111..2222222 100644
    {
    GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);

    @@ -344,7 +344,7 @@ param_int64_values_cmp (GParamSpec *pspec,
    @@ -346,7 +346,7 @@ param_int64_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -366,7 +403,7 @@ index 1111111..2222222 100644
    {
    GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);

    @@ -384,7 +384,7 @@ param_uint64_values_cmp (GParamSpec *pspec,
    @@ -386,7 +386,7 @@ param_uint64_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -375,7 +412,7 @@ index 1111111..2222222 100644
    {
    GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);

    @@ -426,7 +426,7 @@ param_unichar_values_cmp (GParamSpec *pspec,
    @@ -428,7 +428,7 @@ param_unichar_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -384,7 +421,7 @@ index 1111111..2222222 100644
    {
    GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);

    @@ -471,7 +471,7 @@ param_enum_validate (GParamSpec *pspec,
    @@ -473,7 +473,7 @@ param_enum_validate (GParamSpec *pspec,
    }

    static void
    @@ -393,7 +430,7 @@ index 1111111..2222222 100644
    {
    GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);

    @@ -517,7 +517,7 @@ param_flags_validate (GParamSpec *pspec,
    @@ -519,7 +519,7 @@ param_flags_validate (GParamSpec *pspec,
    }

    static void
    @@ -402,7 +439,7 @@ index 1111111..2222222 100644
    {
    GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);

    @@ -560,7 +560,7 @@ param_float_values_cmp (GParamSpec *pspec,
    @@ -562,7 +562,7 @@ param_float_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -411,7 +448,7 @@ index 1111111..2222222 100644
    {
    GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);

    @@ -603,7 +603,7 @@ param_double_values_cmp (GParamSpec *pspec,
    @@ -605,7 +605,7 @@ param_double_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -420,7 +457,7 @@ index 1111111..2222222 100644
    {
    GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);

    @@ -711,7 +711,7 @@ param_string_values_cmp (GParamSpec *pspec,
    @@ -713,7 +713,7 @@ param_string_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -429,7 +466,7 @@ index 1111111..2222222 100644
    {
    /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
    }
    @@ -742,7 +742,7 @@ param_param_validate (GParamSpec *pspec,
    @@ -744,7 +744,7 @@ param_param_validate (GParamSpec *pspec,
    }

    static void
    @@ -438,7 +475,7 @@ index 1111111..2222222 100644
    {
    /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
    }
    @@ -780,7 +780,7 @@ param_boxed_values_cmp (GParamSpec *pspec,
    @@ -782,7 +782,7 @@ param_boxed_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -447,7 +484,7 @@ index 1111111..2222222 100644
    {
    /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
    }
    @@ -816,7 +816,7 @@ param_pointer_values_cmp (GParamSpec *pspec,
    @@ -818,7 +818,7 @@ param_pointer_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -456,7 +493,7 @@ index 1111111..2222222 100644
    {
    GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);

    @@ -967,7 +967,7 @@ param_value_array_values_cmp (GParamSpec *pspec,
    @@ -969,7 +969,7 @@ param_value_array_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -465,7 +502,7 @@ index 1111111..2222222 100644
    {
    /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
    }
    @@ -1011,7 +1011,7 @@ param_object_values_cmp (GParamSpec *pspec,
    @@ -1013,7 +1013,7 @@ param_object_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -474,7 +511,7 @@ index 1111111..2222222 100644
    {
    /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
    }
    @@ -1060,7 +1060,7 @@ param_override_values_cmp (GParamSpec *pspec,
    @@ -1062,7 +1062,7 @@ param_override_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -483,7 +520,7 @@ index 1111111..2222222 100644
    {
    }

    @@ -1104,7 +1104,7 @@ param_gtype_values_cmp (GParamSpec *pspec,
    @@ -1106,7 +1106,7 @@ param_gtype_values_cmp (GParamSpec *pspec,
    }

    static void
    @@ -496,7 +533,7 @@ diff --git a/gobject/gtype.h b/gobject/gtype.h
    index 1111111..2222222 100644
    --- a/gobject/gtype.h
    +++ b/gobject/gtype.h
    @@ -1958,7 +1958,8 @@ guint g_type_get_type_registration_serial (void);
    @@ -1954,7 +1954,8 @@ guint g_type_get_type_registration_serial (void);
    */
    #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    @@ -506,7 +543,7 @@ index 1111111..2222222 100644
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    if (TypeName##_private_offset != 0) \
    @@ -1968,7 +1969,8 @@ static void type_name##_class_intern_init (gpointer klass) \
    @@ -1964,7 +1965,8 @@ static void type_name##_class_intern_init (gpointer klass) \

    #else
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    @@ -516,7 +553,7 @@ index 1111111..2222222 100644
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    type_name##_class_init ((TypeName##Class*) klass); \
    @@ -1980,6 +1982,11 @@ static void type_name##_class_intern_init (gpointer klass) \
    @@ -1976,6 +1978,11 @@ static void type_name##_class_intern_init (gpointer klass) \
    \
    static void type_name##_init (TypeName *self); \
    static void type_name##_class_init (TypeName##Class *klass); \
    @@ -528,7 +565,7 @@ index 1111111..2222222 100644
    static GType type_name##_get_type_once (void); \
    static gpointer type_name##_parent_class = NULL; \
    static gint TypeName##_private_offset; \
    @@ -2019,7 +2026,7 @@ type_name##_get_type_once (void) \
    @@ -2015,7 +2022,7 @@ type_name##_get_type_once (void) \
    sizeof (TypeName##Class), \
    (GClassInitFunc)(void (*)(void)) type_name##_class_intern_init, \
    sizeof (TypeName), \
    @@ -554,27 +591,26 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 15 Nov 2019 11:00:00 +0100
    Subject: [PATCH 7/8] Implement g_get_num_processors for Emscripten
    Subject: [PATCH 8/9] Implement g_get_num_processors for Emscripten

    Upstream-Status: Pending

    diff --git a/glib/gthread.c b/glib/gthread.c
    index 1111111..2222222 100644
    --- a/glib/gthread.c
    +++ b/glib/gthread.c
    @@ -54,6 +54,11 @@
    @@ -54,6 +54,10 @@
    #include <windows.h>
    #endif /* G_OS_WIN32 */

    +#ifdef __EMSCRIPTEN__
    +#include <emscripten.h>
    +#include <emscripten/threading.h>
    +#endif /*__EMSCRIPTEN__*/
    +
    #include "gslice.h"
    #include "gstrfuncs.h"
    #include "gtestutils.h"
    @@ -1045,7 +1050,9 @@ g_thread_self (void)
    @@ -1059,7 +1063,9 @@ g_thread_self (void)
    guint
    g_get_num_processors (void)
    {
    @@ -589,7 +625,7 @@ index 1111111..2222222 100644
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Tue, 8 Oct 2019 11:30:00 +0200
    Subject: [PATCH 8/8] Do not build executables
    Subject: [PATCH 9/9] Do not build executables

    We're only interested in the libraries.

    @@ -600,7 +636,7 @@ diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -886,99 +886,6 @@ gconstructor_as_data_h = custom_target('gconstructor_as_data.h',
    @@ -890,99 +890,6 @@ gconstructor_as_data_h = custom_target('gconstructor_as_data.h',
    output : ['gconstructor_as_data.h'],
    command : [python, '@INPUT0@', '@INPUT1@', 'gconstructor_code', '@OUTPUT@'])

    @@ -704,7 +740,7 @@ diff --git a/glib/meson.build b/glib/meson.build
    index 1111111..2222222 100644
    --- a/glib/meson.build
    +++ b/glib/meson.build
    @@ -394,7 +394,7 @@ if host_system == 'windows'
    @@ -417,7 +417,7 @@ if host_system == 'windows'
    include_directories : configinc,
    dependencies : [libglib_dep])
    endif
    @@ -717,9 +753,9 @@ diff --git a/gobject/meson.build b/gobject/meson.build
    index 1111111..2222222 100644
    --- a/gobject/meson.build
    +++ b/gobject/meson.build
    @@ -143,10 +143,6 @@ libgobject_dep = declare_dependency(link_with : libgobject,
    include_directories : [gobjectinc],
    dependencies : [libglib_dep, glib_enumtypes_dep])
    @@ -147,10 +147,6 @@ if meson.version().version_compare('>=0.54.0')
    meson.override_dependency('gobject-2.0', libgobject_dep)
    endif

    -executable('gobject-query', 'gobject-query.c',
    - install : true,
    @@ -732,7 +768,7 @@ diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -2167,7 +2167,6 @@ subdir('gobject')
    @@ -2295,7 +2295,6 @@ subdir('gobject')
    subdir('gthread')
    subdir('gmodule')
    subdir('gio')
    99 changes: 67 additions & 32 deletions libffi-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,23 @@
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Brion Vibber <[email protected]>
    Date: Sat, 5 May 2018 17:28:06 -0700
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 28 Aug 2020 19:00:00 +0200
    Subject: [PATCH 1/1] Work in progress: wasm32 support for libffi

    See: https://github.com/brion/libffi/commits/emscripten-work
    Implements basic support for void/int/float/double/int64,
    but not yet struct or complex. The closure API is also NYI.

    Based on:
    https://github.com/brion/libffi/commits/emscripten-work

    Tested with:
    emconfigure ./configure --host=wasm32-unknown-linux \
    --enable-static --disable-builddir --disable-raw-api \
    CFLAGS=-DWASM_BIGINT
    emmake make
    EMMAKEN_JUST_CONFIGURE=1 emmake make check \
    RUNTESTFLAGS="CFLAGS_FOR_TARGET='-s WASM_BIGINT=1'"

    Co-authored-by: Brion Vibber <[email protected]>

    Upstream-Status: Pending

    @@ -47,10 +61,10 @@ index 1111111..2222222 100644
    SOURCES="ffi.c sysv.S"
    diff --git a/src/wasm32/ffi.c b/src/wasm32/ffi.c
    new file mode 100644
    index 1111111..2222222
    index 0000000..1111111
    --- /dev/null
    +++ b/src/wasm32/ffi.c
    @@ -0,0 +1,168 @@
    @@ -0,0 +1,189 @@
    +/* -----------------------------------------------------------------------
    + ffi.c - Copyright (c) 2018 Brion Vibber
    +
    @@ -96,23 +110,19 @@ index 1111111..2222222
    + var cif_arg_types = HEAPU32[(cif + 8) >> 2];
    + var cif_rtype = HEAPU32[(cif + 12) >> 2];
    +
    + // emscripten/wasm function pointers are indirected through a table,
    + // which is further subdivided by function signature -- each pointer
    + // must be added to a constant to find its real sig. This doesn't seem
    + // to be a strict wasm requirement, but is a leftover from asm.js
    + // which used separate arrays for each signature.
    + //
    + // This is neatly encapsulated into dynCall_* wrapper functions for us,
    + // which take a function pointer as first parameter and pass the rest on.
    + //
    + // Generate an emscripten call signature and look up the correct wrapper
    + // via name here...
    + var args = [fn];
    + var sig;
    + var sigFloat = Module['wasmMemory'] ? 'f' : 'd';
    +
    + var args = [];
    + var rtype = HEAPU16[(cif_rtype + 6 /* rtype->type*/ ) >> 1];
    + //console.error('rtype is', rtype);
    +
    +#if WASM_BIGINT
    + if (rtype === /* FFI_TYPE_STRUCT */ 13) {
    + throw new Error('struct ret marshalling nyi');
    + } else if (rtype === /* FFI_TYPE_COMPLEX */ 15) {
    + throw new Error('complex ret marshalling nyi');
    + } else if (rtype < 0 || rtype > 14) {
    + throw new Error('Unexpected rtype ' + rtype);
    + }
    +#else
    + var sig;
    + if (rtype === /* FFI_TYPE_VOID */ 0) {
    + sig = 'v';
    + } else if (rtype === /* FFI_TYPE_INT */ 1 ||
    @@ -125,7 +135,7 @@ index 1111111..2222222
    + rtype === /* FFI_TYPE_POINTER */ 14) {
    + sig = 'i';
    + } else if (rtype === /* FFI_TYPE_FLOAT */ 2) {
    + sig = sigFloat;
    + sig = 'f';
    + } else if (rtype === /* FFI_TYPE_DOUBLE */ 3 ||
    + rtype === /* FFI_TYPE_LONGDOUBLE */ 4) {
    + sig = 'd';
    @@ -141,6 +151,7 @@ index 1111111..2222222
    + } else {
    + throw new Error('Unexpected rtype ' + rtype);
    + }
    +#endif
    +
    + for (var i = 0; i < cif_nargs; i++) {
    + var ptr = HEAPU32[(avalue >> 2) + i];
    @@ -150,34 +161,54 @@ index 1111111..2222222
    +
    + if (typ === /* FFI_TYPE_INT*/ 1 || typ === /* FFI_TYPE_SINT32 */ 10) {
    + args.push(HEAP32[ptr >> 2]);
    +#if !WASM_BIGINT
    + sig += 'i';
    +#endif
    + } else if (typ === /* FFI_TYPE_FLOAT */ 2) {
    + args.push(HEAPF32[ptr >> 2]);
    + sig += sigFloat;
    +#if !WASM_BIGINT
    + sig += 'f';
    +#endif
    + } else if (typ === /* FFI_TYPE_DOUBLE */ 3 || typ === /* FFI_TYPE_LONGDOUBLE */ 4) {
    + args.push(HEAPF64[ptr >> 3]);
    + sig += 'd';
    +#if !WASM_BIGINT
    + sig += 'd';
    +#endif
    + } else if (typ === /* FFI_TYPE_UINT8*/ 5) {
    + args.push(HEAPU8[ptr]);
    +#if !WASM_BIGINT
    + sig += 'i';
    +#endif
    + } else if (typ === /* FFI_TYPE_SINT8 */ 6) {
    + args.push(HEAP8[ptr]);
    +#if !WASM_BIGINT
    + sig += 'i';
    +#endif
    + } else if (typ === /* FFI_TYPE_UINT16 */ 7) {
    + args.push(HEAPU16[ptr >> 1]);
    +#if !WASM_BIGINT
    + sig += 'i';
    +#endif
    + } else if (typ === /* FFI_TYPE_SINT16 */ 8) {
    + args.push(HEAP16[ptr >> 1]);
    +#if !WASM_BIGINT
    + sig += 'i';
    +#endif
    + } else if (typ === /* FFI_TYPE_UINT32 */ 9 || typ === /* FFI_TYPE_POINTER */ 14) {
    + args.push(HEAPU32[ptr >> 2]);
    +#if !WASM_BIGINT
    + sig += 'i';
    +#endif
    + } else if (typ === /* FFI_TYPE_UINT64 */ 11 || typ === /* FFI_TYPE_SINT64 */ 12) {
    +#if WASM_BIGINT
    + args.push(BigInt(HEAPU32[ptr >> 2]) | (BigInt(HEAPU32[(ptr + 4) >> 2]) << BigInt(32)));
    +#else
    + // LEGALIZE_JS_FFI mode splits i64 (j) into two i32 args
    + // for compatibility with JavaScript's f64-based numbers.
    + args.push(HEAPU32[ptr >> 2]);
    + args.push(HEAPU32[(ptr + 4) >> 2]);
    + sig += 'j';
    +#endif
    + } else if (typ === /* FFI_TYPE_STRUCT */ 13) {
    + throw new Error('struct marshalling nyi');
    + } else if (typ === /* FFI_TYPE_COMPLEX */ 15) {
    @@ -187,12 +218,11 @@ index 1111111..2222222
    + }
    + }
    +
    + var func = Module['dynCall_' + sig];
    + if (func) {
    + var result = func.apply(null, args);
    + } else {
    + throw new Error('invalid function pointer in ffi_call');
    + }
    +#if WASM_BIGINT
    + var result = wasmTable.get(fn).apply(null, args);
    +#else
    + var result = dynCall(sig, fn, args);
    +#endif
    +
    + if (rtype === 0) {
    + // void
    @@ -207,10 +237,15 @@ index 1111111..2222222
    + } else if (rtype === 7 || rtype === 8) {
    + HEAP16[rvalue >> 1] = result;
    + } else if (rtype === 11 || rtype === 12) {
    +#if WASM_BIGINT
    + HEAP32[rvalue >> 2] = Number(result & BigInt(0xffffffff)) | 0;
    + HEAP32[(rvalue + 4) >> 2] = Number(result >> BigInt(32)) | 0;
    +#else
    + // Warning: returns a truncated 32-bit integer directly.
    + // High bits are in $tempRet0
    + HEAP32[rvalue >> 2] = result;
    + HEAP32[(rvalue + 4) >> 2] = Module.getTempRet0();
    +#endif
    + } else if (rtype === 13) {
    + throw new Error('struct ret marshalling nyi');
    + } else if (rtype === 15) {
    @@ -221,7 +256,7 @@ index 1111111..2222222
    +});
    diff --git a/src/wasm32/ffitarget.h b/src/wasm32/ffitarget.h
    new file mode 100644
    index 1111111..2222222
    index 0000000..1111111
    --- /dev/null
    +++ b/src/wasm32/ffitarget.h
    @@ -0,0 +1,59 @@
    @@ -292,7 +327,7 @@ index 1111111..2222222 100644
    set output_match [lreplace $output_match 1 1 $x]
    }

    + if { [ istarget wasm32-* ] } {
    + if { [ istarget "wasm32-*-*" ] } {
    + # emscripten will get confused if told to build as .exe
    + set exec_suffix ""
    + } else {
  7. @kleisauke kleisauke revised this gist May 22, 2020. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -41,6 +41,9 @@ without_patch() {
    echo "${1%.[[:digit:]]*}"
    }

    # The struct_info file must be built without modifications to EMMAKEN_CFLAGS
    EMMAKEN_CFLAGS= embuilder.py build struct_info

    mkdir $DEPS/zlib
    curl -Ls http://zlib.net/zlib-$VERSION_ZLIB.tar.xz | tar xJC $DEPS/zlib --strip-components=1
    cd $DEPS/zlib
  8. @kleisauke kleisauke revised this gist May 5, 2020. 1 changed file with 65 additions and 0 deletions.
    65 changes: 65 additions & 0 deletions build.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@
    #!/usr/bin/env bash
    set -e

    SOURCE_DIR=$PWD

    # Working directories
    DEPS=$SOURCE_DIR/deps
    TARGET=$SOURCE_DIR/target
    rm -rf $DEPS/
    mkdir $DEPS
    mkdir -p $TARGET

    # Get emscripten crossfile
    curl -Ls -o $SOURCE_DIR/emscripten-crossfile.meson https://gist.github.com/kleisauke/acfa1c09522705efa5eb0541d2d00887/raw/8b9d947eb704c3167f2e4cca4eda115123837f5a/emscripten-crossfile.meson

    # Common compiler flags
    export CFLAGS="-O3"
    export CXXFLAGS="$CFLAGS"
    export LDFLAGS="-L$TARGET/lib -O3"
    export EMMAKEN_CFLAGS="-s USE_PTHREADS=1"

    # Build paths
    export CPATH="$TARGET/include"
    export EM_PKG_CONFIG_PATH="$TARGET/lib/pkgconfig"

    # Specific variables for cross-compilation
    export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten
    export MESON_CROSS="$SOURCE_DIR/emscripten-crossfile.meson"

    # Dependency version numbers
    VERSION_ZLIB=1.2.11
    VERSION_FFI=3.3
    VERSION_GLIB=2.64.2

    # Patches
    PATCH_GLIB=https://gist.github.com/kleisauke/acfa1c09522705efa5eb0541d2d00887/raw/8b9d947eb704c3167f2e4cca4eda115123837f5a/glib-emscripten.patch
    PATCH_FFI=https://gist.github.com/kleisauke/acfa1c09522705efa5eb0541d2d00887/raw/8b9d947eb704c3167f2e4cca4eda115123837f5a/libffi-emscripten.patch

    # Remove patch version component
    without_patch() {
    echo "${1%.[[:digit:]]*}"
    }

    mkdir $DEPS/zlib
    curl -Ls http://zlib.net/zlib-$VERSION_ZLIB.tar.xz | tar xJC $DEPS/zlib --strip-components=1
    cd $DEPS/zlib
    emconfigure ./configure --prefix=$TARGET --static
    emmake make install

    mkdir $DEPS/ffi
    curl -Ls https://sourceware.org/pub/libffi/libffi-$VERSION_FFI.tar.gz | tar xzC $DEPS/ffi --strip-components=1
    cd $DEPS/ffi
    curl -Ls $PATCH_FFI | patch -p1
    autoreconf -fiv
    emconfigure ./configure --host=$CHOST --prefix=$TARGET --enable-static --disable-shared --disable-dependency-tracking \
    --disable-builddir --disable-multi-os-directory --disable-raw-api
    emmake make install

    mkdir $DEPS/glib
    curl -Lks https://download.gnome.org/sources/glib/$(without_patch $VERSION_GLIB)/glib-$VERSION_GLIB.tar.xz | tar xJC $DEPS/glib --strip-components=1
    cd $DEPS/glib
    curl -Ls $PATCH_GLIB | patch -p1
    meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \
    -Diconv="libc" -Dselinux=disabled -Dxattr=false -Dlibmount=disabled -Dnls=disabled -Dinternal_pcre=true
    emmake ninja -C _build install
  9. @kleisauke kleisauke revised this gist May 2, 2020. 1 changed file with 13 additions and 0 deletions.
    13 changes: 13 additions & 0 deletions emscripten-crossfile.meson
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    [binaries]
    c = 'emcc'
    cpp = 'em++'
    ld = 'wasm-ld'
    ar = 'emar'
    ranlib = 'emranlib'
    pkgconfig = ['emconfigure', 'pkg-config']

    [host_machine]
    system = 'emscripten'
    cpu_family = 'wasm32'
    cpu = 'wasm32'
    endian = 'little'
  10. @kleisauke kleisauke created this gist May 2, 2020.
    742 changes: 742 additions & 0 deletions glib-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,742 @@
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 14:00:00 +0200
    Subject: [PATCH 1/8] Revert "Meson: Extract objects from convenience libraries to
    link them"

    This reverts commit 62af03bda8a1d649b079a0e77d3687695d0ab7d3.

    Upstream-Status: Inappropriate [other]
    Upstream may still depend on an older Meson version.

    diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -344,12 +344,6 @@ local_sources = files(

    platform_deps = []
    internal_deps = []
    -# TODO: internal_objects is a workaround for
    -# <https://github.com/mesonbuild/meson/issues/3934> and
    -# <https://github.com/mesonbuild/meson/issues/3937>. When we can depend
    -# on a meson version where those are fixed, revert the commit that
    -# introduced this workaround.
    -internal_objects = []
    appinfo_sources = []
    contenttype_sources = []
    portal_sources = []
    @@ -420,7 +414,6 @@ if host_system != 'windows'

    subdir('xdgmime')
    internal_deps += [xdgmime_lib]
    - internal_objects += [xdgmime_lib.extract_all_objects()]

    install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio')

    @@ -751,20 +744,17 @@ gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h, glib_enumtypes_
    if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1
    subdir('inotify')
    internal_deps += [ inotify_lib ]
    - internal_objects += [inotify_lib.extract_all_objects()]
    endif

    # kevent
    if have_func_kqueue and have_func_kevent
    subdir('kqueue')
    internal_deps += [ kqueue_lib ]
    - internal_objects += [kqueue_lib.extract_all_objects()]
    endif

    if host_system == 'windows'
    subdir('win32')
    internal_deps += [ giowin32_lib ]
    - internal_objects += [giowin32_lib.extract_all_objects()]
    endif

    if have_bash
    @@ -789,12 +779,12 @@ endif
    libgio = library('gio-2.0',
    gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources,
    gio_dtrace_hdr, gio_dtrace_obj,
    - objects : internal_objects,
    version : library_version,
    soversion : soversion,
    darwin_versions : darwin_versions,
    install : true,
    include_directories : [configinc, gioinc],
    + link_with : internal_deps,
    # '$(gio_win32_res_ldflag)',
    dependencies : [libz_dep, libdl_dep, libmount_dep, libglib_dep,
    libgobject_dep, libgmodule_dep, selinux_dep, xattr_dep,
    diff --git a/glib/gnulib/meson.build b/glib/gnulib/meson.build
    index 1111111..2222222 100644
    --- a/glib/gnulib/meson.build
    +++ b/glib/gnulib/meson.build
    @@ -340,4 +340,3 @@ gnulib_lib = static_library('gnulib', gnulib_sources,
    pic : true,
    c_args : ['-DGCC_LINT=1', '-DLIBDIR="@0@"'.format(glib_libdir), '-DGLIB_COMPILATION', '-DG_LOG_DOMAIN="GLib"' ] + glib_hidden_visibility_args + extra_gnulib_args)

    -gnulib_libm_dependency = [libm]
    diff --git a/glib/meson.build b/glib/meson.build
    index 1111111..2222222 100644
    --- a/glib/meson.build
    +++ b/glib/meson.build
    @@ -7,15 +7,8 @@ if not use_system_pcre
    subdir('pcre')
    endif

    -# TODO: gnulib_objects, pcre_objects and pcre_deps are a workaround for
    -# <https://github.com/mesonbuild/meson/issues/3934> and
    -# <https://github.com/mesonbuild/meson/issues/3937>. When we can depend
    -# on a meson version where those are fixed, revert the commit that
    -# introduced this workaround.
    if use_system_printf
    gnulib_lib = []
    - gnulib_objects = []
    - gnulib_libm_dependency = []
    glib_conf.set ('gl_unused', '')
    glib_conf.set ('gl_extern_inline', '')
    else
    @@ -104,7 +97,6 @@ else
    endif

    subdir('gnulib')
    - gnulib_objects = [gnulib_lib.extract_all_objects()]
    endif

    glib_headers = files(
    @@ -336,19 +328,10 @@ if use_pcre_static_flag
    pcre_static_args = ['-DPCRE_STATIC']
    endif

    -if use_system_pcre
    - pcre_deps = [pcre]
    - pcre_objects = []
    -else
    - pcre_deps = []
    - pcre_objects = [libpcre.extract_all_objects()]
    -endif
    -
    glib_c_args = ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre_static_args + glib_hidden_visibility_args
    libglib = library('glib-2.0',
    glib_dtrace_obj, glib_dtrace_hdr,
    sources : [deprecated_sources, glib_sources],
    - objects : [charset_lib.extract_all_objects()] + gnulib_objects + pcre_objects,
    version : library_version,
    soversion : soversion,
    darwin_versions : darwin_versions,
    @@ -356,7 +339,8 @@ libglib = library('glib-2.0',
    # intl.lib is not compatible with SAFESEH
    link_args : [noseh_link_args, glib_link_flags, win32_ldflags],
    include_directories : configinc,
    - dependencies : pcre_deps + [thread_dep, libintl, librt] + libiconv + platform_deps + gnulib_libm_dependency,
    + link_with : [charset_lib, gnulib_lib],
    + dependencies : [pcre, thread_dep, libintl, librt] + libiconv + platform_deps,
    c_args : glib_c_args,
    objc_args : glib_c_args,
    )

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:00:00 +0200
    Subject: [PATCH 2/8] LLVM doesn't define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4

    See: https://bugs.llvm.org/show_bug.cgi?id=11174

    Upstream-Status: Pending

    diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -1689,7 +1689,7 @@ atomicdefine = '''
    # We know that we can always use real ("lock free") atomic operations with MSVC
    if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' or cc.links(atomictest, name : 'atomic ops')
    have_atomic_lock_free = true
    - if cc.get_id() == 'gcc' and not cc.compiles(atomicdefine, name : 'atomic ops define')
    + if not cc.compiles(atomicdefine, name : 'atomic ops define')
    # Old gcc release may provide
    # __sync_bool_compare_and_swap but doesn't define
    # __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:20:00 +0200
    Subject: [PATCH 3/8] posix_spawn isn't usable in WASM

    Upstream-Status: Pending

    diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -541,7 +541,7 @@ if cc.has_function('posix_memalign', prefix : '#include <stdlib.h>')
    endif

    # Check that posix_spawn() is usable; must use header
    -if cc.has_function('posix_spawn', prefix : '#include <spawn.h>')
    +if host_system != 'emscripten' and cc.has_function('posix_spawn', prefix : '#include <spawn.h>')
    glib_conf.set('HAVE_POSIX_SPAWN', 1)
    endif

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 18 Sep 2019 15:40:00 +0200
    Subject: [PATCH 4/8] Network libs are not available in WASM

    Upstream-Status: Pending

    diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -39,7 +39,7 @@ endif

    network_libs = [ ]
    network_args = [ ]
    -if host_system != 'windows'
    +if host_system != 'windows' and host_system != 'emscripten'
    # res_query()
    res_query_test = '''#include <resolv.h>
    int main (int argc, char ** argv) {

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Wed, 22 Apr 2020 12:11:28 +0200
    Subject: [PATCH 5/8] Ensure separate checks are also done for Emscripten

    Upstream-Status: Pending

    diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -358,7 +358,7 @@ foreach m : struct_members
    endforeach

    # Compiler flags
    -if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
    +if cc.get_id() == 'gcc' or cc.get_id() == 'clang' or cc.get_id() == 'emscripten'
    warning_c_args = [
    '-Wduplicated-branches',
    '-Wimplicit-fallthrough',
    @@ -1327,13 +1327,13 @@ g_sizet_compatibility = {
    'long long': sizet_size == long_long_size,
    }

    -# Do separate checks for gcc/clang (and ignore other compilers for now), since
    -# we need to explicitly pass -Werror to the compilers.
    +# Do separate checks for gcc/clang/emscripten (and ignore other compilers for now),
    +# since we need to explicitly pass -Werror to the compilers.
    # FIXME: https://github.com/mesonbuild/meson/issues/5399
    # We can’t simplify these checks using a foreach loop because dictionary keys
    # have to be string literals.
    # FIXME: https://github.com/mesonbuild/meson/issues/5231
    -if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
    +if cc.get_id() == 'gcc' or cc.get_id() == 'clang' or cc.get_id() == 'emscripten'
    g_sizet_compatibility += {
    'short': g_sizet_compatibility['short'] and cc.compiles(
    '''#include <stddef.h>

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 20 Sep 2019 16:05:00 +0200
    Subject: [PATCH 6/8] Fix function pointer cast issues

    It is undefined behavior in C and C++ to cast a function pointer
    to another type and call it that way. This does work in most native
    platforms, however, despite it being UB, but in WASM it can fail.

    See:
    https://emscripten.org/docs/porting/guidelines/function_pointer_issues.html

    Upstream-Status: Pending

    diff --git a/gobject/gobject.c b/gobject/gobject.c
    index 1111111..2222222 100644
    --- a/gobject/gobject.c
    +++ b/gobject/gobject.c
    @@ -189,7 +189,8 @@ G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, qdata) == G_STRUCT_OFFSET(GObjectReal,
    /* --- prototypes --- */
    static void g_object_base_class_init (GObjectClass *class);
    static void g_object_base_class_finalize (GObjectClass *class);
    -static void g_object_do_class_init (GObjectClass *class);
    +static void g_object_do_class_init (GObjectClass *class,
    + gpointer dummy);
    static void g_object_init (GObject *object,
    GObjectClass *class);
    static GObject* g_object_constructor (GType type,
    @@ -496,7 +497,7 @@ g_object_base_class_finalize (GObjectClass *class)
    }

    static void
    -g_object_do_class_init (GObjectClass *class)
    +g_object_do_class_init (GObjectClass *class, gpointer dummy)
    {
    /* read the comment about typedef struct CArray; on why not to change this quark */
    quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
    diff --git a/gobject/gparam.h b/gobject/gparam.h
    index 1111111..2222222 100644
    --- a/gobject/gparam.h
    +++ b/gobject/gparam.h
    @@ -378,7 +378,8 @@ struct _GParamSpecTypeInfo
    /* type system portion */
    guint16 instance_size; /* obligatory */
    guint16 n_preallocs; /* optional */
    - void (*instance_init) (GParamSpec *pspec); /* optional */
    + void (*instance_init) (GParamSpec *pspec, /* optional */
    + gpointer data);

    /* class portion */
    GType value_type; /* obligatory */
    diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c
    index 1111111..2222222 100644
    --- a/gobject/gparamspecs.c
    +++ b/gobject/gparamspecs.c
    @@ -59,7 +59,7 @@

    /* --- param spec functions --- */
    static void
    -param_char_init (GParamSpec *pspec)
    +param_char_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);

    @@ -88,7 +88,7 @@ param_char_validate (GParamSpec *pspec,
    }

    static void
    -param_uchar_init (GParamSpec *pspec)
    +param_uchar_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);

    @@ -135,7 +135,7 @@ param_boolean_validate (GParamSpec *pspec,
    }

    static void
    -param_int_init (GParamSpec *pspec)
    +param_int_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);

    @@ -175,7 +175,7 @@ param_int_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_uint_init (GParamSpec *pspec)
    +param_uint_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);

    @@ -215,7 +215,7 @@ param_uint_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_long_init (GParamSpec *pspec)
    +param_long_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);

    @@ -260,7 +260,7 @@ param_long_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_ulong_init (GParamSpec *pspec)
    +param_ulong_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);

    @@ -304,7 +304,7 @@ param_ulong_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_int64_init (GParamSpec *pspec)
    +param_int64_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);

    @@ -344,7 +344,7 @@ param_int64_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_uint64_init (GParamSpec *pspec)
    +param_uint64_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);

    @@ -384,7 +384,7 @@ param_uint64_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_unichar_init (GParamSpec *pspec)
    +param_unichar_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);

    @@ -426,7 +426,7 @@ param_unichar_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_enum_init (GParamSpec *pspec)
    +param_enum_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);

    @@ -471,7 +471,7 @@ param_enum_validate (GParamSpec *pspec,
    }

    static void
    -param_flags_init (GParamSpec *pspec)
    +param_flags_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);

    @@ -517,7 +517,7 @@ param_flags_validate (GParamSpec *pspec,
    }

    static void
    -param_float_init (GParamSpec *pspec)
    +param_float_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);

    @@ -560,7 +560,7 @@ param_float_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_double_init (GParamSpec *pspec)
    +param_double_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);

    @@ -603,7 +603,7 @@ param_double_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_string_init (GParamSpec *pspec)
    +param_string_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);

    @@ -711,7 +711,7 @@ param_string_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_param_init (GParamSpec *pspec)
    +param_param_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
    }
    @@ -742,7 +742,7 @@ param_param_validate (GParamSpec *pspec,
    }

    static void
    -param_boxed_init (GParamSpec *pspec)
    +param_boxed_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
    }
    @@ -780,7 +780,7 @@ param_boxed_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_pointer_init (GParamSpec *pspec)
    +param_pointer_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
    }
    @@ -816,7 +816,7 @@ param_pointer_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_value_array_init (GParamSpec *pspec)
    +param_value_array_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);

    @@ -967,7 +967,7 @@ param_value_array_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_object_init (GParamSpec *pspec)
    +param_object_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
    }
    @@ -1011,7 +1011,7 @@ param_object_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_override_init (GParamSpec *pspec)
    +param_override_init (GParamSpec *pspec, gpointer dummy)
    {
    /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
    }
    @@ -1060,7 +1060,7 @@ param_override_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_gtype_init (GParamSpec *pspec)
    +param_gtype_init (GParamSpec *pspec, gpointer dummy)
    {
    }

    @@ -1104,7 +1104,7 @@ param_gtype_values_cmp (GParamSpec *pspec,
    }

    static void
    -param_variant_init (GParamSpec *pspec)
    +param_variant_init (GParamSpec *pspec, gpointer dummy)
    {
    GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);

    diff --git a/gobject/gtype.h b/gobject/gtype.h
    index 1111111..2222222 100644
    --- a/gobject/gtype.h
    +++ b/gobject/gtype.h
    @@ -1958,7 +1958,8 @@ guint g_type_get_type_registration_serial (void);
    */
    #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    -static void type_name##_class_intern_init (gpointer klass) \
    +static void type_name##_class_intern_init (gpointer klass, \
    + gpointer dummy) \
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    if (TypeName##_private_offset != 0) \
    @@ -1968,7 +1969,8 @@ static void type_name##_class_intern_init (gpointer klass) \

    #else
    #define _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
    -static void type_name##_class_intern_init (gpointer klass) \
    +static void type_name##_class_intern_init (gpointer klass, \
    + gpointer dummy) \
    { \
    type_name##_parent_class = g_type_class_peek_parent (klass); \
    type_name##_class_init ((TypeName##Class*) klass); \
    @@ -1980,6 +1982,11 @@ static void type_name##_class_intern_init (gpointer klass) \
    \
    static void type_name##_init (TypeName *self); \
    static void type_name##_class_init (TypeName##Class *klass); \
    +static void type_name##_init_adapter (TypeName *self, \
    + gpointer dummy) \
    +{ \
    + type_name##_init (self); \
    +} \
    static GType type_name##_get_type_once (void); \
    static gpointer type_name##_parent_class = NULL; \
    static gint TypeName##_private_offset; \
    @@ -2019,7 +2026,7 @@ type_name##_get_type_once (void) \
    sizeof (TypeName##Class), \
    (GClassInitFunc)(void (*)(void)) type_name##_class_intern_init, \
    sizeof (TypeName), \
    - (GInstanceInitFunc)(void (*)(void)) type_name##_init, \
    + (GInstanceInitFunc)(void (*)(void)) type_name##_init_adapter, \
    (GTypeFlags) flags); \
    { /* custom code follows */
    #define _G_DEFINE_TYPE_EXTENDED_END() \
    diff --git a/gobject/gtypemodule.h b/gobject/gtypemodule.h
    index 1111111..2222222 100644
    --- a/gobject/gtypemodule.h
    +++ b/gobject/gtypemodule.h
    @@ -209,7 +209,7 @@ type_name##_register_type (GTypeModule *type_module) \
    NULL, /* class_data */ \
    sizeof (TypeName), \
    0, /* n_preallocs */ \
    - (GInstanceInitFunc)(void (*)(void)) type_name##_init, \
    + (GInstanceInitFunc)(void (*)(void)) type_name##_init_adapter, \
    NULL /* value_table */ \
    }; \
    type_name##_type_id = g_type_module_register_type (type_module, \

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Fri, 15 Nov 2019 11:00:00 +0100
    Subject: [PATCH 7/8] Implement g_get_num_processors for Emscripten

    Upstream-Status: Pending

    diff --git a/glib/gthread.c b/glib/gthread.c
    index 1111111..2222222 100644
    --- a/glib/gthread.c
    +++ b/glib/gthread.c
    @@ -54,6 +54,11 @@
    #include <windows.h>
    #endif /* G_OS_WIN32 */

    +#ifdef __EMSCRIPTEN__
    +#include <emscripten.h>
    +#include <emscripten/threading.h>
    +#endif /*__EMSCRIPTEN__*/
    +
    #include "gslice.h"
    #include "gstrfuncs.h"
    #include "gtestutils.h"
    @@ -1045,7 +1050,9 @@ g_thread_self (void)
    guint
    g_get_num_processors (void)
    {
    -#ifdef G_OS_WIN32
    +#ifdef __EMSCRIPTEN__
    + return emscripten_num_logical_cores();
    +#elif defined G_OS_WIN32
    unsigned int count;
    SYSTEM_INFO sysinfo;
    DWORD_PTR process_cpus;

    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Kleis Auke Wolthuizen <[email protected]>
    Date: Tue, 8 Oct 2019 11:30:00 +0200
    Subject: [PATCH 8/8] Do not build executables

    We're only interested in the libraries.

    Upstream-Status: Inappropriate [disable feature]
    This patch is just for our convenience.

    diff --git a/gio/meson.build b/gio/meson.build
    index 1111111..2222222 100644
    --- a/gio/meson.build
    +++ b/gio/meson.build
    @@ -886,99 +886,6 @@ gconstructor_as_data_h = custom_target('gconstructor_as_data.h',
    output : ['gconstructor_as_data.h'],
    command : [python, '@INPUT0@', '@INPUT1@', 'gconstructor_code', '@OUTPUT@'])

    -# Several installed executables
    -gio_tool_sources = [
    - 'gio-tool.c',
    - 'gio-tool.h',
    - 'gio-tool-cat.c',
    - 'gio-tool-copy.c',
    - 'gio-tool-info.c',
    - 'gio-tool-list.c',
    - 'gio-tool-mime.c',
    - 'gio-tool-mkdir.c',
    - 'gio-tool-monitor.c',
    - 'gio-tool-mount.c',
    - 'gio-tool-move.c',
    - 'gio-tool-open.c',
    - 'gio-tool-rename.c',
    - 'gio-tool-remove.c',
    - 'gio-tool-save.c',
    - 'gio-tool-set.c',
    - 'gio-tool-trash.c',
    - 'gio-tool-tree.c',
    -]
    -
    -executable('gio', gio_tool_sources,
    - install : true,
    - c_args : gio_c_args,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -
    -executable('gresource', 'gresource-tool.c',
    - install : true,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    - dependencies : [libelf, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -
    -gio_querymodules = executable('gio-querymodules', 'gio-querymodules.c', 'giomodule-priv.c',
    - install : true,
    - c_args : gio_c_args,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -
    -glib_compile_schemas = executable('glib-compile-schemas',
    - [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-schemas.c'],
    - install : true,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -
    -glib_compile_resources = executable('glib-compile-resources',
    - [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-resources.c'],
    - install : true,
    - c_args : gio_c_args,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -
    -# Cannot override those programs in cross compilation case because they are
    -# native executables that cannot be run on the build machine.
    -# See https://gitlab.gnome.org/GNOME/glib/issues/1859.
    -if not meson.is_cross_build()
    - meson.override_find_program('glib-compile-schemas', glib_compile_schemas)
    - meson.override_find_program('glib-compile-resources', glib_compile_resources)
    -endif
    -
    -executable('gsettings', 'gsettings-tool.c',
    - install : true,
    - c_args : gio_c_args,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -install_data('gschema.dtd',
    - install_dir : join_paths(get_option('datadir'), schemas_subdir))
    -
    -install_data(['gschema.loc', 'gschema.its'],
    - install_dir : join_paths(get_option('datadir'), 'gettext/its'))
    -
    -executable('gdbus', 'gdbus-tool.c',
    - install : true,
    - c_args : gio_c_args,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -
    -if host_system != 'windows' and not glib_have_cocoa
    - executable('gapplication', 'gapplication-tool.c',
    - install : true,
    - c_args : gio_c_args,
    - # intl.lib is not compatible with SAFESEH
    - link_args : noseh_link_args,
    - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep])
    -endif
    -
    if enable_systemtap
    gio_stp = configure_file(input : 'gio.stp.in',
    output : '@[email protected]'.format(libgio.full_path().split('/').get(-1)),
    diff --git a/glib/meson.build b/glib/meson.build
    index 1111111..2222222 100644
    --- a/glib/meson.build
    +++ b/glib/meson.build
    @@ -394,7 +394,7 @@ if host_system == 'windows'
    include_directories : configinc,
    dependencies : [libglib_dep])
    endif
    -else
    +elif host_system != 'emscripten'
    gtester = executable('gtester', 'gtester.c',
    install : true,
    c_args : ['-UG_DISABLE_ASSERT'],
    diff --git a/gobject/meson.build b/gobject/meson.build
    index 1111111..2222222 100644
    --- a/gobject/meson.build
    +++ b/gobject/meson.build
    @@ -143,10 +143,6 @@ libgobject_dep = declare_dependency(link_with : libgobject,
    include_directories : [gobjectinc],
    dependencies : [libglib_dep, glib_enumtypes_dep])

    -executable('gobject-query', 'gobject-query.c',
    - install : true,
    - dependencies : [libglib_dep, libgobject_dep])
    -
    install_data('gobject_gdb.py', install_dir : join_paths(glib_pkgdatadir, 'gdb'))
    gdb_conf = configuration_data()
    gdb_conf.set('datadir', glib_datadir)
    diff --git a/meson.build b/meson.build
    index 1111111..2222222 100644
    --- a/meson.build
    +++ b/meson.build
    @@ -2167,7 +2167,6 @@ subdir('gobject')
    subdir('gthread')
    subdir('gmodule')
    subdir('gio')
    -subdir('fuzzing')
    if build_tests
    subdir('tests')
    endif
    334 changes: 334 additions & 0 deletions libffi-emscripten.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,334 @@
    From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
    From: Brion Vibber <[email protected]>
    Date: Sat, 5 May 2018 17:28:06 -0700
    Subject: [PATCH 1/1] Work in progress: wasm32 support for libffi

    See: https://github.com/brion/libffi/commits/emscripten-work

    Upstream-Status: Pending

    diff --git a/Makefile.am b/Makefile.am
    index 1111111..2222222 100644
    --- a/Makefile.am
    +++ b/Makefile.am
    @@ -72,6 +72,7 @@ noinst_HEADERS = \
    src/sparc/ffitarget.h src/sparc/internal.h \
    src/tile/ffitarget.h \
    src/vax/ffitarget.h \
    + src/wasm32/ffitarget.h \
    src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h src/x86/asmnames.h \
    src/xtensa/ffitarget.h \
    src/dlmalloc.c
    @@ -99,7 +100,8 @@ EXTRA_libffi_la_SOURCES = src/aarch64/ffi.c src/aarch64/sysv.S \
    src/s390/sysv.S src/sh/ffi.c src/sh/sysv.S src/sh64/ffi.c \
    src/sh64/sysv.S src/sparc/ffi.c src/sparc/ffi64.c \
    src/sparc/v8.S src/sparc/v9.S src/tile/ffi.c src/tile/tile.S \
    - src/vax/ffi.c src/vax/elfbsd.S src/x86/ffi.c src/x86/sysv.S \
    + src/vax/ffi.c src/vax/elfbsd.S src/wasm32/ffi.c \
    + src/x86/ffi.c src/x86/sysv.S \
    src/x86/ffiw64.c src/x86/win64.S src/x86/ffi64.c \
    src/x86/unix64.S src/x86/sysv_intel.S src/x86/win64_intel.S \
    src/xtensa/ffi.c src/xtensa/sysv.S
    diff --git a/configure.host b/configure.host
    index 1111111..2222222 100644
    --- a/configure.host
    +++ b/configure.host
    @@ -244,6 +244,11 @@ case "${host}" in
    SOURCES="ffi.c elfbsd.S"
    ;;

    + wasm32-*-*)
    + TARGET=wasm32; TARGETDIR=wasm32
    + SOURCES="ffi.c"
    + ;;
    +
    xtensa*-*)
    TARGET=XTENSA; TARGETDIR=xtensa
    SOURCES="ffi.c sysv.S"
    diff --git a/src/wasm32/ffi.c b/src/wasm32/ffi.c
    new file mode 100644
    index 1111111..2222222
    --- /dev/null
    +++ b/src/wasm32/ffi.c
    @@ -0,0 +1,168 @@
    +/* -----------------------------------------------------------------------
    + ffi.c - Copyright (c) 2018 Brion Vibber
    +
    + wasm32/emscripten Foreign Function Interface
    +
    + Permission is hereby granted, free of charge, to any person obtaining
    + a copy of this software and associated documentation files (the
    + ``Software''), to deal in the Software without restriction, including
    + without limitation the rights to use, copy, modify, merge, publish,
    + distribute, sublicense, and/or sell copies of the Software, and to
    + permit persons to whom the Software is furnished to do so, subject to
    + the following conditions:
    +
    + The above copyright notice and this permission notice shall be included
    + in all copies or substantial portions of the Software.
    +
    + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
    + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    + DEALINGS IN THE SOFTWARE.
    + ----------------------------------------------------------------------- */
    +
    +#include <ffi.h>
    +#include <ffi_common.h>
    +#include <stdint.h>
    +#include <stdlib.h>
    +
    +#include <emscripten/emscripten.h>
    +
    +ffi_status FFI_HIDDEN
    +ffi_prep_cif_machdep(ffi_cif *cif)
    +{
    + return FFI_OK;
    +}
    +
    +EM_JS(void, ffi_call, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue), {
    + var cif_abi = HEAPU32[cif >> 2];
    + var cif_nargs = HEAPU32[(cif + 4) >> 2];
    + var cif_arg_types = HEAPU32[(cif + 8) >> 2];
    + var cif_rtype = HEAPU32[(cif + 12) >> 2];
    +
    + // emscripten/wasm function pointers are indirected through a table,
    + // which is further subdivided by function signature -- each pointer
    + // must be added to a constant to find its real sig. This doesn't seem
    + // to be a strict wasm requirement, but is a leftover from asm.js
    + // which used separate arrays for each signature.
    + //
    + // This is neatly encapsulated into dynCall_* wrapper functions for us,
    + // which take a function pointer as first parameter and pass the rest on.
    + //
    + // Generate an emscripten call signature and look up the correct wrapper
    + // via name here...
    + var args = [fn];
    + var sig;
    + var sigFloat = Module['wasmMemory'] ? 'f' : 'd';
    +
    + var rtype = HEAPU16[(cif_rtype + 6 /* rtype->type*/ ) >> 1];
    + //console.error('rtype is', rtype);
    + if (rtype === /* FFI_TYPE_VOID */ 0) {
    + sig = 'v';
    + } else if (rtype === /* FFI_TYPE_INT */ 1 ||
    + rtype === /* FFI_TYPE_UINT8 */ 5 ||
    + rtype === /* FFI_TYPE_SINT8 */ 6 ||
    + rtype === /* FFI_TYPE_UINT16 */ 7 ||
    + rtype === /* FFI_TYPE_SINT16 */ 8 ||
    + rtype === /* FFI_TYPE_UINT32 */ 9 ||
    + rtype === /* FFI_TYPE_SINT32 */ 10 ||
    + rtype === /* FFI_TYPE_POINTER */ 14) {
    + sig = 'i';
    + } else if (rtype === /* FFI_TYPE_FLOAT */ 2) {
    + sig = sigFloat;
    + } else if (rtype === /* FFI_TYPE_DOUBLE */ 3 ||
    + rtype === /* FFI_TYPE_LONGDOUBLE */ 4) {
    + sig = 'd';
    + } else if (rtype === /* FFI_TYPE_UINT64 */ 11 ||
    + rtype === /* FFI_TYPE_SINT64 */ 12) {
    + // Warning: returns a truncated 32-bit integer directly.
    + // High bits are in $tempRet0
    + sig = 'j';
    + } else if (rtype === /* FFI_TYPE_STRUCT */ 13) {
    + throw new Error('struct ret marshalling nyi');
    + } else if (rtype === /* FFI_TYPE_COMPLEX */ 15) {
    + throw new Error('complex ret marshalling nyi');
    + } else {
    + throw new Error('Unexpected rtype ' + rtype);
    + }
    +
    + for (var i = 0; i < cif_nargs; i++) {
    + var ptr = HEAPU32[(avalue >> 2) + i];
    +
    + var arg_type = HEAPU32[(cif_arg_types >> 2) + i];
    + var typ = HEAPU16[(arg_type + 6) >> 1];
    +
    + if (typ === /* FFI_TYPE_INT*/ 1 || typ === /* FFI_TYPE_SINT32 */ 10) {
    + args.push(HEAP32[ptr >> 2]);
    + sig += 'i';
    + } else if (typ === /* FFI_TYPE_FLOAT */ 2) {
    + args.push(HEAPF32[ptr >> 2]);
    + sig += sigFloat;
    + } else if (typ === /* FFI_TYPE_DOUBLE */ 3 || typ === /* FFI_TYPE_LONGDOUBLE */ 4) {
    + args.push(HEAPF64[ptr >> 3]);
    + sig += 'd';
    + } else if (typ === /* FFI_TYPE_UINT8*/ 5) {
    + args.push(HEAPU8[ptr]);
    + sig += 'i';
    + } else if (typ === /* FFI_TYPE_SINT8 */ 6) {
    + args.push(HEAP8[ptr]);
    + sig += 'i';
    + } else if (typ === /* FFI_TYPE_UINT16 */ 7) {
    + args.push(HEAPU16[ptr >> 1]);
    + sig += 'i';
    + } else if (typ === /* FFI_TYPE_SINT16 */ 8) {
    + args.push(HEAP16[ptr >> 1]);
    + sig += 'i';
    + } else if (typ === /* FFI_TYPE_UINT32 */ 9 || typ === /* FFI_TYPE_POINTER */ 14) {
    + args.push(HEAPU32[ptr >> 2]);
    + sig += 'i';
    + } else if (typ === /* FFI_TYPE_UINT64 */ 11 || typ === /* FFI_TYPE_SINT64 */ 12) {
    + // LEGALIZE_JS_FFI mode splits i64 (j) into two i32 args
    + // for compatibility with JavaScript's f64-based numbers.
    + args.push(HEAPU32[ptr >> 2]);
    + args.push(HEAPU32[(ptr + 4) >> 2]);
    + sig += 'j';
    + } else if (typ === /* FFI_TYPE_STRUCT */ 13) {
    + throw new Error('struct marshalling nyi');
    + } else if (typ === /* FFI_TYPE_COMPLEX */ 15) {
    + throw new Error('complex marshalling nyi');
    + } else {
    + throw new Error('Unexpected type ' + typ);
    + }
    + }
    +
    + var func = Module['dynCall_' + sig];
    + if (func) {
    + var result = func.apply(null, args);
    + } else {
    + throw new Error('invalid function pointer in ffi_call');
    + }
    +
    + if (rtype === 0) {
    + // void
    + } else if (rtype === 1 || rtype === 9 || rtype === 10 || rtype === 14) {
    + HEAP32[rvalue >> 2] = result;
    + } else if (rtype === 2) {
    + HEAPF32[rvalue >> 2] = result;
    + } else if (rtype === 3 || rtype === 4) {
    + HEAPF64[rvalue >> 3] = result;
    + } else if (rtype === 5 || rtype === 6) {
    + HEAP8[rvalue] = result;
    + } else if (rtype === 7 || rtype === 8) {
    + HEAP16[rvalue >> 1] = result;
    + } else if (rtype === 11 || rtype === 12) {
    + // Warning: returns a truncated 32-bit integer directly.
    + // High bits are in $tempRet0
    + HEAP32[rvalue >> 2] = result;
    + HEAP32[(rvalue + 4) >> 2] = Module.getTempRet0();
    + } else if (rtype === 13) {
    + throw new Error('struct ret marshalling nyi');
    + } else if (rtype === 15) {
    + throw new Error('complex ret marshalling nyi');
    + } else {
    + throw new Error('Unexpected rtype ' + rtype);
    + }
    +});
    diff --git a/src/wasm32/ffitarget.h b/src/wasm32/ffitarget.h
    new file mode 100644
    index 1111111..2222222
    --- /dev/null
    +++ b/src/wasm32/ffitarget.h
    @@ -0,0 +1,59 @@
    +/* -----------------------------------------------------------------*-C-*-
    + ffitarget.h - Copyright (c) 2018 Brion Vibber
    + Target configuration macros for wasm32.
    +
    + Permission is hereby granted, free of charge, to any person obtaining
    + a copy of this software and associated documentation files (the
    + ``Software''), to deal in the Software without restriction, including
    + without limitation the rights to use, copy, modify, merge, publish,
    + distribute, sublicense, and/or sell copies of the Software, and to
    + permit persons to whom the Software is furnished to do so, subject to
    + the following conditions:
    +
    + The above copyright notice and this permission notice shall be included
    + in all copies or substantial portions of the Software.
    +
    + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
    + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    + DEALINGS IN THE SOFTWARE.
    +
    + ----------------------------------------------------------------------- */
    +
    +#ifndef LIBFFI_TARGET_H
    +#define LIBFFI_TARGET_H
    +
    +#ifndef LIBFFI_H
    +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
    +#endif
    +
    +/* ---- Generic type definitions ----------------------------------------- */
    +
    +typedef unsigned long ffi_arg;
    +typedef signed long ffi_sarg;
    +
    +// TODO: https://github.com/emscripten-core/emscripten/issues/9868
    +typedef void (*ffi_fp)(void);
    +
    +typedef enum ffi_abi {
    + FFI_FIRST_ABI = 0,
    + FFI_WASM32, // "raw", no structures or varargs
    + FFI_WASM32_EMSCRIPTEN, // structures, varargs, and split 64-bit params
    + FFI_LAST_ABI,
    +#ifdef EMSCRIPTEN
    + FFI_DEFAULT_ABI = FFI_WASM32_EMSCRIPTEN
    +#else
    + FFI_DEFAULT_ABI = FFI_WASM32
    +#endif
    +} ffi_abi;
    +
    +#define FFI_CLOSURES 0
    +#define FFI_GO_CLOSURES 0
    +#define FFI_TRAMPOLINE_SIZE 24
    +#define FFI_NATIVE_RAW_API 0
    +
    +#endif
    diff --git a/testsuite/lib/libffi.exp b/testsuite/lib/libffi.exp
    index 1111111..2222222 100644
    --- a/testsuite/lib/libffi.exp
    +++ b/testsuite/lib/libffi.exp
    @@ -216,6 +216,13 @@ proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } {
    set output_match [lreplace $output_match 1 1 $x]
    }

    + if { [ istarget wasm32-* ] } {
    + # emscripten will get confused if told to build as .exe
    + set exec_suffix ""
    + } else {
    + set exec_suffix ".exe"
    + }
    +
    # Set up the compiler flags, based on what we're going to do.

    set options [list]
    @@ -226,7 +233,7 @@ proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } {
    }
    "link" {
    set compile_type "executable"
    - set output_file "[file rootname [file tail $prog]].exe"
    + set output_file "[file rootname [file tail $prog]]$exec_suffix"
    # The following line is needed for targets like the i960 where
    # the default output file is b.out. Sigh.
    }
    @@ -235,7 +242,7 @@ proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } {
    # FIXME: "./" is to cope with "." not being in $PATH.
    # Should this be handled elsewhere?
    # YES.
    - set output_file "./[file rootname [file tail $prog]].exe"
    + set output_file "./[file rootname [file tail $prog]]$exec_suffix"
    # This is the only place where we care if an executable was
    # created or not. If it was, dg.exp will try to run it.
    remote_file build delete $output_file;
    @@ -405,6 +412,11 @@ proc libffi_target_compile { source dest type options } {
    lappend options "libs= -lpthread"
    }

    + if { [string match "wasm32-*" $target_triplet] } {
    + # emscripten sometimes doesn't see the filesystem which breaks the tests using stdout
    + lappend options "additional_flags=-s FORCE_FILESYSTEM=1"
    + }
    +
    verbose "options: $options"
    return [target_compile $source $dest $type $options]
    }