AC_DEFINE_UNQUOTED(MONO_ZERO_LEN_ARRAY, 1, [Length of zero length arrays])
])
+AC_CHECK_HEADERS(nacl/nacl_dyncode.h)
+
if test x$target_win32 = xno; then
dnl hires monotonic clock support
dnl **********************************
dnl *** epoll ***
dnl **********************************
- AC_CHECK_HEADERS(sys/epoll.h)
- haveepoll=no
- AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes], )
- if test "x$haveepoll" = "xyes" -a "x$ac_cv_header_sys_epoll_h" = "xyes" ; then
- AC_DEFINE(HAVE_EPOLL, 1, [epoll supported])
+ if test "x$ac_cv_header_nacl_nacl_dyncode_h" = "xno"; then
+ AC_CHECK_HEADERS(sys/epoll.h)
+ haveepoll=no
+ AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes], )
+ if test "x$haveepoll" = "xyes" -a "x$ac_cv_header_sys_epoll_h" = "xyes"; then
+ AC_DEFINE(HAVE_EPOLL, 1, [epoll supported])
+ fi
fi
havekqueue=no
AC_ARG_ENABLE(nacl_gc, [ --enable-nacl-gc Enable Native Client garbage collection], enable_nacl_gc=$enableval, enable_nacl_gc=no)
AM_CONDITIONAL(NACL_CODEGEN, test x$enable_nacl_codegen != xno)
+
+dnl
+dnl Hack to use system mono for operations in build/install not allowed in NaCl.
+dnl
+nacl_self_host=""
+if test "x$ac_cv_header_nacl_nacl_dyncode_h" = "xyes"; then
+ nacl_self_host="nacl_self_host"
+fi
+AC_SUBST(nacl_self_host)
+
if test "x$enable_nacl_codegen" = "xyes"; then
MONO_NACL_ALIGN_MASK_OFF=1
CPPFLAGS="$CPPFLAGS -D__native_client_codegen__"
TARGET=AMD64;
arch_target=amd64;
JIT_SUPPORTED=yes
+ if test "x$ac_cv_sizeof_void_p" = "x4"; then
+ AC_DEFINE(__mono_ilp32__, 1, [64 bit mode with 4 byte longs and pointers])
+ sizeof_register=8
+ fi
case $host_os in
linux*)
sgen_supported=true
AC_DEFINE(__mono_ilp32__, 1, [64 bit mode with 4 byte longs and pointers])
sizeof_register=8
;;
- *-*-nacl)
+ i686-*-nacl)
TARGET=X86
arch_target=x86
AC_DEFINE(TARGET_X86, 1, [...])
#endif
#if defined (__native_client__)
-#define sem_trywait(x) sem_wait(x)
-#define sem_timedwait(x,y) sem_wait(x)
-#define getdtablesize() (32768)
#undef G_BREAKPOINT
#define G_BREAKPOINT()
#endif
gchar *
g_get_current_dir (void)
{
+#ifdef __native_client__
+ char *buffer;
+ if ((buffer = getenv("NACL_PWD"))) {
+ buffer = g_strdup(buffer);
+ } else {
+ buffer = g_strdup(".");
+ }
+ return buffer;
+#else
int s = 32;
char *buffer = NULL, *r;
gboolean fail;
* so we return the buffer here since it has a pointer to the valid string
*/
return buffer;
+#endif
}
* 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 <config.h>
+
#include <glib.h>
#include <gmodule.h>
-#if defined(__native_client__)
-GModule *
-g_module_open (const gchar *file, GModuleFlags flags)
-{
- printf("dlopen() not supported on Native Client.\n");
- return NULL;
-}
-
-
-gboolean
-g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
-{
- return FALSE;
-}
-
-
-const gchar*
-g_module_error(void)
-{
- return "dlopen not supported on Native Client.";
-}
-
-gboolean
-g_module_close (GModule *module)
-{
- return FALSE;
-}
-
-gchar*
-g_module_build_path (const gchar *directory, const gchar *module_name)
-{
- return NULL;
-}
-
-#else
-
-#ifdef G_OS_UNIX
+#if defined(G_OS_UNIX) && defined(HAVE_DLFCN_H)
#include <dlfcn.h>
/* For Linux and Solaris, need to add others as we port this */
return g_strdup_printf ("%s%s" LIBSUFFIX, lib_prefix, module_name);
}
-#endif /* __native_client__ */
-
JNIEXPORT int JNICALL ikvm_msync(void* address, jint size)
{
+#if defined(__native_client__) && defined(USE_NEWLIB)
+ g_assert_not_reached ();
+ return -1;
+#else
return msync(address, size, MS_SYNC);
+#endif
}
#endif
* None of this is safe with dlclose and incremental collection.
* But then not much of anything is safe in the presence of dlclose.
*/
-#if defined(__linux__) && !defined(_GNU_SOURCE)
+#if (defined(__linux__) || defined(__native_client__)) && !defined(_GNU_SOURCE)
/* Can't test LINUX, since this must be define before other includes */
# define _GNU_SOURCE
#endif
#if !defined(SUNOS4) && !defined(SUNOS5DL) && !defined(IRIX5) && \
!defined(MSWIN32) && !defined(MSWINCE) && \
!(defined(ALPHA) && defined(OSF1)) && \
- !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
+ !defined(HPUX) && !((defined(LINUX) || defined(NACL)) && defined(__ELF__)) && \
!defined(RS6000) && !defined(SCO_ELF) && !defined(DGUX) && \
!(defined(FREEBSD) && defined(__ELF__)) && \
!(defined(OPENBSD) && (defined(__ELF__) || defined(M68K))) && \
# define ELFSIZE ARCH_ELFSIZE
#endif
-#if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
+#if (defined(LINUX) || defined(NACL)) && defined(__ELF__) || defined(SCO_ELF) || \
(defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
(defined(OPENBSD) && defined(__ELF__)) || \
(defined(NETBSD) && defined(__ELF__)) || defined(HURD)
# endif /* !USE_PROC ... */
# endif /* SUNOS */
-#if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
+#if (defined(LINUX) || defined(NACL)) && defined(__ELF__) || defined(SCO_ELF) || \
(defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
(defined(OPENBSD) && defined(__ELF__)) || \
(defined(NETBSD) && defined(__ELF__)) || defined(HURD)
/* For glibc 2.2.4+. Unfortunately, it doesn't work for older */
/* versions. Thanks to Jakub Jelinek for most of the code. */
-# if defined(LINUX) /* Are others OK here, too? */ \
+# if (defined(LINUX) || defined(NACL)) /* Are others OK here, too? */ \
&& (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
/* Determine the machine type: */
# if defined(__native_client__)
# define NACL
-# define I386
-# define mach_type_known
+# if !defined(__portable_native_client__)
+# define I386
+# define mach_type_known
+# else
+ /* Here we will rely upon arch-specific defines. */
+# endif
# endif
# if defined(__arm__) || defined(__thumb__)
# define ARM32
# endif
# endif
+
+# ifdef NACL
+# define OS_TYPE "NACL"
+# if defined(__GLIBC__)
+# define DYNAMIC_LOADING
+# endif
+# define DATASTART ((ptr_t)0x10020000)
+ extern int _end[];
+# define DATAEND (_end)
+# ifdef STACK_GRAN
+# undef STACK_GRAN
+# endif /* STACK_GRAN */
+# define STACK_GRAN 0x10000
+# define HEURISTIC1
+# define USE_MMAP
+# define USE_MUNMAP
+# define USE_MMAP_ANON
+# ifdef USE_MMAP_FIXED
+# undef USE_MMAP_FIXED
+# endif
+# define GETPAGESIZE() 65536
+# define MAX_NACL_GC_THREADS 1024
+# endif
+
# ifdef VAX
# define MACH_TYPE "VAX"
# define ALIGNMENT 4 /* Pointers are longword aligned by 4.2 C compiler */
# define HEAP_START DATAEND
# endif /* USE_MMAP */
# endif /* DGUX */
-# ifdef NACL
-# define OS_TYPE "NACL"
- extern int etext[];
-//# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff))
-# define DATASTART ((ptr_t)0x10000000)
- extern int _end[];
-# define DATAEND (_end)
-# ifdef STACK_GRAN
-# undef STACK_GRAN
-# endif /* STACK_GRAN */
-# define STACK_GRAN 0x10000
-# define HEURISTIC1
-# ifdef USE_MMAP
-# undef USE_MMAP
-# endif
-# ifdef USE_MUNMAP
-# undef USE_MUNMAP
-# endif
-# ifdef USE_MMAP_ANON
-# undef USE_MMAP_ANON
-# endif
-# ifdef USE_MMAP_FIXED
-# undef USE_MMAP_FIXED
-# endif
-# define GETPAGESIZE() 65536
-# define MAX_NACL_GC_THREADS 1024
-# endif
# ifdef LINUX
# ifndef __GNUC__
/* The Intel compiler doesn't like inline assembly */
buf[1024] = 0x15;
(void) sprintf(buf, format, a, b, c, d, e, f);
if (buf[1024] != 0x15) ABORT("GC_printf clobbered stack");
+#ifdef NACL
+ WRITE(GC_stdout, buf, strlen(buf));
+#else
if (WRITE(GC_stdout, buf, strlen(buf)) < 0) ABORT("write to stdout failed");
+#endif
}
void GC_err_printf(format, a, b, c, d, e, f)
buf[1024] = 0x15;
(void) sprintf(buf, format, a, b, c, d, e, f);
if (buf[1024] != 0x15) ABORT("GC_err_printf clobbered stack");
+#ifdef NACL
+ WRITE(GC_stderr, buf, strlen(buf));
+#else
if (WRITE(GC_stderr, buf, strlen(buf)) < 0) ABORT("write to stderr failed");
+#endif
}
void GC_err_puts(s)
GC_CONST char *s;
{
+#ifdef NACL
+ WRITE(GC_stderr, s, strlen(s));
+#else
if (WRITE(GC_stderr, s, strlen(s)) < 0) ABORT("write to stderr failed");
+#endif
}
#if defined(LINUX) && !defined(SMALL_CONFIG)
#endif
#ifdef NACL
-int nacl_park_threads_now = 0;
+volatile int __nacl_thread_suspension_needed = 0;
pthread_t nacl_thread_parker = -1;
volatile int nacl_thread_parked[MAX_NACL_GC_THREADS];
GC_printf1("pthread_stop_world: num_threads %d\n", nacl_num_gc_threads - 1);
#endif
nacl_thread_parker = pthread_self();
- nacl_park_threads_now = 1;
+ __nacl_thread_suspension_needed = 1;
while (1) {
#define NACL_PARK_WAIT_NANOSECONDS 100000
}
}
+void __nacl_suspend_thread_if_needed();
+
void nacl_post_syscall_hook()
{
/* Calling __nacl_suspend_thread_if_needed() right away should guarantee we don't mutate the GC set. */
}
void __nacl_suspend_thread_if_needed() {
- if (nacl_park_threads_now) {
+ if (__nacl_thread_suspension_needed) {
pthread_t self = pthread_self();
int local_dummy = 0;
/* Don't try to park the thread parker. */
nacl_gc_thread_self->stop_info.stack_ptr = (ptr_t)(&local_dummy);
}
nacl_thread_parked[nacl_thread_idx] = 1;
- while (nacl_park_threads_now)
+ while (__nacl_thread_suspension_needed)
; /* spin */
nacl_thread_parked[nacl_thread_idx] = 0;
# if DEBUG_THREADS
GC_printf0("World starting\n");
# endif
- nacl_park_threads_now = 0;
+ __nacl_thread_suspension_needed = 0;
if (GC_notify_event)
GC_notify_event (GC_EVENT_POST_START_WORLD);
#endif /* NACL */
extern void nacl_post_syscall_hook();
extern void nacl_register_gc_hooks(void (*pre)(), void (*post)());
+#include <stdio.h>
+
+struct nacl_irt_blockhook {
+ int (*register_block_hooks)(void (*pre)(void), void (*post)(void));
+};
+
+extern size_t nacl_interface_query(const char *interface_ident,
+ void *table, size_t tablesize);
+
void nacl_initialize_gc_thread()
{
int i;
- nacl_register_gc_hooks(nacl_pre_syscall_hook, nacl_post_syscall_hook);
+ static struct nacl_irt_blockhook gc_hook;
+
pthread_mutex_lock(&nacl_thread_alloc_lock);
if (!nacl_thread_parking_inited)
{
nacl_thread_used[i] = 0;
nacl_thread_parked[i] = 0;
}
+ // TODO: replace with public 'register hook' function when
+ // available from glibc
+ nacl_interface_query("nacl-irt-blockhook-0.1", &gc_hook, sizeof(gc_hook));
+ gc_hook.register_block_hooks(nacl_pre_syscall_hook, nacl_post_syscall_hook);
nacl_thread_parking_inited = 1;
}
GC_ASSERT(nacl_num_gc_threads <= MAX_NACL_GC_THREADS);
/* Return the number of processors, or i<= 0 if it can't be determined. */
int GC_get_nprocs()
{
+#ifndef NACL
/* Should be "return sysconf(_SC_NPROCESSORS_ONLN);" but that */
/* appears to be buggy in many cases. */
/* We look for lines "cpu<n>" in /proc/stat. */
}
close(f);
return result;
+#else /* NACL */
+ return sysconf(_SC_NPROCESSORS_ONLN);
+#endif
}
#endif /* GC_LINUX_THREADS */
}
#ifdef NACL
-/* Native Client doesn't support pthread cleanup functions, */
-/* so wrap pthread_exit and manually cleanup the thread. */
+/* TODO: remove, NaCl glibc now supports pthread cleanup functions. */
void
WRAP_FUNC(pthread_exit)(void *status)
{
- GC_thread_exit_proc(0);
REAL_FUNC(pthread_exit)(status);
}
#endif
#endif
+#if defined(__native_client__) && defined(__GLIBC__)
+volatile int __nacl_thread_suspension_needed = 0;
+void __nacl_suspend_thread_if_needed() {}
+#endif
+
void
dump_table_assembly (MonoImage *m)
{
}
#endif
+/* Native Client has no ftruncate function, even in standalone sel_ldr. */
+#ifndef __native_client__
/* always truncate, because the extend write() adds an extra
* byte to the end of the file
*/
_wapi_set_last_error_from_errno ();
return(FALSE);
}
+#endif
return(TRUE);
}
return(INVALID_HANDLE_VALUE);
}
+#ifdef __native_client__
+ /* Workaround: Native Client currently returns the same fake inode
+ * for all files, so do a simple hash on the filename so we don't
+ * use the same share info for each file.
+ */
+ statbuf.st_ino = g_str_hash(filename);
+#endif
if (share_check (&statbuf, sharemode, fileaccess,
&file_handle.share_info, fd) == FALSE) {
goto retry;
}
+#ifndef __native_client__
result = _wapi_lstat (filename, &linkbuf);
if (result != 0) {
DEBUG ("%s: lstat failed: %s", __func__, filename);
g_free (filename);
goto retry;
}
+#endif
utf8_filename = mono_utf8_from_external (filename);
if (utf8_filename == NULL) {
else
create_time = buf.st_ctime;
+#ifdef __native_client__
+ find_data->dwFileAttributes = _wapi_stat_to_file_attributes (utf8_filename, &buf, NULL);
+#else
find_data->dwFileAttributes = _wapi_stat_to_file_attributes (utf8_filename, &buf, &linkbuf);
+#endif
_wapi_time_t_to_filetime (create_time, &find_data->ftCreationTime);
_wapi_time_t_to_filetime (buf.st_atime, &find_data->ftLastAccessTime);
return (INVALID_FILE_ATTRIBUTES);
}
+#ifndef __native_client__
result = _wapi_lstat (utf8_name, &linkbuf);
if (result != 0) {
_wapi_set_last_path_error_from_errno (NULL, utf8_name);
g_free (utf8_name);
return (INVALID_FILE_ATTRIBUTES);
}
+#endif
+#ifdef __native_client__
+ ret = _wapi_stat_to_file_attributes (utf8_name, &buf, NULL);
+#else
ret = _wapi_stat_to_file_attributes (utf8_name, &buf, &linkbuf);
+#endif
g_free (utf8_name);
glong count;
gsize bytes;
+#ifdef __native_client__
+ gchar *path = g_get_current_dir ();
+ if (length < strlen(path) + 1 || path == NULL)
+ return 0;
+ memcpy (buffer, path, strlen(path) + 1);
+#else
if (getcwd ((char*)buffer, length) == NULL) {
if (errno == ERANGE) { /*buffer length is not big enough */
gchar *path = g_get_current_dir (); /*FIXME g_get_current_dir doesn't work with broken paths and calling it just to know the path length is silly*/
_wapi_set_last_error_from_errno ();
return 0;
}
+#endif
utf16_path = mono_unicode_from_external ((gchar*)buffer, &bytes);
count = (bytes/2)+1;
#include <string.h>
#include <unistd.h>
-#ifdef HAVE_SYS_SEM_H
+#if defined(HAVE_SYS_SEM_H) && !(defined(__native_client__) && defined(__GLIBC__))
# include <sys/sem.h>
#else
# define DISABLE_SHARED_HANDLES
*/
if (g_getenv ("MONO_NO_UNLOAD"))
return;
+#ifdef __native_client__
+ return;
+#endif
mono_domain_unload (domain);
}
check_path_env (void)
{
const char* path;
-#ifdef __native_client__
- path = nacl_mono_path;
-#else
path = g_getenv ("MONO_PATH");
+#ifdef __native_client__
+ if (!path)
+ path = nacl_mono_path;
#endif
if (!path || assemblies_path != NULL)
return;
* we used to do this only when running on valgrind,
* but it happens also in other setups.
*/
-#if defined(HAVE_PTHREAD_GETATTR_NP) && defined(HAVE_PTHREAD_ATTR_GETSTACK)
+#if defined(HAVE_PTHREAD_GETATTR_NP) && defined(HAVE_PTHREAD_ATTR_GETSTACK) && !defined(__native_client__)
{
size_t size;
void *sstart;
*pchi >>= 1;
}
+#if defined(__native_client__) && (defined(__i386__) || defined(__x86_64))
+#define USE_X86_32BIT_INSTRUCTIONS 1
+#endif
+
static inline gint
my_g_bit_nth_msf (gsize mask)
{
/* Mask is expected to be != 0 */
-#if defined(__i386__) && defined(__GNUC__)
+#if (defined(__i386__) && defined(__GNUC__)) || defined(USE_X86_32BIT_INSTRUCTIONS)
int r;
__asm__("bsrl %1,%0\n\t"
}
#endif /* DISABLE_DECIMAL */
-
HANDLE done_event;
MonoInternalThread *thread = mono_thread_internal_current ();
+#if defined(__native_client__)
+ return FALSE;
+#endif
+
if (mono_thread_internal_current () == gc_thread)
/* We are called from inside a finalizer, not much we can do here */
return FALSE;
{
MONO_ARCH_SAVE_REGS;
+/* FIXME: There are some cleanup hangs that should be worked out, but
+ * if the program is going to exit, everything will be cleaned up when
+ * NaCl exits anyway.
+ */
+#ifndef __native_client__
mono_runtime_shutdown ();
/* This will kill the tp threads which cannot be suspended */
mono_thread_suspend_all_other_threads ();
mono_runtime_quit ();
+#endif
/* we may need to do some cleanup here... */
exit (result);
iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
#endif
res.value = iter->args;
+#if defined(__native_client__) && SIZEOF_REGISTER == 8
+ /* Values are stored as 8 byte register sized objects, but 'value'
+ * is dereferenced as a pointer in other routines.
+ */
+ res.value = (char*)res.value + 4;
+#endif
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
if (arg_size <= sizeof (gpointer)) {
int dummy;
int fsync(int fd) { errno=EINVAL; return -1; }
dev_t makedev(guint32 maj, guint32 min) { return (maj)*256+(min); }
+#ifdef USE_NEWLIB
+int getdtablesize(void) {
+#ifdef OPEN_MAX
+ return OPEN_MAX;
+#else
+ return 256;
+#endif
+}
+
+size_t getpagesize(void) {
+#ifdef PAGE_SIZE
+ return PAGE_SIZE;
+#else
+ return 4096;
+#endif
+}
+
+#include <semaphore.h>
+
+int sem_trywait(sem_t *sem) {
+ g_assert_not_reached ();
+ return -1;
+}
+
+int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout) {
+ g_assert_not_reached ();
+ return -1;
+}
+
+#endif
+
#endif
#include <mono/metadata/mono-gc.h>
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/runtime.h>
+#include <mono/utils/mono-threads.h>
#ifdef HAVE_NULL_GC
memset (&cb, 0, sizeof (cb));
cb.mono_method_is_critical = mono_runtime_is_critical_method;
cb.mono_gc_pthread_create = (gpointer)mono_gc_pthread_create;
+
+ mono_threads_init (&cb, sizeof (MonoThreadInfo));
}
void
#elif defined (__native_client__)
+#include <time.h>
+
MonoBoolean
ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngOpen (void)
{
gboolean
mono_threads_abort_appdomain_threads (MonoDomain *domain, int timeout)
{
+#ifdef __native_client__
+ return FALSE;
+#endif
+
abort_appdomain_data user_data;
guint32 start_time;
int orig_timeout = timeout;
int
mono_thread_kill (MonoInternalThread *thread, int signal)
{
+#ifdef __native_client__
+ /* Workaround pthread_kill abort() in NaCl glibc. */
+ return -1;
+#endif
#ifdef HOST_WIN32
/* Win32 uses QueueUserAPC and callers of this are guarded */
g_assert_not_reached ();
gshared.cs
regtests=basic.exe basic-float.exe basic-long.exe basic-calls.exe objects.exe arrays.exe basic-math.exe exceptions.exe iltests.exe devirtualization.exe generics.exe basic-simd.exe
+if NACL_CODEGEN
+test_sources += nacl.cs
+regtests += nacl.exe
+endif
if X86
if MONO_DEBUGGER_SUPPORTED
CSFLAGS = -unsafe -nowarn:0219,0169,0414,0649
-basic-simd.exe: basic-simd.cs
+basic-simd.exe: basic-simd.cs TestDriver.dll
$(MCS) -out:$@ $(CSFLAGS) $< -r:TestDriver.dll -r:Mono.Simd.dll
-nacl.exe: nacl.cs
+nacl.exe: nacl.cs TestDriver.dll
$(MCS) -out:$@ $(CSFLAGS) $< -r:TestDriver.dll -r:Mono.Simd.dll
generics.exe: generics.cs TestDriver.dll generics-variant-types.dll
if CROSS_COMPILING
GENMDESC_PRG=perl $(srcdir)/genmdesc.pl $(arch_define) $(srcdir) $(GENMDESC_OPTS)
else !CROSS_COMPILING
+if NACL_CODEGEN
+GENMDESC_PRG=perl $(srcdir)/genmdesc.pl $(arch_define) $(srcdir) $(GENMDESC_OPTS)
+else
GENMDESC_PRG=./genmdesc $(GENMDESC_OPTS)
+endif
endif !CROSS_COMPILING
cpu-x86.h: cpu-x86.md genmdesc$(EXEEXT)
for i in $(regtests); do $(RUNTIME) $$i; done
rcheck: mono $(regtests)
+if NACL_CODEGEN
+ for i in $(regtests); do echo "running test $$i"; $(RUNTIME) $$i --exclude 'NaClDisable' || exit 1; done
+else
$(RUNTIME) --regression $(regtests)
+endif
gctest: mono gc-test.exe
MONO_DEBUG_OPTIONS=clear-nursery-at-gc $(RUNTIME) --regression gc-test.exe
InitializeCriticalSection (&aot_page_mutex);
aot_modules = g_hash_table_new (NULL, NULL);
+#ifndef __native_client__
mono_install_assembly_load_hook (load_aot_module, NULL);
+#endif
if (g_getenv ("MONO_LASTAOT"))
mono_last_aot_method = atoi (g_getenv ("MONO_LASTAOT"));
class Tests {
- static int Main () {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
public static int test_10_create () {
class Tests {
- static int Main () {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
static void dummy () {
class Tests {
- public static int Main () {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
public static int test_0_beq () {
class Tests {
- public static int Main () {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
public static int test_10_simple_cast () {
class Tests {
- public static int Main () {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
public static int test_0_sin_precision () {
class Tests {
- static int Main () {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
public static int test_0_return () {
return k == -32768 ? 0 : 1;
}
-}
\ No newline at end of file
+}
#ifdef HOST_WIN32
int mixed_mode = FALSE;
#endif
+#ifdef __native_client__
+ gboolean nacl_null_checks_off = FALSE;
+#endif
#ifdef MOONLIGHT
#ifndef HOST_WIN32
#ifdef __native_client__
} else if (strcmp (argv [i], "--nacl-mono-path") == 0){
nacl_mono_path = g_strdup(argv[++i]);
+ } else if (strcmp (argv [i], "--nacl-null-checks-off") == 0){
+ nacl_null_checks_off = TRUE;
#endif
} else {
fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]);
{
nacl_align_byte = -1; /* 0xff */
}
+ if (!nacl_null_checks_off) {
+ MonoDebugOptions *opt = mini_get_debug_options ();
+ opt->explicit_null_checks = TRUE;
+ }
#endif
if (!argv [i]) {
* This used to be an amd64 only crash, but it looks like now most glibc targets do unwinding
* that requires reading the target code.
*/
-#ifdef __linux__
+#if defined( __linux__ ) || defined( __native_client__ )
mono_dont_free_global_codeman = TRUE;
#endif
class Tests {
- public static int Main () {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
public static int test_0_catch () {
return 0;
}
+ [Category ("NaClDisable")]
public static int test_0_div_zero () {
int d = 1;
int q = 0;
return 0;
}
+ [Category ("NaClDisable")]
public static int test_0_long_div_zero () {
long d = 1;
long q = 0;
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/assembly.h>
-#include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/object.h>
-#include <mono/jit/jit.h>
-#include <mono/utils/mono-logger.h>
-
-extern void* mono_aot_module_mscorlib_info;
-extern void* mono_aot_module_System_Core_info;
-extern void* mono_aot_module_System_info;
-extern void* mono_aot_module_Mono_Posix_info;
-extern void* mono_aot_module_System_Configuration_info;
-extern void* mono_aot_module_System_Security_info;
-extern void* mono_aot_module_System_Xml_info;
-/* extern void* mono_aot_module_System_Threading_info; */
-extern void* mono_aot_module_Mono_Security_info;
-extern void* mono_aot_module_Mono_Simd_info;
-extern void* mono_aot_module_TestDriver_info;
-
-extern void* mono_aot_module_basic_info;
-extern void* mono_aot_module_basic_float_info;
-extern void* mono_aot_module_basic_long_info;
-extern void* mono_aot_module_basic_calls_info;
-extern void* mono_aot_module_basic_simd_info;
-extern void* mono_aot_module_objects_info;
-extern void* mono_aot_module_arrays_info;
-extern void* mono_aot_module_basic_math_info;
-extern void* mono_aot_module_exceptions_info;
-extern void* mono_aot_module_devirtualization_info;
-extern void* mono_aot_module_generics_info;
-extern void* mono_aot_module_generics_variant_types_info;
-extern void* mono_aot_module_basic_simd_info;
-extern void* mono_aot_module_gc_stress_info;
-extern void* mono_aot_module_imt_big_iface_test_info;
-extern void* mono_aot_module_make_imt_test_info;
-/* extern void* mono_aot_module_thread_stress_info; */
-extern void* mono_aot_module_iltests_info;
-
-extern void mono_aot_register_module(void *aot_info);
-extern void mono_aot_init(void);
-extern void mono_jit_set_aot_only(mono_bool aot_only);
-extern MonoDomain * mini_init (const char *filename, const char *runtime_version);
-
-int run_all_test_methods(MonoClass *klass) {
- void * iter = NULL;
- MonoMethod *mm = NULL;
- int count = 0;
- int passed = 0;
- printf("Running test methods without reflection\n");
- while (NULL != (mm = mono_class_get_methods(klass, &iter))) {
- long expected_result;
- const char *name = mono_method_get_name(mm);
- char *end = NULL;
- if (strncmp(name, "test_", 5)) continue;
- printf("=== Test %d, method %s\n", count, mono_method_get_name(mm));
- expected_result = strtol(name + 5, &end, 10);
- if (name == end) {
- printf(" warning: could not determine expected return value\n");
- expected_result = 0;
- }
- MonoObject *mo = mono_runtime_invoke(mm, NULL, NULL, NULL);
- int *ret = mono_object_unbox(mo);
- if (ret && *ret == expected_result) {
- printf(" passed!\n");
- passed++;
- } else {
- printf(" FAILED, expected %d, returned %p, %d\n", expected_result, ret,
- ret != NULL ? *ret : 0);
- }
- count++;
- }
- if (count > 0) {
- printf("============================================\n");
- printf("Final count: %d tests, %d pass, %.2f%%\n", count, passed,
- (double)passed / count * 100.0);
- } else {
- printf("no test methods found.\n");
- }
- return count;
-}
-
-#if defined(__native_client__)
-extern void* mono_aot_module_nacl_info;
-extern char* nacl_mono_path;
-char *load_corlib_data() {
- FILE *mscorlib;
- static char *corlib_data = NULL;
- if (corlib_data) return corlib_data;
-
- mscorlib = fopen("mscorlib.dll", "r");
- if (NULL != mscorlib) {
- size_t size;
- struct stat st;
- if (0 == stat("mscorlib.dll", &st)) {
- size = st.st_size;
- printf("reading mscorlib.dll, size %ld\n", size);
- corlib_data = malloc(size);
- if (corlib_data != NULL) {
- while (fread(corlib_data, 1, size, mscorlib) != 0) ;
- if (!ferror(mscorlib)) {
- mono_set_corlib_data(corlib_data, size);
- } else {
- perror("error reading mscorlib.dll");
- free(corlib_data);
- corlib_data = NULL;
- }
- } else {
- perror("Could not allocate memory");
- }
- } else {
- perror("stat error");
- }
- fclose(mscorlib);
- }
- return corlib_data;
-}
-#endif
-
-/* Initialize Mono. Must run only once per process */
-MonoDomain *init_mono(char *mname) {
- MonoDomain *domain = NULL;
-#ifdef AOT_VERSION
- mono_jit_set_aot_only(1);
- mono_aot_register_module(mono_aot_module_mscorlib_info);
- mono_aot_register_module(mono_aot_module_TestDriver_info);
- mono_aot_register_module(mono_aot_module_System_Core_info);
- mono_aot_register_module(mono_aot_module_System_info);
- mono_aot_register_module(mono_aot_module_Mono_Posix_info);
- mono_aot_register_module(mono_aot_module_System_Configuration_info);
- mono_aot_register_module(mono_aot_module_System_Security_info);
- mono_aot_register_module(mono_aot_module_System_Xml_info);
- mono_aot_register_module(mono_aot_module_Mono_Security_info);
- /* mono_aot_register_module(mono_aot_module_System_Threading_info); */
- mono_aot_register_module(mono_aot_module_Mono_Simd_info);
-
- mono_aot_register_module(mono_aot_module_basic_info);
- mono_aot_register_module(mono_aot_module_basic_float_info);
- mono_aot_register_module(mono_aot_module_basic_long_info);
- mono_aot_register_module(mono_aot_module_basic_calls_info);
- mono_aot_register_module(mono_aot_module_basic_simd_info);
- mono_aot_register_module(mono_aot_module_objects_info);
- mono_aot_register_module(mono_aot_module_arrays_info);
- mono_aot_register_module(mono_aot_module_basic_math_info);
- mono_aot_register_module(mono_aot_module_exceptions_info);
- mono_aot_register_module(mono_aot_module_devirtualization_info);
- mono_aot_register_module(mono_aot_module_generics_info);
- mono_aot_register_module(mono_aot_module_generics_variant_types_info);
- mono_aot_register_module(mono_aot_module_gc_stress_info);
- mono_aot_register_module(mono_aot_module_imt_big_iface_test_info);
- mono_aot_register_module(mono_aot_module_iltests_info);
-#endif
- /* mono_aot_register_module(mono_aot_module_make_imt_test_info); */
- /* mono_aot_register_module(mono_aot_module_thread_stress_info); */
-#if defined(__native_client__)
-#ifdef AOT_VERSION
- mono_aot_register_module(mono_aot_module_nacl_info);
-#endif
-
- /* Test file-less shortcut for loading mscorlib metadata */
- load_corlib_data();
- nacl_mono_path = strdup(".");
-#endif
- /* Uncomment the following if something is going wrong */
- /* mono_trace_set_level_string("info"); */
- domain = mono_jit_init(mname);
- if (NULL == domain) {
- printf("ERROR: mono_jit_init failure\n");
- exit(-1);
- }
- return domain;
-}
-
-/* Run all tests from one assembly file */
-int try_one(char *mname, MonoDomain *domain) {
- MonoAssembly *ma;
- MonoImage *mi;
- MonoClass *mc;
- MonoMethodDesc *mmd;
- MonoMethod *mm;
- MonoObject *mo;
- MonoString *monostring_arg;
- MonoArray *arg_array;
- int *failures = NULL;
- const int kUseTestDriver = 1;
- int test_count = 0;
- void *args [1];
- char *cstr_arg = "--timing";
-
- ma = mono_domain_assembly_open(domain, mname);
- if (NULL == ma) {
- printf("ERROR: could not open mono assembly\n");
- exit(-1);
- }
-
- mi = mono_assembly_get_image(ma);
- if (NULL == mi) {
- printf("ERROR: could not get assembly image\n");
- exit(-1);
- }
-
- monostring_arg = mono_string_new(domain, cstr_arg);
- mc = mono_class_from_name(mono_get_corlib(), "System", "String");
- if (0 == mc) {
- printf("ERROR: could not mono string class\n");
- exit(-1);
- }
-
- // to pass a string argument, change the 0 to a 1 and uncomment
- // mono_array_setref below
- arg_array = mono_array_new(domain, mc, 0);
- //mono_array_setref(arg_array, 0, monostring_arg);
- args[0] = arg_array;
-
- if (!kUseTestDriver) {
- mc = mono_class_from_name(mi, "", "Tests");
- if (NULL == mc) {
- printf("could not open Tests class\n");
- exit(-1);
- }
- test_count = run_all_test_methods(mc);
- }
- /* If run_all_test_methods didn't find any tests, try Main */
- if (kUseTestDriver || test_count == 0) {
- mmd = mono_method_desc_new("Tests:Main()", 1);
- mm = mono_method_desc_search_in_image(mmd, mi);
- if (0 == mm) {
- mmd = mono_method_desc_new("Tests:Main(string[])", 1);
- mm = mono_method_desc_search_in_image(mmd, mi);
- if (0 == mm) {
- printf("Couldn't find Tests:Main() or Tests:Main(string[])\n");
- exit(-1);
- }
- }
-
- mo = mono_runtime_invoke(mm, NULL, args, NULL);
- failures = mo != NULL ? mono_object_unbox(mo) : NULL;
- if (NULL == failures || *failures != 0) {
- printf("--------------------> Failed");
- }
- }
- return failures != NULL ? failures : 1;
-}
-
-int main(int argc, char *argv[]) {
- MonoDomain *domain;
- int failures = 0;
-
- if (argc < 2) {
- printf("no test specified; running basic.exe\n");
- printf("================================\n");
- domain = init_mono("basic.exe");
- try_one("basic.exe", domain);
- } else {
- domain = init_mono(argv[1]);
- int i;
- for (i = 1; i < argc; i++) {
- printf("\nRunning tests from %s:\n", argv[i]);
- printf("===============================\n\n");
- failures += try_one(argv[i], domain);
- }
- }
- mono_jit_cleanup(domain);
- return failures;
-}
#include <string.h>
#include <mono/metadata/opcodes.h>
+#if defined(__native_client__) || defined(__native_client_codegen__)
+volatile int __nacl_thread_suspension_needed = 0;
+void __nacl_suspend_thread_if_needed() {}
+#endif
+
#define MINI_OP(a,b,dest,src1,src2) b,
#define MINI_OP3(a,b,dest,src1,src2,src3) b,
/* keep in sync with the enum in mini.h */
void
mono_disassemble_code (MonoCompile *cfg, guint8 *code, int size, char *id)
{
+#if defined(__native_client__)
+ return;
+#endif
#ifndef DISABLE_LOGGING
GHashTable *offset_to_bb_hash = NULL;
int i, cindex, bb_num;
GC_start_blocking;
GC_end_blocking;
gc_thread_vtable;
+ __nacl_suspend_thread_if_needed;
+ __nacl_thread_suspension_needed;
+ nacl_mono_path;
local:
*;
};
/* image-writer.c doesn't happen */
#define kNaClLengthOfCallImm kNaClAlignmentAMD64
-int is_nacl_call_reg_sequence(guint8* code);
+int is_nacl_call_reg_sequence (guint8* code);
+void amd64_nacl_clear_legacy_prefix_tag ();
+void amd64_nacl_tag_legacy_prefix (guint8* code);
+void amd64_nacl_tag_rex (guint8* code);
+guint8* amd64_nacl_get_legacy_prefix_tag ();
+guint8* amd64_nacl_get_rex_tag ();
+void amd64_nacl_instruction_pre ();
+void amd64_nacl_instruction_post (guint8 **start, guint8 **end);
+void amd64_nacl_membase_handler (guint8** code, gint8 basereg, gint32 offset, gint8 dreg);
#endif
#ifdef HOST_WIN32
} else {
tls->unwind_state.unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
if (sigctx) {
+#ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
mono_arch_sigctx_to_monoctx (sigctx, &tls->unwind_state.ctx);
tls->unwind_state.valid = TRUE;
+#else
+ tls->unwind_state.valid = FALSE;
+#endif
} else if (ctx) {
memcpy (&tls->unwind_state.ctx, ctx, sizeof (MonoContext));
tls->unwind_state.valid = TRUE;
{
}
+pid_t
+mono_runtime_syscall_fork (void)
+{
+ g_assert_not_reached();
+ return 0;
+}
+void
+mono_gdb_render_native_backtraces (pid_t crashed_pid)
+{
+}
#else
patch_info.data.method = method;
g_hash_table_remove (domain_jit_info (target_domain)->jump_target_hash, method);
+#if defined(__native_client_codegen__) && defined(__native_client__)
+ /* These patches are applied after a method has been installed, no target munging is needed. */
+ nacl_allow_target_modification (FALSE);
+#endif
for (tmp = jlist->list; tmp; tmp = tmp->next)
mono_arch_patch_code (NULL, target_domain, tmp->data, &patch_info, NULL, TRUE);
+#if defined(__native_client_codegen__) && defined(__native_client__)
+ nacl_allow_target_modification (TRUE);
+#endif
}
}
#include "mini-unwind.h"
#include "jit.h"
+#ifdef __native_client_codegen__
+#include <nacl/nacl_dyncode.h>
+#endif
+
+
/*
* The mini code should not have any compile time dependencies on the GC being used, so the same object file from mini/
* can be linked into both mono and mono-sgen.
#endif
#if defined(__native_client__) || defined(__native_client_codegen__)
+extern volatile int __nacl_thread_suspension_needed;
+extern void __nacl_suspend_thread_if_needed();
void mono_nacl_gc();
#endif
using System;
using Mono.Simd;
+using System.Threading;
+
+class A {
+ public void Print() { Console.WriteLine("A"); }
+}
+
+class B : A {
+ public void Print() { Console.WriteLine("B"); }
+}
+
+class ThreadRunner {
+ public Int32 Inc2(Int32 a) { return Inc1(a); }
+ public Int32 Inc1(Int32 a) { return a + 2; }
+ public void PrintA(A a) { a.Print(); ((B)a).Print(); }
+ public void Run() {
+ Console.WriteLine("Running thread" );
+ B b = new B();
+ Int32 a=0;
+ for(int i = 0; i < 1000000; i++) {
+ a = Inc2(a);
+ if(i % 100000 == 0) PrintA(b);
+ }
+ Console.WriteLine("Ending thread");
+ }
+}
+
+
+class Extensions { public static string BogusProperty { get; set; } }
+
+class RuntimeServices {
+ public System.Reflection.MemberInfo[] members = typeof(Extensions).GetMembers();
+ public void Run() {
+ foreach (var m in members) System.Console.WriteLine(m);
+ }
+}
class Tests {
struct myvt {
- public int X;
- public int Y;
+ public int X;
+ public int Y;
}
static int test_0_vector4i_cmp_gt () {
- Vector4i a = new Vector4i (10, 5, 12, -1);
+ Vector4i a = new Vector4i (10, 5, 12, -1);
Vector4i b = new Vector4i (-1, 5, 10, 10);
Vector4i c = a.CompareGreaterThan (b);
-
+
if (c.X != -1)
return 1;
if (c.Y != 0)
return 2;
if (c.Z != -1)
- return 3;
+ return 3;
if (c.W != 0)
- return 4;
+ return 4;
return 0;
}
static myvt CompareGT(myvt a, myvt b) {
- myvt r;
- r.X = a.X > b.X ? -1 : 0;
- r.Y = a.Y > b.Y ? -1 : 0;
- return r;
+ myvt r;
+ r.X = a.X > b.X ? -1 : 0;
+ r.Y = a.Y > b.Y ? -1 : 0;
+ return r;
}
static int test_0_struct2i_cmp_gt() {
- myvt a;
- myvt b;
- a.X = 10;
- a.Y = 5;
- b.X = -1;
- b.Y = 5;
- myvt c = CompareGT(a, b);
- if (c.X != -1)
- return 1;
- if (c.Y != 0)
- return 2;
- return 0;
+ myvt a;
+ myvt b;
+ a.X = 10;
+ a.Y = 5;
+ b.X = -1;
+ b.Y = 5;
+ myvt c = CompareGT(a, b);
+ if (c.X != -1)
+ return 1;
+ if (c.Y != 0)
+ return 2;
+ return 0;
}
static int vararg_sum(params int[] args) {
- int sum = 0;
- foreach(int arg in args) {
- sum += arg;
- }
- return sum;
+ int sum = 0;
+ foreach(int arg in args) {
+ sum += arg;
+ }
+ return sum;
}
static int test_21_vararg_test() {
- int sum = 0;
- sum += vararg_sum();
- sum += vararg_sum(1);
- sum += vararg_sum(2, 3);
- sum += vararg_sum(4, 5, 6);
- return sum;
+ int sum = 0;
+ sum += vararg_sum();
+ sum += vararg_sum(1);
+ sum += vararg_sum(2, 3);
+ sum += vararg_sum(4, 5, 6);
+ return sum;
}
+
+ static int test_0_threads() {
+ // Run a bunch of threads, make them JIT some code and
+ // do some casts
+ ThreadRunner runner = new ThreadRunner();
+ Thread[] threads = new Thread[10];
+ for (int i = 0; i < 10; i++) {
+ threads[i] = new Thread(new ThreadStart(runner.Run));
+ threads[i].Start();
+ }
+ for (int i = 0; i < 10; i++) {
+ threads[i].Join();
+ }
+ return 0;
+ }
+
+
+ static int test_0_reflection() {
+ RuntimeServices r = new RuntimeServices();
+ r.Run();
+ return 0;
+ }
+
+ public class BaseClass {
+ }
+
+ public class LongClass : BaseClass {
+ public long Value;
+ public LongClass(long val) { Value = val; }
+ }
+
+ static public long add_two_LongClass(BaseClass l1, BaseClass l2) {
+ long l = checked (((LongClass)l1).Value + ((LongClass)l2).Value);
+ return l;
+ }
+
+ static int test_0_laddcc() {
+ long l = add_two_LongClass(new LongClass(System.Int64.MinValue), new LongClass(1234));
+ if (l == 1234)
+ return 1;
+ return 0;
+ }
+
public static int Main(String[] args) {
- return TestDriver.RunTests(typeof(Tests));
+ return TestDriver.RunTests(typeof(Tests));
}
}
class Tests {
- static int Main () {
- return TestDriver.RunTests (typeof (Tests));
+ public static int Main (string[] args) {
+ return TestDriver.RunTests (typeof (Tests), args);
}
public static int test_0_return () {
-
+#if defined(__native_client__) && defined(__x86_64__)
+typedef guint64 regmask_t;
+#else
typedef size_t regmask_t;
+#endif
enum {
MONO_REG_INT,
#include "mini.h"
-#if defined(HOST_WIN32) || !defined(HAVE_SYS_IPC_H) || !defined(HAVE_SYS_SEM_H)
+#if defined(HOST_WIN32) || !defined(HAVE_SYS_IPC_H) || !defined(HAVE_SYS_SEM_H) || (defined(__native_client__) && defined(__GLIBC__))
int mini_wapi_hps (int argc, char **argv)
{
static int verbose = 0;
static const char *graph_properties = "\tnode [fontsize=8.0]\n\tedge [len=2,color=red]\n";
+#if defined(__native_client__) || defined(__native_client_codegen__)
+volatile int __nacl_thread_suspension_needed = 0;
+void __nacl_suspend_thread_if_needed() {}
+#endif
+
static void
output_type_edge (MonoClass *first, MonoClass *second) {
if (include_namespace)
fclose (output);
return 0;
}
-
-
testlog: $(PLOG_TESTS)
$(with_mono_path) perl $(srcdir)/ptestrunner.pl $(top_builddir)
+if NACL_CODEGEN
+check-local:
+else
check-local: testlog
+endif
EXTRA_DIST=utils.c utils.h proflog.h log-profiler.txt perf_event.h \
$(PLOG_TESTS_SRC) ptestrunner.pl
#define HASH_SIZE 9371
#define SMALL_HASH_SIZE 31
+#if defined(__native_client__) || defined(__native_client_codegen__)
+volatile int __nacl_thread_suspension_needed = 0;
+void __nacl_suspend_thread_if_needed() {}
+#endif
+
static int debug = 0;
static int collect_traces = 0;
static int show_traces = 0;
#PLATFORM_DISABLED_TESTS=dynamic-method-resurrection.exe exception17.exe
endif
+if NACL_CODEGEN
+# Tests that use Thread.Abort()
+PLATFORM_DISABLED_TESTS= abort-stress-1.exe \
+ abort-stress-2.exe \
+ abort-stress-3.exe \
+ appdomain-thread-abort.exe \
+ async-exc-compilation.exe \
+ bug-561239.exe \
+ bug-70561.exe \
+ finalizer-abort.exe \
+ finally_guard.exe \
+ main-returns-abort-resetabort.exe \
+ main-returns-background-abort-resetabort.exe \
+ thread6.exe \
+ threadpool-exceptions5.exe \
+ threadpool-exceptions6.exe
+
+# Tests that rely on AppDomain.Unload
+PLATFORM_DISABLED_TESTS+= appdomain-async-invoke.exe \
+ appdomain-exit.exe \
+ appdomain-unload-callback.exe \
+ appdomain-unload.exe \
+ domain-stress.exe \
+ generic-unloading.2.exe \
+ monitor.exe \
+ remoting4.exe \
+ threadpool-exceptions7.exe \
+ xdomain-threads.exe
+
+# pinvoke2 attaches a thread to the runtime, but
+# doesn't 'unattach' it and it hangs in GC on exit
+PLATFORM_DISABLED_TESTS+= pinvoke2.exe
+
+# Tests that currently hang waiting for non-main threads
+# to exit in NaCl, need to investigate. Most are AppDomain
+# creation and Delegate tests.
+PLATFORM_DISABLED_TESTS+= appdomain1.exe \
+ delegate9.exe \
+ marshal-valuetypes.exe \
+ cross-domain.exe \
+ stackframes-async.2.exe \
+ generic-marshalbyref.2.exe \
+ generic-xdomain.2.exe \
+ bug-415577.exe
+
+# Tests that fail trying to write files (appdomain create mostly)
+PLATFORM_DISABLED_TESTS+= bug-335131.2.exe \
+ bug-349190.2.exe \
+ bug-80307.exe \
+ bug-462592.exe
+
+# FIXME: don't know why delegate2.exe fails, it shouldn't
+PLATFORM_DISABLED_TESTS+= delegate2.exe
+
+# These tests newly fail with the latest revision. pinvoke3 fails because
+# of a thread attach, the others have not been investigated. TODO revisit.
+PLATFORM_DISABLED_TESTS+= pinvoke3.exe \
+ async_read.exe \
+ async-with-cb-throws.exe \
+ appdomain-unload-doesnot-raise-pending-events.exe \
+ gsharing-valuetype-layout.exe
+
+if X86
+# FIXME: There are problems with async callbacks and results on NaCl 32-bit
+PLATFORM_DISABLED_TESTS+= delegate1.exe \
+ delegate3.exe \
+ delegate5.exe \
+ delegate8.exe \
+ threadpool.exe \
+ threadpool1.exe \
+ threadpool-exceptions3.exe \
+ bug-323114.exe \
+ delegate-exit.exe \
+ bug-80392.2.exe
+
+# FIXME: These tests hang/fail for unknown reasons, deal with exiting
+PLATFORM_DISABLED_TESTS+= main-returns-background-resetabort.exe \
+ main-returns-background.exe \
+ main-returns-background-change.exe
+endif
+
+endif
+
+# The two finalizer tests only work under sgen
+# gc-altstack.exe fails under boehm because it has no support for altstack
# bug-459094.exe creates an extremely deep directory tree
# delegate-invoke.exe depends on 929c6bc9b6d76a273f251e6f5dfacac36e9c38bd which was
# reverted.
# Test that no symbols are missed in eglib-remap.h
#
OK_G_SYMBOLS='g_list\|g_slist\|g_concat_dir_and_file'
+if NACL_CODEGEN
+test-eglib-remap:
+else
test-eglib-remap:
@echo "Testing eglib remap..."
@if which nm > /dev/null; then if nm $(top_builddir)/mono/mini/mono | grep -v $(OK_G_SYMBOLS) | grep 't g_'; then exit 1; else exit 0; fi; fi
+endif
#
# Tests that the internals in mono/io-layer/messages.c are ok by triggering the
# code that checks that the table is properly sorted
#
+if NACL_CODEGEN
+test-messages:
+else
test-messages: w32message.exe
> test_messages.zero
$(with_mono_path) $(JITTEST_PROG_RUN) w32message.exe >& w32message.allout && cmp test_messages.zero w32message.allout
+endif
if MOONLIGHT
test_2_1 : test-coreclr-security
test-generic-sharing-managed: test-runner.exe $(GSHARED_TESTS)
@$(RUNTIME) ./test-runner.exe -j a --opt-sets "gshared gshared,shared gshared,-inline gshared,-inline,shared" $(GSHARED_TESTS)
+if NACL_CODEGEN
+test-generic-sharing:
+else
test-generic-sharing:
@if test x$(M) != x; then $(MAKE) test-generic-sharing-managed; else $(MAKE) test-generic-sharing-normal; fi
+endif
EXTRA_DIST += async-exceptions.cs
async-exceptions.exe : async-exceptions.cs
sed -e 's,LIBTOOL =,LIBTOOL2 =,g' Makefile > 2 && echo "LIBTOOL = bash ./libtool" > 1 && cat 1 2 > Makefile
touch libtest.c
+
+if NACL_CODEGEN
+test-process-exit:
+else
EXTRA_DIST += bug-438454.cs bug-438454.exe.stdout.expected threadpool-in-processexit.cs threadpool-in-processexit.exe.stdout.expected
test-process-exit:
@$(MCS) $(srcdir)/bug-438454.cs -out:bug-438454.exe
@echo "Testing threadpool-in-processexit.exe..."
@$(RUNTIME) threadpool-in-processexit.exe > threadpool-in-processexit.exe.stdout
@diff -w threadpool-in-processexit.exe.stdout $(srcdir)/threadpool-in-processexit.exe.stdout.expected
+endif
OOM_TESTS = \
gc-oom-handling.exe \
CodeChunk *current;
CodeChunk *full;
#if defined(__native_client_codegen__) && defined(__native_client__)
- MonoGHashTable *hash;
+ GHashTable *hash;
#endif
};
if (next_dynamic_code_addr == NULL) {
const guint kPageMask = 0xFFFF; /* 64K pages */
next_dynamic_code_addr = (uintptr_t)(etext + kPageMask) & ~kPageMask;
+#if defined (__GLIBC__)
+ /* TODO: For now, just jump 64MB ahead to avoid dynamic libraries. */
+ next_dynamic_code_addr += (uintptr_t)0x4000000;
+#else
/* Workaround bug in service runtime, unable to allocate */
/* from the first page in the dynamic code section. */
- /* TODO: remove */
next_dynamic_code_addr += (uintptr_t)0x10000;
+#endif
}
- cman->hash = mono_g_hash_table_new (NULL, NULL);
- /* Keep the hash table from being collected */
- mono_gc_register_root (&cman->hash, sizeof (void*), NULL);
+ cman->hash = g_hash_table_new (NULL, NULL);
if (patch_source_base == NULL) {
patch_source_base = g_malloc (kMaxPatchDepth * sizeof(unsigned char *));
patch_dest_base = g_malloc (kMaxPatchDepth * sizeof(unsigned char *));
/* Allocate code space from the service runtime */
code_ptr = allocate_code (size);
/* Insert pointer to code space in hash, keyed by buffer ptr */
- mono_g_hash_table_insert (cman->hash, temp_ptr, code_ptr);
+ g_hash_table_insert (cman->hash, temp_ptr, code_ptr);
nacl_jit_check_init ();
unsigned char *code;
int status;
g_assert (newsize <= size);
- code = mono_g_hash_table_lookup (cman->hash, data);
+ code = g_hash_table_lookup (cman->hash, data);
g_assert (code != NULL);
/* Pad space after code with HLTs */
/* TODO: this is x86/amd64 specific */
}
status = nacl_dyncode_create (code, data, newsize);
if (status != 0) {
+ unsigned char *codep;
+ fprintf(stderr, "Error creating Native Client dynamic code section attempted to be\n"
+ "emitted at %p (hex dissasembly of code follows):\n", code);
+ for (codep = data; codep < data + newsize; codep++)
+ fprintf(stderr, "%02x ", *codep);
+ fprintf(stderr, "\n");
g_assert_not_reached ();
}
- mono_g_hash_table_remove (cman->hash, data);
+ g_hash_table_remove (cman->hash, data);
g_assert (data == patch_source_base[patch_current_depth]);
g_assert (code == patch_dest_base[patch_current_depth]);
patch_current_depth--;
void *
nacl_code_manager_get_code_dest (MonoCodeManager *cman, void *data)
{
- return mono_g_hash_table_lookup (cman->hash, data);
+ return g_hash_table_lookup (cman->hash, data);
}
#endif
{
#ifdef MONO_CROSS_COMPILE
g_assert_not_reached ();
+#elif defined(__native_client__)
+ g_assert_not_reached ();
#else
arm_ucontext *my_uc = sigctx;
{
#ifdef MONO_CROSS_COMPILE
g_assert_not_reached ();
+#elif defined(__native_client__)
+ g_assert_not_reached ();
#else
arm_ucontext *my_uc = ctx;
*
* Returns: 0 on success.
*/
+#if defined(__native_client__)
+int
+mono_mprotect (void *addr, size_t length, int flags)
+{
+ int prot = prot_from_flags (flags);
+ void *new_addr;
+
+ if (flags & MONO_MMAP_DISCARD) memset (addr, 0, length);
+
+ new_addr = mmap(addr, length, prot, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
+ if (new_addr == addr) return 0;
+ return -1;
+}
+#else
int
mono_mprotect (void *addr, size_t length, int flags)
{
}
return mprotect (addr, length, prot);
}
+#endif // __native_client__
#else
if (g_path_is_absolute (path)) {
abspath = g_strdup (path);
} else {
-#ifdef __native_client__
- gchar *tmpdir = ".";
- abspath = g_build_filename (tmpdir, path, NULL);
-#else
gchar *tmpdir = g_get_current_dir ();
abspath = g_build_filename (tmpdir, path, NULL);
g_free (tmpdir);
-#endif
}
#ifdef HOST_WIN32
errno = old_errno;
}
return result;
+#elif defined(__native_client__)
+ /* Workaround pthread_kill abort() in NaCl glibc. */
+ return 0;
#else
return pthread_kill (mono_thread_info_get_tid (info), signum);
#endif
if ((mask == 0) || (nth_bit == BITS_PER_CHUNK))
return -1;
-#if defined(__i386__) && defined(__GNUC__)
+#if defined(__native_client__) && (defined(__i386__) || defined(__x86_64))
+#define USE_X86_32BIT_INSTRUCTIONS 1
+#endif
+
+#if (defined(__i386__) && defined(__GNUC__)) || defined(USE_X86_32BIT_INSTRUCTIONS)
{
int r;
/* This depends on mask != 0 */
my_g_bit_nth_lsf_nomask (gsize mask)
{
/* Mask is expected to be != 0 */
-#if defined(__i386__) && defined(__GNUC__)
+#if (defined(__i386__) && defined(__GNUC__)) || defined(USE_X86_32BIT_INSTRUCTIONS)
int r;
__asm__("bsfl %1,%0\n\t"
}
#endif
-
fi; done; done; \
$$ok
+if NACL_CODEGEN
+check-local:
+else
check-local: mcs-compileall mcs-do-test-profiles
$(MAKE) $(test_select) mcs-do-run-test-profiles
+endif
# Compile all mcs tests
test: mcs-do-test-profiles
PATH="$r/runtime/_tmpinst/bin:$PATH"
MONO_SHARED_DIR=$r/runtime
export MONO_CFG_DIR MONO_SHARED_DIR PATH
+if [ -n "@nacl_self_host@" ]; then
+ case "$@" in
+ # gacutil.exe and mdoc.exe require filesystem functionality not
+ # exposed in NaCl.
+ # mcs.exe was added to the list recently because mcs under NaCl
+ # no longer produces equivalent output. TODO: investigate
+ */mcs.exe* | */gacutil.exe* | */mdoc.exe* ) exec /usr/local/bin/mono "$@";;
+ esac
+fi
exec "$r/libtool" --mode=execute "$r/@mono_runtime@" --config "@mono_cfg_dir@/mono/config" "$@"