Merge pull request #5415 from kumpera/wasm-support
authorRodrigo Kumpera <kumpera@users.noreply.github.com>
Wed, 23 Aug 2017 23:03:16 +0000 (19:03 -0400)
committerGitHub <noreply@github.com>
Wed, 23 Aug 2017 23:03:16 +0000 (19:03 -0400)
WebAssembly port

15 files changed:
README.md
configure.ac
mono/metadata/mono-config.c
mono/metadata/object-offsets.h
mono/sgen/sgen-archdep.h
mono/utils/Makefile.am
mono/utils/atomic.c
mono/utils/mono-context.h
mono/utils/mono-dl-wasm.c [new file with mode: 0644]
mono/utils/mono-hwcap-wasm.c [new file with mode: 0644]
mono/utils/mono-membar.h
mono/utils/mono-mmap.c
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-wasm.c [new file with mode: 0644]
mono/utils/mono-threads.h

index bd25f4ab2473301bff6f41d5c956015b4df7663e..facec5b23836396c9fbc11120c5f8eee8fd64b1c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -483,6 +483,16 @@ http://code.google.com/p/nativeclient/
   * Currently this is used with Mono's AOT engine as
 Native Client does not support JIT engines yet.
 
+* `--enable-wasm`
+
+  * Use this option to configure mono to run on WebAssembly. It will
+    set both host and target to the WebAssembly triplet. This overrides
+    the values passed to `--host` or `--target` and ignored what config.sub guesses.
+
+    This is a workaround to enable usage of old automake versions that don't
+    recognize the wasm triplet.
+
+
 Working With Submodules
 =======================
 
index aa0111de8aec8119c31963c6433ac3f56a643e3e..c3000129cfc00d37b5a7afe38fc1f658d2d3e734 100644 (file)
@@ -96,8 +96,15 @@ need_link_unlink=no
 #Set to extra linker flags to be passed to the runtime binaries (mono /mono-sgen)
 extra_runtime_ldflags=""
 
+
+# Hack for WASM
+# Current autotools (v1.15) doesn't have a triplet we can use for wasm so the kludge we do is to
+# work around it by using a feature flag instead
+AC_ARG_ENABLE(wasm,[  --enable-wasm    Hack to set the current runtime to target wasm], enable_wasm=$enableval)
+
 # Thread configuration inspired by sleepycat's db
 AC_MSG_CHECKING([host platform characteristics])
+
 libgc_threads=no
 has_dtrace=no
 parallel_mark=yes
@@ -107,6 +114,16 @@ host_win32=no
 target_win32=no
 platform_android=no
 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"
+libdl="-ldl"
+libgc_threads=pthreads
+
+else
+
 case "$host" in
        *-mingw*|*-*-cygwin*)
                AC_DEFINE(DISABLE_PORTABILITY,1,[Disable the io-portability layer])
@@ -350,6 +367,10 @@ case "$host" in
                libdl="-ldl"
                ;;
 esac
+
+# WASM hack
+fi
+
 AC_MSG_RESULT(ok)
 
 if test x$need_link_unlink = xyes; then
@@ -3038,6 +3059,18 @@ jit_wanted=true
 boehm_supported=true
 BTLS_SUPPORTED=no
 BTLS_PLATFORM=
+
+if test "x$enable_wasm" = "xyes"; then
+TARGET=WASM
+HOST=WASM
+arch_target=wasm
+AC_DEFINE(TARGET_WASM, 1, [Target wasm])
+BTLS_SUPPORTED=no
+with_tls=pthread
+target_mach=no
+
+else
+
 case "$host" in
        mips*)
                TARGET=MIPS;
@@ -3440,6 +3473,8 @@ SPARC64)
        ;;
 esac
 
+#WASM hack
+fi
 
 
 dnl *************
@@ -4309,6 +4344,8 @@ AM_CONDITIONAL(HOST_X86, test x$HOST = xX86)
 AM_CONDITIONAL(HOST_AMD64, test x$HOST = xAMD64)
 AM_CONDITIONAL(HOST_ARM, test x$HOST = xARM)
 AM_CONDITIONAL(HOST_ARM64, test x$HOST = xARM64)
+AM_CONDITIONAL(HOST_WASM, test x$HOST = xWASM)
+
 AM_CONDITIONAL(CROSS_COMPILE, test "x$host" != "x$target")
 
 AC_SUBST(LIBC)
index 7ee7fe2e23a7fabca3e238729679264827738188..c3840963bd92b69c156c1cc999630e3fa97c2402 100644 (file)
@@ -42,6 +42,8 @@
 #define CONFIG_OS "hpux"
 #elif defined(__HAIKU__)
 #define CONFIG_OS "haiku"
+#elif defined (TARGET_WASM)
+#define CONFIG_OS "wasm"
 #else
 #warning Unknown operating system
 #define CONFIG_OS "unknownOS"
@@ -82,6 +84,9 @@
 #elif defined(mips) || defined(__mips) || defined(_mips)
 #define CONFIG_CPU "mips"
 #define CONFIG_WORDSIZE "32"
