Merge pull request #5428 from kumpera/wasm-support-p2
authorRodrigo Kumpera <kumpera@users.noreply.github.com>
Fri, 8 Sep 2017 18:55:38 +0000 (14:55 -0400)
committerGitHub <noreply@github.com>
Fri, 8 Sep 2017 18:55:38 +0000 (14:55 -0400)
Mono Wasm support

28 files changed:
configure.ac
mono/eglib/eglib-config.h.in
mono/eglib/gpath.c
mono/metadata/object.c
mono/mini/Makefile.am.in
mono/mini/aot-runtime-wasm.c [new file with mode: 0644]
mono/mini/aot-runtime.c
mono/mini/cpu-wasm.md [new file with mode: 0644]
mono/mini/driver.c
mono/mini/exceptions-wasm.c [new file with mode: 0644]
mono/mini/genmdesc.pl [changed mode: 0644->0755]
mono/mini/interp/interp.c
mono/mini/interp/interp.h
mono/mini/jit.h
mono/mini/mini-arch.h
mono/mini/mini-exceptions.c
mono/mini/mini-wasm.c [new file with mode: 0644]
mono/mini/mini-wasm.h [new file with mode: 0644]
mono/mini/mini.h
mono/mini/trace.c
mono/mini/tramp-wasm.c [new file with mode: 0644]
mono/sgen/sgen-conf.h
mono/sgen/sgen-gc.c
mono/sgen/sgen-marksweep.c
mono/utils/mono-dl-posix.c
mono/utils/mono-threads-coop.c
mono/utils/mono-threads-wasm.c
mono/utils/networking-missing.c

index c2d59d88407f5e0cfbdff1ac84cbdce31ff8aef2..bad8ecc8e3c8d08b5978acdf663d81535eb076be 100644 (file)
@@ -117,8 +117,8 @@ host_darwin=no
 
 
 if test "x$enable_wasm" = "xyes"; then
-CFLAGS="$CFLAGS -D_REENTRANT -D_GNU_SOURCE -DNO_UNALIGNED_ACCESS -s WASM=1 -DWASM -Os"
-CPPFLAGS="$CPPFLAGS -D_REENTRANT -DUSE_MMAP -D_GNU_SOURCE -DNO_UNALIGNED_ACCESS -s WASM=1 -DWASM -Os"
+CFLAGS="$CFLAGS -D_REENTRANT -D_GNU_SOURCE -DNO_UNALIGNED_ACCESS -s WASM=1"
+CPPFLAGS="$CPPFLAGS -D_REENTRANT -DUSE_MMAP -D_GNU_SOURCE -DNO_UNALIGNED_ACCESS -s WASM=1"
 libdl="-ldl"
 libgc_threads=pthreads
 
