* 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
=======================
#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
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])
libdl="-ldl"
;;
esac
+
+# WASM hack
+fi
+
AC_MSG_RESULT(ok)
if test x$need_link_unlink = xyes; then
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;
;;
esac
+#WASM hack
+fi
dnl *************
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)
#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"
#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"
// 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)
#define REDZONE_SIZE 0
+#elif defined (TARGET_WASM)
+
+#define REDZONE_SIZE 0
+
#endif
#endif /* __MONO_SGENARCHDEP_H__ */
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 \
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 \
arch_sources += mono-hwcap-s390x.c
endif
+if HOST_WASM
+arch_sources += mono-hwcap-wasm.c
+endif
+
else
arch_sources += mono-hwcap-cross.c
return(ret);
}
-void InterlockedWrite(volatile gint8 *dst, gint8 val)
+void InterlockedWrite8(volatile gint8 *dst, gint8 val)
{
int thr_ret;
* 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__) || \
--- /dev/null
+#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
--- /dev/null
+/**
+ * \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)
+{
+}
#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
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
extern int tkill (pid_t tid, int signal);
#endif
-#if defined(_POSIX_VERSION)
+#if defined(_POSIX_VERSION) && !defined (TARGET_WASM)
#include <pthread.h>
--- /dev/null
+#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
/* 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