+#elif defined(TARGET_WASM)
+#define CONFIG_CPU "wasm"
+#define CONFIG_WORDSIZE "32"
 #else
 #error Unknown CPU
 #define CONFIG_CPU "unknownCPU"
index dcf37e0015cf646f710a3c277e705980b25b6793..233f9528ed90ca0a34cdf5377989320fe0dc61c7 100644 (file)
@@ -178,7 +178,16 @@ DECL_OFFSET(MonoDelegateTrampInfo, method_ptr)
 // Architecture-specific offsets
 // -----------------------------
 
-#if defined(TARGET_X86)
+#if defined(TARGET_WASM)
+DECL_OFFSET(MonoContext, wasm_ip)
+DECL_OFFSET(MonoContext, wasm_bp)
+DECL_OFFSET(MonoContext, wasm_sp)
+DECL_OFFSET(MonoContext, llvm_exc_reg)
+
+DECL_OFFSET(MonoLMF, method)
+DECL_OFFSET(MonoLMF, lmf_addr)
+
+#elif defined(TARGET_X86)
 DECL_OFFSET(MonoContext, eax)
 DECL_OFFSET(MonoContext, ebx)
 DECL_OFFSET(MonoContext, ecx)
index 9fa6e2141c2e620e4a9d7d6b5671030019407e8a..9a3ad0157044ba79cbb6deb47a7b20a39ced03db 100644 (file)
 
 #define REDZONE_SIZE   0
 
+#elif defined (TARGET_WASM)
+
+#define REDZONE_SIZE   0
+
 #endif
 
 #endif /* __MONO_SGENARCHDEP_H__ */
index b277688859176ae54ff3a4d3c5b16ff574eccbb5..118ab953d0e8bcc172995e3e797a268899737113 100644 (file)
@@ -39,6 +39,7 @@ monoutils_sources = \
        mono-dl-windows.c       \
        mono-dl-darwin.c        \
        mono-dl-posix.c         \
+       mono-dl-wasm.c  \
        mono-dl.h               \
        mono-dl-windows-internals.h     \
        mono-log-windows.c      \
@@ -136,6 +137,7 @@ monoutils_sources = \
        mono-threads-openbsd.c  \
        mono-threads-android.c  \
        mono-threads-haiku.c    \
+       mono-threads-wasm.c     \
        mono-threads.h  \
        mono-threads-debug.h    \
        mono-threads-api.h      \
@@ -246,6 +248,10 @@ if S390X
 arch_sources += mono-hwcap-s390x.c
 endif
 
+if HOST_WASM
+arch_sources += mono-hwcap-wasm.c
+endif
+
 else
 
 arch_sources += mono-hwcap-cross.c
index c01d8ae5ff295ad2c00ba8631c16e9293720d8ac..2c8802412f91bb840589bd8d767be7b0dfef97d9 100644 (file)
@@ -406,7 +406,7 @@ gpointer InterlockedReadPointer(volatile gpointer *src)
        return(ret);
 }
 
-void InterlockedWrite(volatile gint8 *dst, gint8 val)
+void InterlockedWrite8(volatile gint8 *dst, gint8 val)
 {
        int thr_ret;
        
index b26442f73f5c7897e5ec9da2bf1881399dacf2fa..827e0ed9f813a197db765b5267bd4fbf6f75104b 100644 (file)
@@ -34,7 +34,25 @@ typedef struct __darwin_xmm_reg MonoContextSimdReg;
  * MONO_CONTEXT_GET_CURRENT captures the current context as close as possible. One reg might be clobbered
  *  to hold the address of the target MonoContext. It will be a caller save one, so should not be a problem.
  */
-#if (defined(__i386__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
+#if defined (TARGET_WASM)
+
+typedef struct {
+       mgreg_t wasm_sp;
+       mgreg_t wasm_bp;
+       mgreg_t llvm_exc_reg;
+       mgreg_t wasm_ip;
+       mgreg_t wasm_pc;
+} MonoContext;
+
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->wasm_ip = (mgreg_t)(ip); } while (0);
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->wasm_bp = (mgreg_t)(bp); } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->wasm_sp = (mgreg_t)(sp); } while (0);
+
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->wasm_ip))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->wasm_bp))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->wasm_sp))
+
+#elif (defined(__i386__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
 
 /*HACK, move this to an eventual mono-signal.c*/
 #if defined( __linux__) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || \
diff --git a/mono/utils/mono-dl-wasm.c b/mono/utils/mono-dl-wasm.c
new file mode 100644 (file)
index 0000000..1d0dd98
--- /dev/null
@@ -0,0 +1,76 @@
+#include <config.h>
+
+#if defined (HOST_WASM)
+
+#include "mono/utils/mono-dl.h"
+#include "mono/utils/mono-embed.h"
+#include "mono/utils/mono-path.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <glib.h>
+
+const char *
+mono_dl_get_so_prefix (void)
+{
+       return "";
+}
+
+const char **
+mono_dl_get_so_suffixes (void)
+{
+       static const char *suffixes[] = {
+               ".wasm", //we only recognize .wasm files for DSOs.
+               "",
+       };
+       return suffixes;
+}
+
+int
+mono_dl_get_executable_path (char *buf, int buflen)
+{
+       strncpy (buf, "/managed", buflen); //This is a packaging convertion that our tooling should enforce
+       return 0;
+}
+
+const char*
+mono_dl_get_system_dir (void)
+{
+       return NULL;
+}
+
+
+void*
+mono_dl_lookup_symbol (MonoDl *module, const char *name)
+{
+       return NULL;
+}
+
+char*
+mono_dl_current_error_string (void)
+{
+       return g_strdup ("");
+}
+
+
+int
+mono_dl_convert_flags (int flags)
+{
+       return flags;
+}
+
+void *
+mono_dl_open_file (const char *file, int flags)
+{
+       return NULL;
+}
+
+void
+mono_dl_close_handle (MonoDl *module)
+{
+       //nothing to do
+}
+
+#endif
diff --git a/mono/utils/mono-hwcap-wasm.c b/mono/utils/mono-hwcap-wasm.c
new file mode 100644 (file)
index 0000000..d7d78b0
--- /dev/null
@@ -0,0 +1,15 @@
+/**
+ * \file
+ * wasm feature detection
+ *
+ * Authors:
+ *    Rodrigo Kumpera (kumpera@gmail.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "mono/utils/mono-hwcap.h"
+
+void
+mono_hwcap_arch_init (void)
+{
+}
index 3f937b3b43164c6f8a97015bcff49fc6632324b3..7abf273a6508693e915cd7976e0f7cc0f76b1209 100644 (file)
 
 #include <glib.h>
 
-#ifdef _MSC_VER
+
+#ifdef TARGET_WASM
+
+static inline void mono_memory_barrier (void)
+{
+}
+
+static inline void mono_memory_read_barrier (void)
+{
+}
+
+static inline void mono_memory_write_barrier (void)
+{
+}
+
+#elif _MSC_VER
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #endif
index af8df3236f710ee1b3bf5c5bf0482c21386a4073..3fa797bbd99dcb06b756647189b34b4b1420d476 100644 (file)
@@ -380,13 +380,17 @@ mono_valloc_granule (void)
 void*
 mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type)
 {
-       return g_malloc (length);
+       g_assert (addr == NULL);
+       return mono_valloc_aligned (length, mono_pagesize (), flags, type);
 }
 
 void*
 mono_valloc_aligned (size_t size, size_t alignment, int flags, MonoMemAccountType type)
 {
-       g_assert_not_reached ();
+       void *res = NULL;
+       if (posix_memalign (&res, alignment, size))
+               return NULL;
+       return res;
 }
 
 #define HAVE_VALLOC_ALIGNED
index 22fcb674add26a94d235726f21a0a701afb40bc8..6804024e156a0a6a31ff4c9ff3db282344197a02 100644 (file)
@@ -30,7 +30,7 @@
 extern int tkill (pid_t tid, int signal);
 #endif
 
-#if defined(_POSIX_VERSION)
+#if defined(_POSIX_VERSION) && !defined (TARGET_WASM)
 
 #include <pthread.h>
 
diff --git a/mono/utils/mono-threads-wasm.c b/mono/utils/mono-threads-wasm.c
new file mode 100644 (file)
index 0000000..6ef8a9c
--- /dev/null
@@ -0,0 +1,60 @@
+#include "config.h"
+
+#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-mmap.h>
+
+#if defined (USE_WASM_BACKEND)
+
+#define round_down(addr, val) ((void*)((addr) & ~((val) - 1)))
+
+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
+}
+
+void
+mono_threads_suspend_init_signals (void)
+{
+}
+
+void
+mono_threads_suspend_init (void)
+{
+}
+
+void
+mono_threads_suspend_register (MonoThreadInfo *info)
+{
+}
+
+gboolean
+mono_threads_suspend_begin_async_resume (MonoThreadInfo *info)
+{
+       return TRUE;
+}
+
+void
+mono_threads_suspend_free (MonoThreadInfo *info)
+{
+}
+
+gboolean
+mono_threads_suspend_begin_async_suspend (MonoThreadInfo *info, gboolean interrupt_kernel)
+{
+       return TRUE;
+}
+
+gboolean
+mono_threads_suspend_check_suspend_result (MonoThreadInfo *info)
+{
+       return TRUE;
+}
+
+void
+mono_threads_suspend_abort_syscall (MonoThreadInfo *info)
+{
+}
+
+#endif
index ff3b40ed525e236b1fcafdeea25aaac9f4015620..ffa9de63a66e5468d8cd5fe58989202cb73755b1 100644 (file)
@@ -109,7 +109,9 @@ and reduce the number of casts drastically.
 /* If this is defined, use the signals backed on Mach. Debug only as signals can't be made usable on OSX. */
 // #define USE_SIGNALS_ON_MACH
 
-#if defined (_POSIX_VERSION)
+#ifdef HOST_WASM
+#define USE_WASM_BACKEND
+#elif defined (_POSIX_VERSION)
 #if defined (__MACH__) && !defined (USE_SIGNALS_ON_MACH)
 #define USE_MACH_BACKEND
 #else