@@ -555,7 +555,18 @@ AC_CHECK_FUNCS(_finite, , AC_MSG_CHECKING(for _finite in math.h)
 AC_CHECK_HEADERS(linux/magic.h)
 
 # not 64 bit clean in cross-compile
-AC_CHECK_SIZEOF(void *, 4)
+if test "x$enable_wasm" = "xyes"; then
+AC_DEFINE(SIZEOF_VOID_P,4)
+AC_DEFINE(SIZEOF_LONG,4)
+ac_cv_sizeof_void_p="4"
+ac_cv_sizeof_long="4"
+else
+AC_CHECK_SIZEOF(void *)
+AC_CHECK_SIZEOF(long)
+fi
+
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long long)
 
 AC_CACHE_CHECK([for clang],
        mono_cv_clang,[
@@ -3067,6 +3078,7 @@ TARGET=WASM
 HOST=WASM
 arch_target=wasm
 AC_DEFINE(TARGET_WASM, 1, [Target wasm])
+AC_DEFINE(HOST_WASM, 1, [Host wasm])
 BTLS_SUPPORTED=no
 with_tls=pthread
 target_mach=no
@@ -3752,10 +3764,6 @@ AC_SUBST(PIDTYPE)
 AC_DEFINE(HAVE_CLASSIC_WINAPI_SUPPORT, 1, [Use classic Windows API support])
 AC_DEFINE(HAVE_UWP_WINAPI_SUPPORT, 0, [Don't use UWP Windows API support])
 
-AC_CHECK_SIZEOF(int)
-AC_CHECK_SIZEOF(void *)
-AC_CHECK_SIZEOF(long)
-AC_CHECK_SIZEOF(long long)
 AC_CHECK_FUNCS(strlcpy stpcpy strtok_r rewinddir vasprintf strerror_r)
 AC_CHECK_FUNCS(getrlimit)
 AC_CHECK_FUNCS(fork execv execve)
@@ -4342,6 +4350,7 @@ AM_CONDITIONAL(POWERPC64, test x$TARGET = xPOWERPC64)
 AM_CONDITIONAL(ARM, test x$TARGET = xARM)
 AM_CONDITIONAL(ARM64, test x$TARGET = xARM64)
 AM_CONDITIONAL(S390X, test x$TARGET = xS390X)
+AM_CONDITIONAL(WASM, test x$TARGET = xWASM)
 AM_CONDITIONAL(HOST_X86, test x$HOST = xX86)
 AM_CONDITIONAL(HOST_AMD64, test x$HOST = xAMD64)
 AM_CONDITIONAL(HOST_ARM, test x$HOST = xARM)
index 71797575e685c1107665e4eb14481f1fcb3a796f..26e48fd3490604163234891c3852203c5449f507 100644 (file)
@@ -37,6 +37,11 @@ typedef signed   @GSIZE@ gssize;
 #define G_BREAKPOINT()
 #endif
 
+#if defined (HOST_WASM)
+#undef G_BREAKPOINT
+#define G_BREAKPOINT() do { printf ("MONO: BREAKPOINT\n"); abort (); } while (0)
+#endif
+
 typedef @PIDTYPE@ GPid;
 
 #endif
index 59f5923125bffef92db3ff085e4d4ac12773cbd6..21e7770460345029bb2dea2ddd6a56eca8c7f57f 100644 (file)
@@ -160,7 +160,8 @@ g_path_get_basename (const char *filename)
        return g_strdup (&r[1]);
 }
 
-#ifndef HAVE_STRTOK_R
+//wasm does have strtok_r even though autoconf fails to find
+#if !defined (HAVE_STRTOK_R) && !defined (HOST_WASM)
 // This is from BSD's strtok_r
 
 char *
index 38dfb764e46f92ef329aed59ab559b4c070a3faf..2ea88c75f8cfde20ecb362453f027e16dbe1225a 100644 (file)
@@ -5257,8 +5257,9 @@ mono_object_new_checked (MonoDomain *domain, MonoClass *klass, MonoError *error)
 
        MonoVTable *vtable;
 
-       vtable = mono_class_vtable (domain, klass);
-       g_assert (vtable); /* FIXME don't swallow the error */
+       vtable = mono_class_vtable_full (domain, klass, error);
+       if (!is_ok (error))
+               return NULL;
 
        MonoObject *o = mono_object_new_specific_checked (vtable, error);
        return o;
index e33441b6d35a4218910e493ff5375292217e37b7..28fb9ee5b8d2fdbc6a19ed9ea8541ad4814c313b 100755 (executable)
@@ -312,6 +312,12 @@ genmdesc_LDADD = \
        $(GLIB_LIBS)                                    \
        $(LIBICONV)
 
+wasm_sources = \
+       mini-wasm.c             \
+       mini-wasm.h             \
+       exceptions-wasm.c       \
+       tramp-wasm.c
+
 x86_sources = \
        mini-x86.c              \
        mini-x86.h              \
@@ -456,6 +462,7 @@ common_sources = \
        aot-compiler.h          \
        aot-compiler.c          \
        aot-runtime.c           \
+       aot-runtime-wasm.c      \
        graph.c                 \
        mini-codegen.c          \
        mini-exceptions.c       \
@@ -541,6 +548,12 @@ endif
 
 regtests = $(filter-out $(regtests_DISABLED),$(regtests_UNIVERSAL))
 
+if WASM
+arch_sources = $(wasm_sources)
+arch_built=cpu-wasm.h
+arch_define=__wasm__
+endif
+
 if X86
 arch_sources = $(x86_sources)
 arch_built=cpu-x86.h
@@ -687,12 +700,20 @@ GENMDESC_OPTS=
 # build dependency for the poor windows users
 # $(arch_define) is the preprocessor symbol that enables all the opcodes
 # for the specific platform in mini-ops.h
+
 if CROSS_COMPILING
 GENMDESC_PRG=perl $(srcdir)/genmdesc.pl $(arch_define) $(srcdir) $(GENMDESC_OPTS)
-else !CROSS_COMPILING
+else
+if WASM
+GENMDESC_PRG=perl $(srcdir)/genmdesc.pl $(arch_define) $(srcdir) $(GENMDESC_OPTS)
+else
 GENMDESC_PRG=./genmdesc $(GENMDESC_OPTS)
+endif
 endif !CROSS_COMPILING
 
+cpu-wasm.h: cpu-wasm.md genmdesc$(EXEEXT)
+       $(GENMDESC_PRG) cpu-wasm.h wasm_desc $(srcdir)/cpu-wasm.md
+
 cpu-x86.h: cpu-x86.md genmdesc$(EXEEXT)
        $(GENMDESC_PRG) cpu-x86.h x86_desc $(srcdir)/cpu-x86.md
 
@@ -882,6 +903,7 @@ EXTRA_DIST = TestDriver.cs \
        TestHelpers.cs \
        genmdesc.pl                             \
        $(test_sources)                         \
+       $(wasm_sources) cpu-wasm.md             \
        $(x86_sources) cpu-x86.md               \
        $(amd64_sources) cpu-amd64.md           \
        $(ppc_sources) cpu-ppc.md cpu-ppc64.md  \
diff --git a/mono/mini/aot-runtime-wasm.c b/mono/mini/aot-runtime-wasm.c
new file mode 100644 (file)
index 0000000..4fb8906
--- /dev/null
@@ -0,0 +1,408 @@
+/**
+ * \file
+ * WASM AOT runtime
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#include "mini.h"
+#include "interp/interp.h"
+
+#ifdef TARGET_WASM
+
+static void
+wasm_restore_context (void)
+{
+       g_error ("wasm_restore_context");
+}
+
+static void
+wasm_call_filter (void)
+{
+       g_error ("wasm_call_filter");
+}
+
+static void
+wasm_throw_exception (void)
+{
+       g_error ("wasm_throw_exception");
+}
+
+static void
+wasm_rethrow_exception (void)
+{
+       g_error ("wasm_rethrow_exception");
+}
+
+static void
+wasm_throw_corlib_exception (void)
+{
+       g_error ("wasm_throw_corlib_exception");
+}
+
+static char
+type_to_c (MonoType *t)
+{
+       if (t->byref)
+               return 'I';
+
+handle_enum:
+       switch (t->type) {
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I:
+       case MONO_TYPE_U:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_CLASS:
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_STRING:
+               return 'I';
+       case MONO_TYPE_R4:
+               return 'F';
+       case MONO_TYPE_R8:
+               return 'D';
+               break;
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+               return 'L';
+       case MONO_TYPE_VOID:
+               return 'V';
+       case MONO_TYPE_VALUETYPE:
+               if (t->data.klass->enumtype) {
+                       t = mono_class_enum_basetype (t->data.klass);
+                       goto handle_enum;
+               }
+
+               return 'I';
+       case MONO_TYPE_GENERICINST:
+               if (t->data.klass->valuetype)
+                       return 'S';
+               return 'I';
+       default:
+               g_warning ("CANT TRANSLATE %s", mono_type_full_name (t));
+               return 'X';
+       }
+}
+
+#if SIZEOF_VOID_P == 4
+#define FIDX(x) ((x) * 2)
+#else
+#define FIDX(x) (x)
+#endif
+
+static void
+wasm_invoke_v (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(void) = target_func;
+       func ();
+}
+
+static void
+wasm_invoke_vi (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a) = target_func;
+       func (margs->iargs [0]);
+}
+
+static void
+wasm_invoke_vii (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, gpointer b) = target_func;
+       func (margs->iargs [0], margs->iargs [1]);
+}
+
+static void
+wasm_invoke_viii (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, gpointer b, gpointer c) = target_func;
+       func (margs->iargs [0], margs->iargs [1], margs->iargs [2]);
+}
+
+static void
+wasm_invoke_viiii (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, gpointer b, gpointer c, gpointer d) = target_func;
+       func (margs->iargs [0], margs->iargs [1], margs->iargs [2], margs->iargs [3]);
+}
+
+static void
+wasm_invoke_viiiii (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, gpointer b, gpointer c, gpointer d, gpointer e) = target_func;
+       func (margs->iargs [0], margs->iargs [1], margs->iargs [2], margs->iargs [3], margs->iargs [4]);
+}
+
+static void
+wasm_invoke_viiiiii (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, gpointer b, gpointer c, gpointer d, gpointer e, gpointer f) = target_func;
+       func (margs->iargs [0], margs->iargs [1], margs->iargs [2], margs->iargs [3], margs->iargs [4], margs->iargs [5]);
+}
+
+static void
+wasm_invoke_i (void *target_func, InterpMethodArguments *margs)
+{
+       int (*func)(void) = target_func;
+       int res = func ();
+       *(int*)margs->retval = res;
+}
+
+static void
+wasm_invoke_ii (void *target_func, InterpMethodArguments *margs)
+{
+       int (*func)(gpointer a) = target_func;
+       int res = func (margs->iargs [0]);
+       *(int*)margs->retval = res;
+}
+
+static void
+wasm_invoke_iii (void *target_func, InterpMethodArguments *margs)
+{
+       int (*func)(gpointer a, gpointer b) = target_func;
+       int res = func (margs->iargs [0], margs->iargs [1]);
+       *(int*)margs->retval = res;
+}
+
+static void
+wasm_invoke_iiii (void *target_func, InterpMethodArguments *margs)
+{
+       int (*func)(gpointer a, gpointer b, gpointer c) = target_func;
+       int res = func (margs->iargs [0], margs->iargs [1], margs->iargs [2]);
+       *(int*)margs->retval = res;
+}
+
+static void
+wasm_invoke_iiiii (void *target_func, InterpMethodArguments *margs)
+{
+       int (*func)(gpointer a, gpointer b, gpointer c, gpointer d) = target_func;
+       int res = func (margs->iargs [0], margs->iargs [1], margs->iargs [2], margs->iargs [3]);
+       *(int*)margs->retval = res;
+}
+
+static void
+wasm_invoke_iiiiii (void *target_func, InterpMethodArguments *margs)
+{
+       int (*func)(gpointer a, gpointer b, gpointer c, gpointer d, gpointer e) = target_func;
+       int res = func (margs->iargs [0], margs->iargs [1], margs->iargs [2], margs->iargs [3], margs->iargs [4]);
+       *(int*)margs->retval = res;
+}
+
+typedef union {
+       gint64 l;
+       struct {
+               gint32 lo;
+               gint32 hi;
+       } pair;
+} interp_pair;
+
+static void
+wasm_invoke_ll (void *target_func, InterpMethodArguments *margs)
+{
+       gint64 (*func)(gint64 a) = target_func;
+
+       interp_pair p;
+       p.pair.lo = (gint32)margs->iargs [0];
+       p.pair.hi = (gint32)margs->iargs [1];
+
+       gint64 res = func (p.l);
+       *(gint64*)margs->retval = res;
+}
+
+static void
+wasm_invoke_li (void *target_func, InterpMethodArguments *margs)
+{
+       gint64 (*func)(gpointer a) = target_func;
+       gint64 res = func (margs->iargs [0]);
+       *(gint64*)margs->retval = res;
+}
+
+static void
+wasm_invoke_lil (void *target_func, InterpMethodArguments *margs)
+{
+       gint64 (*func)(gpointer a, gint64 b) = target_func;
+
+       interp_pair p;
+       p.pair.lo = (gint32)margs->iargs [1];
+       p.pair.hi = (gint32)margs->iargs [2];
+
+       gint64 res = func (margs->iargs [0], p.l);
+       *(gint64*)margs->retval = res;
+}
+
+static void
+wasm_invoke_dd (void *target_func, InterpMethodArguments *margs)
+{
+       double (*func)(double a) = target_func;
+
+       double res = func (margs->fargs [FIDX (0)]);
+       *(double*)margs->retval = res;
+}
+
+static void
+wasm_invoke_ddd (void *target_func, InterpMethodArguments *margs)
+{
+       double (*func)(double a, double b) = target_func;
+
+       double res = func (margs->fargs [FIDX (0)], margs->fargs [FIDX (1)]);
+       *(double*)margs->retval = res;
+}
+
+
+       
+static void
+wasm_invoke_vif (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, float b) = target_func;
+
+       func (margs->iargs [0], 
+               *(float*)&margs->fargs [FIDX (0)]);
+}
+
+static void
+wasm_invoke_viff (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, float b, float c) = target_func;
+
+       func (margs->iargs [0],
+               *(float*)&margs->fargs [FIDX (0)],
+               *(float*)&margs->fargs [FIDX (1)]);
+}
+
+static void
+wasm_invoke_viffff (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, float b, float c, float d, float e) = target_func;
+
+       func (margs->iargs [0],
+               *(float*)&margs->fargs [FIDX (0)],
+               *(float*)&margs->fargs [FIDX (1)],
+               *(float*)&margs->fargs [FIDX (2)],
+               *(float*)&margs->fargs [FIDX (3)]);
+}
+
+static void
+wasm_invoke_vifffffi (void *target_func, InterpMethodArguments *margs)
+{
+       void (*func)(gpointer a, float b, float c, float d, float e, float f, int g) = target_func;
+
+       func (margs->iargs [0],
+               *(float*)&margs->fargs [FIDX (0)],
+               *(float*)&margs->fargs [FIDX (1)],
+               *(float*)&margs->fargs [FIDX (2)],
+               *(float*)&margs->fargs [FIDX (3)],
+               *(float*)&margs->fargs [FIDX (4)],
+               *(float*)&margs->iargs [1]);
+}
+
+static void
+wasm_enter_icall_trampoline (void *target_func, InterpMethodArguments *margs)
+{
+       static char cookie [8];
+       static int c_count;
+
+       MonoMethodSignature *sig = margs->sig;
+
+       c_count = sig->param_count + sig->hasthis + 1;
+       cookie [0] = type_to_c (sig->ret);
+       if (sig->hasthis)
+               cookie [1] = 'I';
+       for (int i = 0; i < sig->param_count; ++i)
+               cookie [1 + sig->hasthis + i ] = type_to_c (sig->params [i]);
+       cookie [c_count] = 0;
+
+       if (!strcmp ("V", cookie))
+               wasm_invoke_v (target_func, margs);
+       else if (!strcmp ("VI", cookie))
+               wasm_invoke_vi (target_func, margs);
+       else if (!strcmp ("VII", cookie))
+               wasm_invoke_vii (target_func, margs);
+       else if (!strcmp ("VIII", cookie))
+               wasm_invoke_viii (target_func, margs);
+       else if (!strcmp ("VIIII", cookie))
+               wasm_invoke_viiii (target_func, margs);
+       else if (!strcmp ("VIIIII", cookie))
+               wasm_invoke_viiiii (target_func, margs);
+       else if (!strcmp ("VIIIIII", cookie))
+               wasm_invoke_viiiiii (target_func, margs);
+       else if (!strcmp ("I", cookie))
+               wasm_invoke_i (target_func, margs);
+       else if (!strcmp ("II", cookie))
+               wasm_invoke_ii (target_func, margs);
+       else if (!strcmp ("III", cookie))
+               wasm_invoke_iii (target_func, margs);
+       else if (!strcmp ("IIII", cookie))
+               wasm_invoke_iiii (target_func, margs);
+       else if (!strcmp ("IIIII", cookie))
+               wasm_invoke_iiiii (target_func, margs);
+       else if (!strcmp ("IIIIII", cookie))
+               wasm_invoke_iiiiii (target_func, margs);
+       else if (!strcmp ("LL", cookie))
+               wasm_invoke_ll (target_func, margs);
+       else if (!strcmp ("LI", cookie))
+               wasm_invoke_li (target_func, margs);
+       else if (!strcmp ("LIL", cookie))
+               wasm_invoke_lil (target_func, margs);
+       else if (!strcmp ("DD", cookie))
+               wasm_invoke_dd (target_func, margs);
+       else if (!strcmp ("DDD", cookie))
+               wasm_invoke_ddd (target_func, margs);
+       else if (!strcmp ("VIF", cookie))
+               wasm_invoke_vif (target_func, margs);
+       else if (!strcmp ("VIFF", cookie))
+               wasm_invoke_viff (target_func, margs);
+       else if (!strcmp ("VIFFFF", cookie))
+               wasm_invoke_viffff (target_func, margs);
+       else if (!strcmp ("VIFFFFFI", cookie))
+               wasm_invoke_vifffffi (target_func, margs);
+       else {
+               printf ("CANNOT HANDLE COOKIE %s\n", cookie);
+               g_assert (0);
+       }
+}
+
+gpointer
+mono_aot_get_trampoline_full (const char *name, MonoTrampInfo **out_tinfo)
+{
+       gpointer code = NULL;
+
+       if (!strcmp (name, "restore_context"))
+               code = wasm_restore_context;
+       else if (!strcmp (name, "call_filter"))
+               code = wasm_call_filter;
+       else if (!strcmp (name, "throw_exception"))
+               code = wasm_throw_exception;
+       else if (!strcmp (name, "rethrow_exception"))
+               code = wasm_rethrow_exception;
+       else if (!strcmp (name, "throw_corlib_exception"))
+               code = wasm_throw_corlib_exception;
+       else if (!strcmp (name, "enter_icall_trampoline"))
+               code = wasm_enter_icall_trampoline;
+
+       g_assert (code);
+
+       if (out_tinfo) {
+               MonoTrampInfo *tinfo = g_new0 (MonoTrampInfo, 1);
+               tinfo->code = code;
+               tinfo->code_size = 1;
+               tinfo->name = g_strdup (name);
+               tinfo->ji = NULL;
+               tinfo->unwind_ops = NULL;
+               tinfo->uw_info = NULL;
+               tinfo->uw_info_len = 0;
+               tinfo->owns_uw_info = FALSE;
+
+               *out_tinfo = tinfo;
+       }
+
+       return code;
+}
+#endif
index d6c2486414f3278b960ec7480d50137ea27e7cee..4e86a5a3f32dc0f21460bfb23046f2a12f34f55b 100644 (file)
@@ -5143,6 +5143,8 @@ no_trampolines (void)
        g_assert_not_reached ();
 }
 
+
+#ifndef TARGET_WASM
 /*
  * Return the trampoline identified by NAME from the mscorlib AOT file.
  * On ppc64, this returns a function descriptor.
@@ -5159,6 +5161,8 @@ mono_aot_get_trampoline_full (const char *name, MonoTrampInfo **out_tinfo)
 
        return mono_create_ftnptr_malloc ((guint8 *)load_function_full (amodule, name, out_tinfo));
 }
+#endif
+
 
 gpointer
 mono_aot_get_trampoline (const char *name)
diff --git a/mono/mini/cpu-wasm.md b/mono/mini/cpu-wasm.md
new file mode 100644 (file)
index 0000000..e69de29
index 297179bf86cabaa76b112108bb7a977d9c65db1f..f293f7c6803ff1e3dc488d9d694711479610b208 100644 (file)
@@ -2376,6 +2376,11 @@ mono_jit_set_aot_mode (MonoAotMode mode)
                mono_aot_only = TRUE;
                mono_use_interpreter = TRUE;
        }
+       if (mono_aot_mode == MONO_AOT_MODE_INTERP_LLVMONLY) {
+               mono_aot_only = TRUE;
+               mono_use_interpreter = TRUE;
+               mono_llvm_only = TRUE;
+       }
 }
 
 mono_bool
diff --git a/mono/mini/exceptions-wasm.c b/mono/mini/exceptions-wasm.c
new file mode 100644 (file)
index 0000000..63e72b0
--- /dev/null
@@ -0,0 +1,34 @@
+#include "mini.h"
+
+
+gpointer
+mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
+{
+       g_error ("mono_arch_get_call_filter");
+       return NULL;
+}
+
+gpointer
+mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
+{
+       g_error ("mono_arch_get_restore_context");
+       return NULL;
+}
+
+gboolean
+mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, 
+                                                        MonoJitInfo *ji, MonoContext *ctx, 
+                                                        MonoContext *new_ctx, MonoLMF **lmf,
+                                                        mgreg_t **save_locations,
+                                                        StackFrameInfo *frame)
+{
+       g_error ("mono_arch_unwind_frame");
+       return FALSE;
+}
+
+gpointer 
+mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
+{
+       g_error ("mono_arch_get_throw_corlib_exception");
+       return NULL;
+}
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 8c8e7ea..ae49ecb
@@ -20,7 +20,7 @@ sub INST_MAX   () {return 6;}
 
 # this must include all the #defines used in mini-ops.h
 my @defines = qw (__i386__ __x86_64__ __ppc__ __powerpc__ __ppc64__ __arm__ 
-       __sparc__ sparc __s390__ s390 __alpha__ __mips__ __aarch64__);
+       __sparc__ sparc __s390__ s390 __alpha__ __mips__ __aarch64__ __wasm__);
 my %table =();
 my %template_table =();
 my @opcodes = ();
@@ -88,7 +88,9 @@ sub load_opcodes
        if ($arch =~ "__aarch64__") {
                $arch_define = "TARGET_ARM64";
        }
-
+       if ($arch =~ "__wasm__") {
+               $arch_define = "TARGET_WASM";
+       }
        parse_file ($arch_define, "$srcdir/mini-ops.h");
        return;
        $cpp .= " -D$arch_define $srcdir/mini-ops.h|";
index fccce6b3411211e47139f783249bb0032de10225..42b91954fcf2c223e6c66a23fd404544ff3cb88b 100644 (file)
@@ -795,6 +795,10 @@ static InterpMethodArguments* build_args_from_sig (MonoMethodSignature *sig, Int
        int i8_align = mono_arm_i8_align ();
 #endif
 
+#ifdef TARGET_WASM
+       margs->sig = sig;
+#endif
+
        if (sig->hasthis)
                margs->ilen++;
 
index 6abf93a6f0a38c900820258f6b73859f2b35d048..42198d92193fa81bec29b67d47c4d6325364fd62 100644 (file)
@@ -6,8 +6,13 @@
 #define __MONO_MINI_INTERPRETER_H__
 #include <mono/mini/mini.h>
 
+#ifdef TARGET_WASM
+#define INTERP_ICALL_TRAMP_IARGS 12
+#define INTERP_ICALL_TRAMP_FARGS 12
+#else
 #define INTERP_ICALL_TRAMP_IARGS 12
 #define INTERP_ICALL_TRAMP_FARGS 4
+#endif
 
 struct _InterpMethodArguments {
        size_t ilen;
@@ -16,6 +21,9 @@ struct _InterpMethodArguments {
        double *fargs;
        gpointer *retval;
        size_t is_float_ret;
+#ifdef TARGET_WASM
+       MonoMethodSignature *sig;
+#endif
 };
 
 typedef struct _InterpMethodArguments InterpMethodArguments;
index 408fead304ef2f95073bbe518c329125f519ea24..3a91c13f0d56369aeee04453a39dfd3e1e577514 100644 (file)
@@ -57,7 +57,9 @@ typedef enum {
        MONO_AOT_MODE_LLVMONLY,
        /* Uses Interpreter, JIT is disabled and not allowed,
         * equivalent to "--full-aot --interpreter" */
-       MONO_AOT_MODE_INTERP
+       MONO_AOT_MODE_INTERP,
+       /* Same as INTERP, but use only llvm compiled code */
+       MONO_AOT_MODE_INTERP_LLVMONLY,
 } MonoAotMode;
 
 MONO_API void
index eb50de0f5e4aebe8a94ce6bea359635255c92c11..c49ed5a41d569c71627c295a89ac0de4365ac1aa 100644 (file)
@@ -25,6 +25,8 @@
 #include "mini-arm64.h"
 #elif defined(__mips__)
 #include "mini-mips.h"
+#elif TARGET_WASM
+#include "mini-wasm.h"
 #else
 #error add arch specific include file in mini-arch.h
 #endif
index 611201eecd7f6a490714df7889f2431ed1d7209b..10cf1b75cb194d9051761962546b5ffba8b9f8f8 100644 (file)
@@ -3263,7 +3263,7 @@ mono_llvm_load_exception (void)
 
        if (mono_ex->trace_ips) {
                GList *trace_ips = NULL;
-               gpointer ip = __builtin_return_address (0);
+               gpointer ip = RETURN_ADDRESS ();
 
                size_t upper = mono_array_length (mono_ex->trace_ips);
 
diff --git a/mono/mini/mini-wasm.c b/mono/mini/mini-wasm.c
new file mode 100644 (file)
index 0000000..0104909
--- /dev/null
@@ -0,0 +1,253 @@
+#include "mini.h"
+
+
+gpointer
+mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code)
+{
+       g_error ("mono_arch_get_this_arg_from_call");
+}
+
+gpointer
+mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
+{
+       g_error ("mono_arch_get_delegate_virtual_invoke_impl");
+}
+
+
+void
+mono_arch_cpu_init (void)
+{
+       // printf ("mono_arch_cpu_init\n");
+}
+
+void
+mono_arch_finish_init (void)
+{
+       // printf ("mono_arch_finish_init\n");
+}
+
+void
+mono_arch_init (void)
+{
+       // printf ("mono_arch_init\n");
+}
+
+void
+mono_arch_cleanup (void)
+{
+}
+
+void
+mono_arch_register_lowlevel_calls (void)
+{
+}
+
+void
+mono_arch_flush_register_windows (void)
+{
+}
+
+void
+mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
+{
+}
+
+
+MonoMethod*
+mono_arch_find_imt_method (mgreg_t *regs, guint8 *code)
+{
+       g_error ("mono_arch_find_static_call_vtable");
+       return (MonoMethod*) regs [MONO_ARCH_IMT_REG];
+}
+
+MonoVTable*
+mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code)
+{
+       g_error ("mono_arch_find_static_call_vtable");
+       return (MonoVTable*) regs [MONO_ARCH_RGCTX_REG];
+}
+
+gpointer
+mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, gpointer fail_tramp)
+{
+       g_error ("mono_arch_build_imt_trampoline");
+}
+
+guint32
+mono_arch_cpu_enumerate_simd_versions (void)
+{
+       return 0;
+}
+
+guint32
+mono_arch_cpu_optimizations (guint32 *exclude_mask)
+{
+       return 0;
+}
+
+GSList*
+mono_arch_get_delegate_invoke_impls (void)
+{
+       g_error ("mono_arch_get_delegate_invoke_impls");
+       return NULL;
+}
+
+gpointer
+mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target)
+{
+       g_error ("mono_arch_get_delegate_invoke_impl");
+       return NULL;
+}
+
+mgreg_t
+mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
+{
+       g_error ("mono_arch_context_get_int_reg");
+       return 0;
+}
+
+int
+mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
+{
+       g_error ("mono_arch_get_argument_info");
+       return 0;
+
+}
+
+void
+mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
+{
+       ext->lmf.previous_lmf = (gsize)prev_lmf;
+       /* Mark that this is a MonoLMFExt */
+       ext->lmf.previous_lmf = (gsize)(gpointer)(((gssize)ext->lmf.previous_lmf) | 2);
+}
+
+
+
+void
+mono_runtime_setup_stat_profiler (void)
+{
+       g_error ("mono_runtime_setup_stat_profiler");
+}
+
+
+void
+mono_runtime_shutdown_stat_profiler (void)
+{
+       g_error ("mono_runtime_shutdown_stat_profiler");
+}
+
+
+gboolean
+MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal)
+{
+       g_error ("mono_chain_signal");
+       
+       return FALSE;
+}
+
+void
+mono_runtime_install_handlers (void)
+{
+}
+
+void
+mono_runtime_cleanup_handlers (void)
+{
+}
+
+gboolean
+mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
+{
+       g_error ("WASM systems don't support mono_thread_state_init_from_handle");
+       return FALSE;
+}
+
+
+/*
+The following functions don't belong here, but are due to laziness.
+*/
+
+//w32file-wasm.c
+gboolean
+mono_w32file_get_volume_information (const gunichar2 *path, gunichar2 *volumename, gint volumesize, gint *outserial, gint *maxcomp, gint *fsflags, gunichar2 *fsbuffer, gint fsbuffersize)
+{
+       g_error ("mono_w32file_get_volume_information");
+}
+
+
+//llvm builtin's that we should not have used in the first place
+
+
+//libc / libpthread missing bits from musl or shit we didn't detect :facepalm:
+int pthread_getschedparam (pthread_t thread, int *policy, struct sched_param *param)
+{
+       g_error ("pthread_getschedparam");
+       return 0;
+}
+
+int
+pthread_attr_getstacksize (const pthread_attr_t *restrict attr, size_t *restrict stacksize)
+{
+       return 65536; //wasm page size
+}
+
+int
+pthread_sigmask (int how, const sigset_t * restrict set, sigset_t * restrict oset)
+{
+       return 0;
+}
+
+
+int
+sigsuspend(const sigset_t *sigmask)
+{
+       g_error ("sigsuspend");
+       return 0;
+}
+
+int
+getdtablesize (void)
+{
+       return 256; //random constant that is the fd limit
+}
+
+void *
+getgrnam (const char *name)
+{
+       return NULL;
+}
+
+void *
+getgrgid (gid_t gid)
+{
+       return NULL;
+}
+
+int
+inotify_init (void)
+{
+       g_error ("inotify_init");
+}
+
+int
+inotify_rm_watch (int fd, int wd)
+{
+       g_error ("inotify_rm_watch");
+       return 0;
+}
+
+int
+inotify_add_watch (int fd, const char *pathname, uint32_t mask)
+{
+       g_error ("inotify_add_watch");
+       return 0;
+}
+
+int
+sem_timedwait (sem_t *sem, const struct timespec *abs_timeout)
+{
+       g_error ("sem_timedwait");
+       return 0;
+       
+}
diff --git a/mono/mini/mini-wasm.h b/mono/mini/mini-wasm.h
new file mode 100644 (file)
index 0000000..8205dc1
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef __MONO_MINI_WASM_H__
+#define __MONO_MINI_WASM_H__
+
+#include <mono/utils/mono-sigcontext.h>
+#include <mono/utils/mono-context.h>
+
+#define MONO_ARCH_CPU_SPEC mono_wasm_desc
+
+#define MONO_ARCH_HAVE_INIT_LMF_EXT 1
+
+#define MONO_MAX_IREGS 1
+#define MONO_MAX_FREGS 1
+
+#define WASM_REG_0 0
+
+
+struct MonoLMF {
+       /* 
+        * If the second lowest bit is set to 1, then this is a MonoLMFExt structure, and
+        * the other fields are not valid.
+        */
+       gpointer previous_lmf;
+       gpointer lmf_addr;
+
+       /* This is only set in trampoline LMF frames */
+       MonoMethod *method;
+
+       gboolean top_entry;
+};
+
+typedef struct {
+       int dummy;
+} MonoCompileArch;
+
+#define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) do { (lmf)->top_entry = TRUE; } while (0)
+
+#define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->llvm_exc_reg = (gsize)exc; } while (0)
+
+#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {       \
+               MONO_CONTEXT_SET_IP ((ctx), (start_func));      \
+               MONO_CONTEXT_SET_BP ((ctx), (0));       \
+               MONO_CONTEXT_SET_SP ((ctx), (0));       \
+       } while (0)
+
+
+#define MONO_ARCH_VTABLE_REG WASM_REG_0
+#define MONO_ARCH_IMT_REG WASM_REG_0
+#define MONO_ARCH_RGCTX_REG WASM_REG_0
+
+#endif /* __MONO_MINI_WASM_H__ */  
index 9645a0de7b99d1b9ac7e8caedbb37a3bf0cabded..0edfea186b4e5adfaacc6013a6d1e6f82e83613e 100644 (file)
@@ -3266,4 +3266,31 @@ gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal);
  */
 void mono_interruption_checkpoint_from_trampoline (void);
 
+
+#if defined (HOST_WASM)
+
+#define RETURN_ADDRESS_N(N) NULL
+#define RETURN_ADDRESS() RETURN_ADDRESS_N(0)
+
+
+#elif defined (__GNUC__)
+
+#define RETURN_ADDRESS_N(N) (__builtin_extract_return_addr (__builtin_return_address (N)))
+#define RETURN_ADDRESS() RETURN_ADDRESS_N(0)
+
+#elif defined(_MSC_VER)
+
+#include <intrin.h>
+#pragma intrinsic(_ReturnAddress)
+
+#define RETURN_ADDRESS() _ReturnAddress()
+#define RETURN_ADDRESS_N(N) NULL
+
+#else
+
+#error "Missing return address intrinsics implementation"
+
+#endif
+
+
 #endif /* __MONO_MINI_H__ */
index 0e50ae550707597de0aee029b8dc9cdda3829405..b81fe604ed3aef345b7eef2ca52c01e4630172d7 100644 (file)
 #  define fprintf(__ignore, ...) g_log ("mono-gc", G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
 #endif
 
-#ifdef __GNUC__
-
-#define RETURN_ADDRESS_N(N) (__builtin_extract_return_addr (__builtin_return_address (N)))
-#define RETURN_ADDRESS() RETURN_ADDRESS_N(0)
-
-#elif defined(_MSC_VER)
-
-#include <intrin.h>
-#pragma intrinsic(_ReturnAddress)
-
-#define RETURN_ADDRESS() _ReturnAddress()
-#define RETURN_ADDRESS_N(N) NULL
-
-#else
-
-#error "Missing return address intrinsics implementation"
-
-#endif
-
 static MonoTraceSpec trace_spec;
 
 static volatile gint32 output_lock = 0;
diff --git a/mono/mini/tramp-wasm.c b/mono/mini/tramp-wasm.c
new file mode 100644 (file)
index 0000000..50447fb
--- /dev/null
@@ -0,0 +1,54 @@
+#include "mini.h"
+
+
+gpointer
+mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
+{
+       g_error ("mono_arch_create_specific_trampoline");
+}
+
+guchar*
+mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot)
+{
+       g_error ("mono_arch_create_generic_trampoline");
+}
+
+gpointer
+mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot)
+{
+       g_error ("mono_arch_create_rgctx_lazy_fetch_trampoline");
+}
+
+void
+mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
+{
+       g_error ("mono_arch_patch_plt_entry");
+}
+
+gpointer
+mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
+{
+       printf ("mono_arch_get_enter_icall_trampoline");
+       g_assert (0);
+       return NULL;
+}
+
+void
+mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
+{
+       g_error ("mono_arch_patch_callsite");
+}
+
+gpointer
+mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
+{
+       g_error ("mono_arch_get_unbox_trampoline");
+       return NULL;
+}
+
+gpointer
+mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr)
+{
+       g_error ("mono_arch_get_static_rgctx_trampoline");
+       return NULL;
+}
\ No newline at end of file
index 53e962c2b702e7ea8a893dc940ea8d42d227b967..5e8866ffff869d2123ece47d39040009b0a95118 100644 (file)
@@ -104,6 +104,20 @@ typedef mword SgenDescriptor;
 #endif
 #endif
 
+#if defined (TARGET_WASM)
+#define DEFAULT_MAJOR SGEN_MAJOR_SERIAL
+#define DEFAULT_SWEEP_MODE SGEN_SWEEP_SERIAL
+#elif defined(HAVE_CONC_GC_AS_DEFAULT)
+/* Use concurrent major on deskstop platforms */
+#define DEFAULT_MAJOR SGEN_MAJOR_CONCURRENT
+#define DEFAULT_SWEEP_MODE SGEN_SWEEP_CONCURRENT
+#else
+#define DEFAULT_MAJOR SGEN_MAJOR_SERIAL
+#define DEFAULT_SWEEP_MODE SGEN_SWEEP_CONCURRENT
+#endif
+
+
+
 /*
  * Maximum level of debug to enable on this build.
  * Making this a constant enables us to put logging in a lot of places and
index beb5ce1b2580c265935db3200a138fd91f31c9a4..d5416f0df3630ee6a6bc5b4781bc0e9c5442873c 100644 (file)
@@ -337,13 +337,6 @@ nursery_canaries_enabled (void)
 
 #define safe_object_get_size   sgen_safe_object_get_size
 
-#if defined(HAVE_CONC_GC_AS_DEFAULT)
-/* Use concurrent major on deskstop platforms */
-#define DEFAULT_MAJOR SGEN_MAJOR_CONCURRENT
-#else
-#define DEFAULT_MAJOR SGEN_MAJOR_SERIAL
-#endif
-
 typedef enum {
        SGEN_MAJOR_DEFAULT,
        SGEN_MAJOR_SERIAL,
index 5f4185d4df70ec4f48a692aae3edfc46cfd3396b..e06ac6d3f83f22177fa54f48f5dc96fa23870e98 100644 (file)
@@ -189,10 +189,15 @@ enum {
        SWEEP_STATE_COMPACTING
 };
 
+typedef enum {
+       SGEN_SWEEP_SERIAL = FALSE,
+       SGEN_SWEEP_CONCURRENT = TRUE,
+} SgenSweepMode;
+
 static volatile int sweep_state = SWEEP_STATE_SWEPT;
 
 static gboolean concurrent_mark;
-static gboolean concurrent_sweep = TRUE;
+static gboolean concurrent_sweep = DEFAULT_SWEEP_MODE;
 
 int sweep_pool_context = -1;
 
index c2b2b96d9d7419c0eea9d9400a84da27323b6d7a..ea1b595c4a5b6b66bb0016c10ef2cc4ed2706c98 100644 (file)
@@ -15,7 +15,7 @@
 #include <unistd.h>
 #endif
 
-#if defined(_POSIX_VERSION)
+#if defined(_POSIX_VERSION) && !defined (HOST_WASM)
 
 #include "mono/utils/mono-dl.h"
 #include "mono/utils/mono-embed.h"
index 440eff85125121729d9c330de899bf5d74e43d0f..1b9849fe5aff24f0672b6d232e28c526827f8525 100644 (file)
@@ -37,6 +37,9 @@
 #ifdef _MSC_VER
 // TODO: Find MSVC replacement for __builtin_unwind_init
 #define SAVE_REGS_ON_STACK g_assert_not_reached ();
+#elif defined (HOST_WASM)
+//TODO: figure out wasm stack scanning
+#define SAVE_REGS_ON_STACK do {} while (0)
 #else 
 #define SAVE_REGS_ON_STACK __builtin_unwind_init ();
 #endif
index 6ef8a9c5e843d7b84415ffdb13d71121930dc3ba..60816ed8d578d1cfbf9fc4d37c8688521f297833 100644 (file)
@@ -7,13 +7,13 @@
 
 #define round_down(addr, val) ((void*)((addr) & ~((val) - 1)))
 
-void
-mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize)
+int
+mono_threads_get_max_stack_size (void)
 {
-       *staddr = round_down ((size_t)&staddr, 65536); //WASM pagesize is 64k
-       *stsize = 65536 * 4; //we say it's 4 pages, there isn't much that uses this beyond the GC
+       return 65536 * 8; //totally arbitrary, this value is actually useless until WASM supports multiple threads.
 }
 
+
 void
 mono_threads_suspend_init_signals (void)
 {
@@ -57,4 +57,79 @@ mono_threads_suspend_abort_syscall (MonoThreadInfo *info)
 {
 }
 
+//----
+
+gboolean
+mono_native_thread_id_equals (MonoNativeThreadId id1, MonoNativeThreadId id2)
+{
+       return id1 == id2;
+}
+
+
+MonoNativeThreadId
+mono_native_thread_id_get (void)
+{
+       return (MonoNativeThreadId)1;
+}
+
+MONO_API gboolean
+mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg)
+{
+       g_error ("WASM doesn't support threading");
+}
+
+static const char *thread_name;
+
+void
+mono_native_thread_set_name (MonoNativeThreadId tid, const char *name)
+{
+       thread_name = g_strdup (name);
+}
+
+gboolean
+mono_native_thread_join (MonoNativeThreadId tid)
+{
+       g_error ("WASM doesn't support threading");
+       return FALSE;
+}
+
+//----
+
+gboolean
+mono_threads_platform_yield (void)
+{
+       return TRUE;
+}
+
+void
+mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize)
+{
+       *staddr = round_down ((size_t)&staddr, 65536); //WASM pagesize is 64k
+       *stsize = 65536 * 4; //we say it's 4 pages, there isn't much that uses this beyond the GC
+}
+
+
+gboolean
+mono_thread_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *tid)
+{
+       g_error ("WASM doesn't support threading");
+       return FALSE;
+}
+
+void mono_threads_platform_init (void)
+{
+}
+
+void
+mono_threads_platform_exit (gsize exit_code)
+{
+       g_error ("WASM doesn't support threading");
+}
+
+gboolean
+mono_threads_platform_in_critical_region (MonoNativeThreadId tid)
+{
+       return FALSE;
+}
+
 #endif
index 32aeb9633886e6fed3fd9f09e10ab79386cbd4f0..45ccf518a7db1658ea9cae743458f0ce6be97961 100644 (file)
@@ -16,7 +16,8 @@
 #include <netdb.h>
 #endif
 
-#ifndef HAVE_INET_PTON
+//wasm does have inet_pton even though autoconf fails to find
+#if !defined (HAVE_INET_PTON) && !defined (HOST_WASM)
 
 int
 inet_pton (int family, const char *address, void *inaddrp)