# Process this file with autoconf to produce a configure script.
#AC_PREREQ([2.62])
-AC_INIT(mono, [3.0.8],
+AC_INIT(mono, [3.0.10],
[http://bugzilla.xamarin.com/enter_bug.cgi?classification=Mono])
AC_CONFIG_SRCDIR([README])
AC_ARG_ENABLE(minimal, [ --enable-minimal=LIST drop support for LIST subsystems.
LIST is a comma-separated list from: aot, profiler, decimal, pinvoke, debug, appdomains, verifier,
reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd, soft_debug, perfcounters, normalization, assembly_remapping, shared_perfcounters, remoting,
- sgen_remset, sgen_marksweep_par, sgen_marksweep_fixed, sgen_marksweep_fixed_par, sgen_copying.],
+ security, sgen_remset, sgen_marksweep_par, sgen_marksweep_fixed, sgen_marksweep_fixed_par, sgen_copying.],
[
for feature in `echo "$enable_minimal" | sed -e "s/,/ /g"`; do
eval "mono_feature_disable_$feature='yes'"
AC_MSG_NOTICE([Disabled remoting])
fi
+if test "x$mono_feature_disable_security" = "xyes"; then
+ AC_DEFINE(DISABLE_SECURITY, 1, [Disable CAS/CoreCLR security])
+ AC_MSG_NOTICE([Disabled CAS/CoreCLR security manager (used e.g. for Moonlight)])
+fi
+
if test "x$mono_feature_disable_sgen_remset" = "xyes"; then
AC_DEFINE(DISABLE_SGEN_REMSET, 1, [Disable wbarrier=remset support in SGEN.])
AC_MSG_NOTICE([Disabled wbarrier=remset support in SGEN.])
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
AC_MSG_RESULT(ok)
], [
AC_MSG_RESULT(no)
- AC_MSG_WARN(Using mono_mutex_t for recursive mutexes)
- AC_DEFINE(USE_MONO_MUTEX, 1, [Use mono_mutex_t])
+ AC_ERROR(Posix system lacks support for recursive mutexes)
])
AC_CHECK_FUNCS(pthread_attr_setstacksize)
AC_CHECK_FUNCS(pthread_attr_getstack pthread_attr_getstacksize)
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
NESTED_LIBGC_FLAGS="$NESTED_LIBGC_FLAGS -DHAVE_ARMV6"
fi
;;
- s390-*-linux*)
- TARGET=S390;
- arch_target=s390;
- ACCESS_UNALIGNED="yes"
- JIT_SUPPORTED=yes
- sgen_supported=true
- # Required CFLAGS for s390[x]. USE_STRING_INLINES is automatic with gcc 4.1
- CFLAGS="$CFLAGS -mbackchain -D__USE_STRING_INLINES"
- ;;
+# TODO: make proper support for NaCl host.
+# arm*-*nacl)
+# TARGET=ARM;
+# arch_target=arm;
+# ACCESS_UNALIGNED="no"
+# JIT_SUPPORTED=yes
+# sgen_supported=true
+# AOT_SUPPORTED="no"
+# ;;
s390x-*-linux*)
TARGET=S390x;
arch_target=s390x;
AC_DEFINE(__mono_ilp32__, 1, [64 bit mode with 4 byte longs and pointers])
sizeof_register=8
;;
- *-*-nacl)
+# TODO: make proper support for NaCl target.
+# arm*-*nacl)
+# TARGET=ARM
+# arch_target=arm
+# AC_DEFINE(TARGET_ARM, 1, [...])
+# ACCESS_UNALIGNED="no"
+# JIT_SUPPORTED=yes
+# sizeof_register=4
+# CPPFLAGS="$CPPFLAGS \
+# -DARM_FPU_VFP=1 -D__ARM_EABI__ \
+# -D__arm__ \
+# -D__portable_native_client__ \
+# -DARM_FPU_VFP=1 \
+# -Dtimezone=_timezone \
+# -DDISABLE_SOCKETS \
+# -DDISABLE_ATTACH \
+# -DUSE_NEWLIB"
+# jit_wanted=true
+ # Can't use tls, since it depends on the runtime detection of tls offsets
+ # in mono-compiler.h
+# with_tls=pthread
+# ;;
+ i686-*-nacl)
TARGET=X86
arch_target=x86
AC_DEFINE(TARGET_X86, 1, [...])
])
fi
-if test ${TARGET} = ARM && test x$cross_compiling = xno && test x$enable_mcs_build != xno; then
+if test ${TARGET} = ARM; then
dnl ******************************************
dnl *** Check to see what FPU is available ***
dnl ******************************************
AC_MSG_CHECKING(which FPU to use)
+ #
+ # This is a bit tricky:
+ #
+ # if (__ARM_PCS_VFP) {
+ # /* mfloat-abi=hard == VFP with hard ABI */
+ # } elif (!__SOFTFP__) {
+ # /* mfloat-abi=softfp == VFP with soft ABI */
+ # } else {
+ # /* mfloat-abi=soft == no VFP */
+ # }
+ #
+ # The exception is iOS (w/ GCC) where none of the above
+ # are defined (but iOS always uses the 'softfp' ABI).
+ #
+ # No support for FPA.
+ #
+
fpu=NONE
- if gcc -v 2>&1 | grep -q -- '--with-float=hard'; then
- fpu=VFP_HARD
+
+ # iOS GCC always uses the 'softfp' ABI.
+ if test x"$GCC" = xyes && test x$platform_darwin = xyes; then
+ fpu=VFP
fi
+ # Are we using the 'hard' ABI?
if test x$fpu = xNONE; then
- ORIG_CFLAGS=$CFLAGS
- CFLAGS="$CFLAGS -mfpu=vfp -mfloat-abi=softfp"
- AC_TRY_RUN([
- int main () { __asm__ ("faddd d7, d6, d7"); return 0; }
- ], fpu=VFP, fpu=NONE)
- CFLAGS=$ORIG_CFLAGS
+ AC_TRY_COMPILE([], [
+ #ifndef __ARM_PCS_VFP
+ #error "Float ABI is not 'hard'"
+ #endif
+ return 0;
+ ], [
+ fpu=VFP_HARD
+ ], [
+ fpu=NONE
+ ])
fi
+ # No 'hard' ABI. 'soft' or 'softfp'?
if test x$fpu = xNONE; then
AC_TRY_COMPILE([], [
- __asm__ ("ldfd f0, [r0]");
- ], fpu=FPA, fpu=NONE)
+ #ifdef __SOFTFP__
+ #error "Float ABI is not 'softfp'"
+ #endif
+ return 0;
+ ], [
+ fpu=VFP
+ ], [
+ fpu=NONE
+ ])
fi
AC_MSG_RESULT($fpu)
CPPFLAGS="$CPPFLAGS -DARM_FPU_$fpu=1"
unset fpu
- AC_MSG_CHECKING(for ARMV6)
- AC_TRY_RUN([
- int main () { __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory"); return 0; }
- ], armv6=yes, armv6=no)
+ if test x$cross_compiling = xno; then
+ AC_MSG_CHECKING(for ARMV6)
+ AC_TRY_RUN([
+ int main () { __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory"); return 0; }
+ ], armv6=yes, armv6=no)
- AC_MSG_RESULT($armv6)
- if test ${armv6} = yes; then
- AC_DEFINE(HAVE_ARMV6, 1, "Host supports ARMV6 instructions")
- # libgc's gc_locks.h depends on this
- NESTED_LIBGC_FLAGS="$NESTED_LIBGC_FLAGS -DHAVE_ARMV6"
+ AC_MSG_RESULT($armv6)
+ if test ${armv6} = yes; then
+ AC_DEFINE(HAVE_ARMV6, 1, "Host supports ARMV6 instructions")
+ # libgc's gc_locks.h depends on this
+ NESTED_LIBGC_FLAGS="$NESTED_LIBGC_FLAGS -DHAVE_ARMV6"
+ fi
fi
fi
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
AM_CONDITIONAL(POWERPC64, test x$TARGET = xPOWERPC64)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
-AM_CONDITIONAL(S390, test x$TARGET = xS390)
AM_CONDITIONAL(S390x, test x$TARGET = xS390x)
AM_CONDITIONAL(HOST_X86, test x$HOST = xX86)
AM_CONDITIONAL(HOST_AMD64, test x$HOST = xAMD64)
mono/arch/amd64/Makefile
mono/arch/ppc/Makefile
mono/arch/sparc/Makefile
-mono/arch/s390/Makefile
mono/arch/s390x/Makefile
mono/arch/arm/Makefile
mono/arch/ia64/Makefile
#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__ */
-
if (vasprintf (&msg, format, args) < 0)
return;
+#ifdef G_OS_WIN32
+ printf ("%s%s%s\n",
+ log_domain != NULL ? log_domain : "",
+ log_domain != NULL ? ": " : "",
+ msg);
+#else
#if MONOTOUCH
FILE *target = stderr;
#else
log_domain != NULL ? log_domain : "",
log_domain != NULL ? ": " : "",
msg);
+#endif
free (msg);
if (log_level & fatal){
fflush (stdout);
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)))
# define GC_CLEAR_DEFINED
# endif /* ALPHA */
# ifdef ARM32
+#ifdef __native_client__
+#define NACL_ALIGN() ".align 4\n"
+#define MASK_REGISTER(reg) "bic " reg ", " reg ", #0xc0000000\n"
+#else
+#define NACL_ALIGN()
+#define MASK_REGISTER(reg)
+#endif
inline static int GC_test_and_set(volatile unsigned int *addr) {
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7__)
int ret, tmp;
__asm__ __volatile__ (
"1:\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%3")
"ldrex %0, [%3]\n"
+ MASK_REGISTER("%3")
"strex %1, %2, [%3]\n"
"teq %1, #0\n"
"bne 1b\n"
* bus because there are no SMP ARM machines. If/when there are,
* this code will likely need to be updated. */
/* See linuxthreads/sysdeps/arm/pt-machine.h in glibc-2.1 */
- __asm__ __volatile__("swp %0, %1, [%2]"
+ __asm__ __volatile__(MASK_REGISTER("%2")
+ "swp %0, %1, [%2]"
: "=&r"(oldval)
: "r"(1), "r"(addr)
: "memory");
/* 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
-# if !defined(LINUX) && !defined(NETBSD) && !defined(DARWIN)
+# if defined(NACL)
+# define mach_type_known
+# elif !defined(LINUX) && !defined(NETBSD) && !defined(DARWIN)
# define NOSYS
# define mach_type_known
# endif
# 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 */
# endif
# ifdef ARM32
-# define CPP_WORDSZ 32
+# if defined( NACL )
+# define MACH_TYPE "NACL"
+# else
# define MACH_TYPE "ARM32"
+# endif
+# define CPP_WORDSZ 32
# define ALIGNMENT 4
# ifdef NETBSD
# define OS_TYPE "NETBSD"
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
__asm__ __volatile__ ("add $16, %esp");\
} while (0)
+#elif __arm__
+
+#define NACL_STORE_REGS() \
+ do { \
+ __asm__ __volatile__ ("push {r4-r12,lr}");\
+ __asm__ __volatile__ ("mov r0, %0" : : "r" (&nacl_gc_thread_self->stop_info.stack_ptr)); \
+ __asm__ __volatile__ ("bic r0, r0, #0xc0000000");\
+ __asm__ __volatile__ ("str sp, [r0]");\
+ memcpy(nacl_gc_thread_self->stop_info.reg_storage, nacl_gc_thread_self->stop_info.stack_ptr, NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\
+ __asm__ __volatile__ ("add sp, sp, #40");\
+ __asm__ __volatile__ ("bic sp, sp, #0xc0000000");\
+ } while (0)
+#else
+
+#error "Please port NACL_STORE_REGS"
+
#endif
void nacl_pre_syscall_hook()
}
}
+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
Mono.Data.Sqlite \
System.Numerics \
System.Data.Services.Client \
- System.Reactive.Interfaces \
- System.Reactive.Core \
- System.Reactive.Linq \
- System.Reactive.PlatformServices \
- System.Reactive.Experimental \
- System.Reactive.Debugger \
- System.Net.Http \
System.IO.Compression \
System.IO.Compression.FileSystem \
System.ComponentModel.DataAnnotations \
Mono.CompilerServices.SymbolWriter \
Mono.CSharp \
Microsoft.CSharp \
- System.Reactive.Providers
+ System.Net.Http
monotouch_runtime_dirs := \
corlib \
System.Web \
Mono.Web \
System.Web.Services \
- System.Web \
- System.Net.Http
+ System.Web
net_3_5_only_dirs := \
Microsoft.Build.Framework \
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
+using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
//string recursiveDir;
IDictionary evaluatedMetadata;
IDictionary unevaluatedMetadata;
+ bool isDynamic;
+ bool keepDuplicates = true;
+ string removeMetadata, keepMetadata;
BuildItem ()
{
this.parent_item_group = parentItemGroup;
this.itemElement = itemElement;
-
- if (Include == String.Empty)
- throw new InvalidProjectFileException (String.Format ("The required attribute \"Include\" is missing from element <{0}>.", Name));
+ isDynamic = parentItemGroup.IsDynamic;
+
+ if (IsDynamic) {
+ if (!string.IsNullOrEmpty (Remove)) {
+ if (!string.IsNullOrEmpty (Include) || !string.IsNullOrEmpty (Exclude))
+ throw new InvalidProjectFileException (string.Format ("The attribute \"Remove\" in element <{0}> is unrecognized.", Name));
+ if (itemElement.HasChildNodes)
+ throw new InvalidProjectFileException ("Children are not allowed below an item remove element.");
+ }
+ if (string.IsNullOrEmpty (Include) && !string.IsNullOrEmpty (Exclude))
+ throw new InvalidProjectFileException (string.Format ("The attribute \"Exclude\" in element <{0}> is unrecognized.", Name));
+ } else {
+ if (string.IsNullOrEmpty (Include))
+ throw new InvalidProjectFileException (string.Format ("The required attribute \"Include\" is missing from element <{0}>.", Name));
+ if (!string.IsNullOrEmpty (Remove))
+ throw new InvalidProjectFileException (string.Format ("The attribute \"Remove\" in element <{0}> is unrecognized.", Name));
+ }
+
+ foreach (XmlAttribute attr in itemElement.Attributes) {
+ if (attr.Name == "Include" || attr.Name == "Exclude" || attr.Name == "Condition")
+ continue;
+ if (!IsDynamic)
+ throw new InvalidProjectFileException (string.Format ("The attribute \"{0}\" in element <{1}> is unrecognized.", attr.Name, Name));
+
+ switch (attr.Name) {
+ case "Remove":
+ Remove = attr.Value;
+ break;
+ case "KeepDuplicates":
+ KeepDuplicates = bool.Parse (attr.Value);
+ break;
+ case "RemoveMetadata":
+ removeMetadata = attr.Value;
+ break;
+ case "KeepMetadata":
+ keepMetadata = attr.Value;
+ break;
+ default:
+ throw new InvalidProjectFileException (string.Format ("The attribute \"{0}\" in element <{1}> is unrecognized.", attr.Name, Name));
+ }
+ }
}
-
+
BuildItem (BuildItem parent)
{
isImported = parent.isImported;
this.finalItemSpec = MSBuildUtils.Unescape (Include);
return;
}
-
+
foreach (XmlNode xn in itemElement.ChildNodes) {
XmlElement xe = xn as XmlElement;
if (xe != null && ConditionParser.ParseAndEvaluate (xe.GetAttribute ("Condition"), project))
AddMetadata (xe.Name, xe.InnerText);
}
+ if (IsDynamic) {
+ if (!evaluatedTo)
+ return;
+
+ if (!string.IsNullOrEmpty (Remove)) {
+ RemoveItems (project);
+ return;
+ }
+
+ if (string.IsNullOrEmpty (Include)) {
+ UpdateMetadata (project);
+ return;
+ }
+ }
+
DirectoryScanner directoryScanner;
Expression includeExpr, excludeExpr;
ITaskItem[] includes, excludes;
+ var options = IsDynamic ?
+ ParseOptions.AllowItemsMetadataAndSplit : ParseOptions.AllowItemsNoMetadataAndSplit;
+
includeExpr = new Expression ();
- includeExpr.Parse (Include, ParseOptions.AllowItemsNoMetadataAndSplit);
+ includeExpr.Parse (Include, options);
excludeExpr = new Expression ();
- excludeExpr.Parse (Exclude, ParseOptions.AllowItemsNoMetadataAndSplit);
+ excludeExpr.Parse (Exclude, options);
includes = (ITaskItem[]) includeExpr.ConvertTo (project, typeof (ITaskItem[]),
ExpressionOptions.ExpandItemRefs);
foreach (ITaskItem matchedItem in directoryScanner.MatchedItems)
AddEvaluatedItem (project, evaluatedTo, matchedItem);
}
-
+
+ bool CheckCondition (Project project)
+ {
+ if (parent_item_group != null && !ConditionParser.ParseAndEvaluate (parent_item_group.Condition, project))
+ return false;
+ if (parent_item != null && !parent_item.CheckCondition (project))
+ return false;
+ return ConditionParser.ParseAndEvaluate (Condition, project);
+ }
+
+ void UpdateMetadata (Project project)
+ {
+ BuildItemGroup group;
+ if (!project.TryGetEvaluatedItemByNameBatched (Name, out group))
+ return;
+
+ foreach (BuildItem item in group) {
+ if (!item.CheckCondition (project))
+ continue;
+
+ foreach (string name in evaluatedMetadata.Keys) {
+ item.SetMetadata (name, (string)evaluatedMetadata [name]);
+ }
+
+ AddAndRemoveMetadata (project, item);
+ }
+ }
+
+ void AddAndRemoveMetadata (Project project, BuildItem item)
+ {
+ if (!string.IsNullOrEmpty (removeMetadata)) {
+ var removeExpr = new Expression ();
+ removeExpr.Parse (removeMetadata, ParseOptions.AllowItemsNoMetadataAndSplit);
+
+ var removeSpec = (string[]) removeExpr.ConvertTo (
+ project, typeof (string[]), ExpressionOptions.ExpandItemRefs);
+
+ foreach (var remove in removeSpec) {
+ item.DeleteMetadata (remove);
+ }
+ }
+
+ if (!string.IsNullOrEmpty (keepMetadata)) {
+ var keepExpr = new Expression ();
+ keepExpr.Parse (keepMetadata, ParseOptions.AllowItemsNoMetadataAndSplit);
+
+ var keepSpec = (string[]) keepExpr.ConvertTo (
+ project, typeof (string[]), ExpressionOptions.ExpandItemRefs);
+
+ var metadataNames = new string [item.evaluatedMetadata.Count];
+ item.evaluatedMetadata.Keys.CopyTo (metadataNames, 0);
+
+ foreach (string name in metadataNames) {
+ if (!keepSpec.Contains (name))
+ item.DeleteMetadata (name);
+ }
+ }
+ }
+
+ void RemoveItems (Project project)
+ {
+ BuildItemGroup group;
+ if (!project.TryGetEvaluatedItemByNameBatched (Name, out group))
+ return;
+
+ var removeExpr = new Expression ();
+ removeExpr.Parse (Remove, ParseOptions.AllowItemsNoMetadataAndSplit);
+
+ var removes = (ITaskItem[]) removeExpr.ConvertTo (
+ project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs);
+
+ var directoryScanner = new DirectoryScanner ();
+
+ directoryScanner.Includes = removes;
+
+ if (project.FullFileName != String.Empty)
+ directoryScanner.BaseDirectory = new DirectoryInfo (Path.GetDirectoryName (project.FullFileName));
+ else
+ directoryScanner.BaseDirectory = new DirectoryInfo (Directory.GetCurrentDirectory ());
+
+ directoryScanner.Scan ();
+
+ foreach (ITaskItem matchedItem in directoryScanner.MatchedItems) {
+ group.RemoveItem (matchedItem);
+ }
+ }
+
+ bool ContainsItem (Project project, ITaskItem taskItem)
+ {
+ BuildItemGroup group;
+ if (!project.TryGetEvaluatedItemByNameBatched (Name, out group))
+ return false;
+
+ var item = group.FindItem (taskItem);
+ if (item == null)
+ return false;
+
+ foreach (string metadataName in evaluatedMetadata.Keys) {
+ string metadataValue = (string)evaluatedMetadata [metadataName];
+ if (!metadataValue.Equals (item.evaluatedMetadata [metadataName]))
+ return false;
+ }
+
+ foreach (string metadataName in item.evaluatedMetadata.Keys) {
+ string metadataValue = (string)item.evaluatedMetadata [metadataName];
+ if (!metadataValue.Equals (evaluatedMetadata [metadataName]))
+ return false;
+ }
+
+ return true;
+ }
+
void AddEvaluatedItem (Project project, bool evaluatedTo, ITaskItem taskitem)
{
+ if (IsDynamic && evaluatedTo && !KeepDuplicates && ContainsItem (project, taskitem))
+ return;
+
BuildItemGroup big;
BuildItem bi = new BuildItem (this);
bi.finalItemSpec = taskitem.ItemSpec;
}
big.AddItem (bi);
+
+ if (IsDynamic)
+ AddAndRemoveMetadata (project, bi);
}
// during item's eval phase, any item refs in this item, have either
}
}
+ internal bool IsDynamic {
+ get { return isDynamic; }
+ }
+
+ internal string Remove {
+ get;
+ private set;
+ }
+
+ internal bool KeepDuplicates {
+ get { return keepDuplicates; }
+ private set { keepDuplicates = value; }
+ }
+
public bool IsImported {
get { return isImported; }
}
internal bool FromXml {
get { return itemElement != null; }
}
+
+ internal XmlElement XmlElement {
+ get { return itemElement; }
+ }
internal bool HasParentItem {
get { return parent_item != null; }
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
+using System.Linq;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
GroupingCollection parentCollection;
Project parentProject;
bool read_only;
- bool evaluated;
+ bool evaluated;
+ bool isDynamic;
public BuildItemGroup ()
: this (null, null, null, false)
}
internal BuildItemGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
+ : this (xmlElement, project, importedProject, readOnly, false)
+ {
+ }
+
+ internal BuildItemGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly, bool dynamic)
{
this.buildItems = new List <BuildItem> ();
this.importedProject = importedProject;
this.itemGroupElement = xmlElement;
this.parentProject = project;
this.read_only = readOnly;
+ this.isDynamic = dynamic;
if (!FromXml)
return;
RemoveItem (item);
}
+ internal BuildItem FindItem (ITaskItem taskItem)
+ {
+ return buildItems.FirstOrDefault (i => i.FinalItemSpec == taskItem.ItemSpec);
+ }
+
+ internal void RemoveItem (ITaskItem itemToRemove)
+ {
+ if (itemToRemove == null)
+ return;
+
+ var item = FindItem (itemToRemove);
+ if (item == null)
+ return;
+
+ item.Detach ();
+ buildItems.Remove (item);
+ }
+
public BuildItem[] ToArray ()
{
return buildItems.ToArray ();
internal void Evaluate ()
{
- if (evaluated)
+ if (!isDynamic && evaluated)
return;
foreach (BuildItem bi in buildItems) {
if (bi.Condition == String.Empty)
return itemGroupElement;
}
}
+
+ internal bool IsDynamic {
+ get {
+ return isDynamic;
+ }
+ }
}
}
using Microsoft.Build.Utilities;
namespace Microsoft.Build.BuildEngine {
- public class BuildTask {
+ public class BuildTask : IBuildTask {
ITaskHost hostObject;
Target parentTarget;
continue;
tempNames.Add (xmlAttribute.Name);
}
-
+
return tempNames.ToArray ();
}
else
taskElement.SetAttribute (parameterName, parameterValue);
}
-
+
void LogTaskStarted ()
{
TaskStartedEventArgs tsea = new TaskStartedEventArgs ("Task started.", null,
get { return taskElement; }
set { taskElement = value; }
}
-
+
[MonoTODO]
public Type Type {
get { return parentTarget.Project.TaskDatabase.GetTypeFromClassName (Name); }
}
+
+ public IEnumerable<string> GetAttributes ()
+ {
+ foreach (XmlAttribute attrib in TaskElement.Attributes)
+ yield return attrib.Value;
+ foreach (XmlNode xn in TaskElement.ChildNodes) {
+ XmlElement xe = xn as XmlElement;
+ if (xe == null)
+ continue;
+
+ //FIXME: error on any other child
+ if (String.Compare (xe.LocalName, "Output", StringComparison.Ordinal) == 0) {
+ foreach (XmlAttribute attrib in xe.Attributes)
+ yield return attrib.Value;
+ }
+ }
+ }
+
}
}
--- /dev/null
+//
+// BuildTaskItemGroup.cs
+//
+// Author:
+// Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace Microsoft.Build.BuildEngine {
+
+ internal class BuildTaskItemGroup : BuildItemGroup, IBuildTask {
+
+ public bool ContinueOnError {
+ get; set;
+ }
+
+ internal BuildTaskItemGroup (XmlElement element, Target target)
+ : base (element, target.Project, null, false, true)
+ {
+ }
+
+ public bool Execute ()
+ {
+ Evaluate ();
+ return true;
+ }
+
+ public IEnumerable<string> GetAttributes ()
+ {
+ foreach (XmlAttribute attrib in XmlElement.Attributes)
+ yield return attrib.Value;
+
+ foreach (BuildItem item in this) {
+ foreach (XmlAttribute attrib in item.XmlElement.Attributes)
+ yield return attrib.Value;
+ }
+ }
+
+ }
+}
+
--- /dev/null
+//
+// BuildTaskPropertyGroup.cs
+//
+// Author:
+// Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace Microsoft.Build.BuildEngine {
+
+ internal class BuildTaskPropertyGroup : BuildPropertyGroup, IBuildTask {
+
+ public bool ContinueOnError {
+ get; set;
+ }
+
+ internal BuildTaskPropertyGroup (XmlElement element, Target target)
+ : base (element, target.Project, null, false)
+ {
+ }
+
+ public bool Execute ()
+ {
+ Evaluate ();
+ return true;
+ }
+
+ public IEnumerable<string> GetAttributes ()
+ {
+ foreach (XmlAttribute attrib in XmlElement.Attributes)
+ yield return attrib.Value;
+ }
+
+ }
+}
+
{
return ParseBooleanAnd ();
}
+
+ public static string And (string a, string b)
+ {
+ return a + " and " + b;
+ }
ConditionExpression ParseBooleanAnd ()
{
--- /dev/null
+//
+// IBuildTask.cs
+//
+// Author:
+// Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.Build.BuildEngine {
+ internal interface IBuildTask {
+ bool ContinueOnError {
+ get; set;
+ }
+
+ string Condition {
+ get; set;
+ }
+
+ bool Execute ();
+
+ IEnumerable<string> GetAttributes ();
+ }
+}
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
+using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
+using Mono.XBuild.Utilities;
namespace Microsoft.Build.BuildEngine {
public class Target : IEnumerable {
Project project;
XmlElement targetElement;
List <XmlElement> onErrorElements;
- List <BuildTask> buildTasks;
+ List <IBuildTask> buildTasks;
internal Target (XmlElement targetElement, Project project, ImportedProject importedProject)
{
this.onErrorElements = new List <XmlElement> ();
this.buildState = BuildState.NotStarted;
- this.buildTasks = new List <BuildTask> ();
+ this.buildTasks = new List <IBuildTask> ();
this.batchingImpl = new TargetBatchingImpl (project, this.targetElement);
bool onErrorFound = false;
"The element <OnError> must be last under element <Target>. Found element <Error> instead.");
#if NET_3_5
else if (xe.Name == "ItemGroup") {
- //don't blow up for ItemGroups inside Targets in >= 3.5
- // TODO: evaluate them (see https://bugzilla.xamarin.com/show_bug.cgi?id=1862 and test in TargetTest.cs )
+ buildTasks.Add (new BuildTaskItemGroup (xe, this));
+ continue;
+ } else if (xe.Name == "PropertyGroup") {
+ buildTasks.Add (new BuildTaskPropertyGroup (xe, this));
continue;
}
#endif
internal List<string> AfterThisTargets { get; set; }
#endif
- internal List<BuildTask> BuildTasks {
+ internal List<IBuildTask> BuildTasks {
get { return buildTasks; }
}
for (int i = 0; i < target.BuildTasks.Count; i ++) {
//FIXME: parsing attributes repeatedly
- BuildTask bt = target.BuildTasks [i];
+ IBuildTask bt = target.BuildTasks [i];
TaskBatchingImpl batchingImpl = new TaskBatchingImpl (project);
bool task_result = batchingImpl.Build (bt, out executeOnErrors);
{
}
- public bool Build (BuildTask buildTask, out bool executeOnErrors)
+ public bool Build (IBuildTask buildTask, out bool executeOnErrors)
{
executeOnErrors = false;
try {
}
}
- bool Run (BuildTask buildTask, out bool executeOnErrors)
+ bool Run (IBuildTask buildTask, out bool executeOnErrors)
{
executeOnErrors = false;
// Parse task attributes to get list of referenced metadata and items
// to determine batching
//
- void ParseTaskAttributes (BuildTask buildTask)
+ void ParseTaskAttributes (IBuildTask buildTask)
{
- foreach (XmlAttribute attrib in buildTask.TaskElement.Attributes)
- ParseAttribute (attrib.Value);
-
- foreach (XmlNode xn in buildTask.TaskElement.ChildNodes) {
- XmlElement xe = xn as XmlElement;
- if (xe == null)
- continue;
-
- //FIXME: error on any other child
- if (String.Compare (xe.LocalName, "Output", StringComparison.Ordinal) == 0) {
- foreach (XmlAttribute attrib in xe.Attributes)
- ParseAttribute (attrib.Value);
- }
+ foreach (var attr in buildTask.GetAttributes ()) {
+ ParseAttribute (attr);
}
}
}
Microsoft.Build.BuildEngine/BuildPropertyGroup.cs
Microsoft.Build.BuildEngine/BuildSettings.cs
Microsoft.Build.BuildEngine/BuildTask.cs
+Microsoft.Build.BuildEngine/BuildTaskItemGroup.cs
+Microsoft.Build.BuildEngine/BuildTaskPropertyGroup.cs
Microsoft.Build.BuildEngine/BuildWhen.cs
Microsoft.Build.BuildEngine/ChangeType.cs
Microsoft.Build.BuildEngine/ColorResetter.cs
Microsoft.Build.BuildEngine/ImportedProject.cs
Microsoft.Build.BuildEngine/InternalLoggerException.cs
Microsoft.Build.BuildEngine/InvalidProjectFileException.cs
+Microsoft.Build.BuildEngine/IBuildTask.cs
Microsoft.Build.BuildEngine/IReference.cs
Microsoft.Build.BuildEngine/ItemReference.cs
Microsoft.Build.BuildEngine/LogExtensions.cs
// Parameter "itemInclude" cannot have zero length.
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (ArgumentException))]
public void TestCtor6 ()
{
}
[Test]
+ [Category ("NotDotNet")]
public void TestGetEnumerator1 ()
{
BuildPropertyGroup bpg = new BuildPropertyGroup ();
}
[Test]
+ [Category ("NotDotNet")]
public void TestValueXml ()
{
BuildPropertyGroup [] bpgs = new BuildPropertyGroup [1];
[TestFixture]
public class ConsoleLoggerTest {
[Test]
+ [Category ("NotDotNet")]
public void TestAssignment ()
{
ConsoleLogger cl = new ConsoleLogger ();
}
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (ArgumentException))]
public void TestBuildProject1 ()
{
}
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (ArgumentException))]
public void TestBuildProjectNull1 ()
{
}
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (ArgumentException))]
public void TestBuildProjectNull2 ()
{
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef1 ()
{
//test for multiple items with same metadata also
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef2 ()
{
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef3 ()
{
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef4 ()
{
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef5 ()
{
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRefInOutput () {
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
}
[Test]
+ [Category ("NotDotNet")]
public void TestMSBuildThisProperties ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray1 ()
{
Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItems", "@(NonExistant)",
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray2 ()
{
Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItems", "$(NonExistant)",
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray3 ()
{
Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "$(NonExistant)",
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray4 () {
Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "%(NonExistant.Md)",
true, "Build failed", "count: 0");
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray5 () {
// with extra space in prop value
Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", " %(NonExistant.Md)",
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
using System;
using System.Collections;
using Microsoft.Build.BuildEngine;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
+using MonoTests.Microsoft.Build.Tasks;
using NUnit.Framework;
using System.IO;
+using System.Xml;
namespace MonoTests.Microsoft.Build.BuildEngine {
[TestFixture]
}
#if NET_3_5
- [Test]
- public void BuildProjectWithItemGroupInsideTarget()
+ bool Build (string projectXml, ILogger logger)
{
- ItemGroupInsideATarget ();
+ if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
+ var reader = new StringReader (projectXml);
+ var xml = XmlReader.Create (reader);
+ return BuildOnWindows (xml, logger);
+ } else {
+ return BuildOnLinux (projectXml, logger);
+ }
}
- private MonoTests.Microsoft.Build.Tasks.TestMessageLogger ItemGroupInsideATarget() {
- var engine = new Engine(Consts.BinPath);
- var project = engine.CreateNewProject();
- var projectXml = GetProjectXmlWithItemGroupInsideATarget ();
- project.LoadXml(projectXml);
+ bool BuildOnWindows (XmlReader reader, ILogger logger)
+ {
+ var type = Type.GetType ("Microsoft.Build.Evaluation.ProjectCollection, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+
+ var prop = type.GetProperty ("GlobalProjectCollection");
+ var coll = prop.GetValue (null);
+
+ var loadProject = coll.GetType ().GetMethod (
+ "LoadProject", new Type[] { typeof (XmlReader), typeof (string) });
+ var proj = loadProject.Invoke (coll, new object[] { reader, "4.0" });
+
+ var build = proj.GetType ().GetMethod ("Build", new Type[] { typeof (string), typeof (ILogger[]) });
+ var ret = (bool)build.Invoke (proj, new object[] { "Main", new ILogger[] { logger }});
+ return ret;
+ }
- MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
- new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ bool BuildOnLinux (string projectXml, ILogger logger)
+ {
+ var engine = new Engine (Consts.BinPath);
+ var project = engine.CreateNewProject ();
+ project.LoadXml (projectXml);
+
engine.RegisterLogger (logger);
+
+ return project.Build ("Main");
+ }
- bool result = project.Build("Main");
- if (!result)
- {
+ TestMessageLogger CreateLogger (string projectXml)
+ {
+ var logger = new TestMessageLogger ();
+ var result = Build (projectXml, logger);
+
+ if (!result) {
logger.DumpMessages ();
- Assert.Fail("Build failed");
+ Assert.Fail ("Build failed");
}
return logger;
}
- private string GetProjectXmlWithItemGroupInsideATarget ()
+ void ItemGroupInsideTarget (string xml, params string[] messages)
+ {
+ var logger = CreateLogger (xml);
+
+ try
+ {
+ Assert.AreEqual(messages.Length, logger.NormalMessageCount, "Expected number of messages");
+ for (int i = 0; i < messages.Length; i++)
+ logger.CheckLoggedMessageHead (messages [i], i.ToString ());
+ Assert.AreEqual(0, logger.NormalMessageCount, "Extra messages found");
+
+ Assert.AreEqual(1, logger.TargetStarted, "TargetStarted count");
+ Assert.AreEqual(1, logger.TargetFinished, "TargetFinished count");
+ Assert.AreEqual(messages.Length, logger.TaskStarted, "TaskStarted count");
+ Assert.AreEqual(messages.Length, logger.TaskFinished, "TaskFinished count");
+ }
+ catch (AssertionException)
+ {
+ logger.DumpMessages();
+ throw;
+ }
+ }
+
+ [Test]
+ public void BuildProjectWithItemGroupInsideTarget ()
{
- return
+ ItemGroupInsideTarget (
@"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<ItemGroup>
- <fruit Include=""apple""/>
+ <fruit Include=""apple""/>
<fruit Include=""apricot""/>
</ItemGroup>
</ItemGroup>
<Message Text=""%(fruit.Identity)""/>
</Target>
- </Project>";
+ </Project>", "apple", "apricot", "raspberry");
}
+
+ [Test]
+ public void BuildProjectWithItemGroupInsideTarget2 ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""4.0"">
+ <ItemGroup>
+ <A Include='1'>
+ <Sub>Foo</Sub>
+ </A>
+ </ItemGroup>
+ <PropertyGroup>
+ <Foo>Bar</Foo>
+ </PropertyGroup>
+ <Target Name='Main'>
+ <ItemGroup>
+ <A Include='2'>
+ <Sub>$(Foo);Hello</Sub>
+ </A>
+ </ItemGroup>
+
+ <Message Text='@(A)' />
+ <Message Text='%(A.Sub)' />
+ </Target>
+ </Project>", "1;2", "Foo", "Bar;Hello");
+ }
+
[Test]
- [Category ("NotWorking")] //https://bugzilla.xamarin.com/show_bug.cgi?id=1862
- public void BuildProjectOutputWithItemGroupInsideTarget()
+ public void BuildProjectWithPropertyGroupInsideTarget ()
{
- var logger = ItemGroupInsideATarget ();
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <PropertyGroup>
+ <A>Foo</A>
+ <B>Bar</B>
+ </PropertyGroup>
- try
- {
- Assert.AreEqual(3, logger.NormalMessageCount, "Expected number of messages");
- logger.CheckLoggedMessageHead("apple", "A1");
- logger.CheckLoggedMessageHead("apricot", "A2");
- logger.CheckLoggedMessageHead("raspberry", "A3");
- Assert.AreEqual(0, logger.NormalMessageCount, "Extra messages found");
+ <Target Name=""Main"">
+ <Message Text='$(A)' />
+ <PropertyGroup>
+ <A>$(B)</A>
+ </PropertyGroup>
+ <Message Text='$(A)' />
+ </Target>
+ </Project>", "Foo", "Bar");
+ }
- Assert.AreEqual(1, logger.TargetStarted, "TargetStarted count");
- Assert.AreEqual(1, logger.TargetFinished, "TargetFinished count");
- Assert.AreEqual(3, logger.TaskStarted, "TaskStarted count");
- Assert.AreEqual(3, logger.TaskFinished, "TaskFinished count");
+ [Test]
+ public void BuildProjectWithPropertyGroupInsideTarget2 ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <PropertyGroup>
+ <A>Foo</A>
+ <B>Bar</B>
+ </PropertyGroup>
- }
- catch (AssertionException)
- {
- logger.DumpMessages();
- throw;
- }
+ <Target Name=""Main"">
+ <Message Text='$(A)' />
+ <PropertyGroup Condition='true'>
+ <B Condition='false'>False</B>
+ </PropertyGroup>
+ <PropertyGroup Condition='true'>
+ <A>$(B)</A>
+ </PropertyGroup>
+ <Message Text='$(A)' />
+ <Message Text='$(B)' />
+ <PropertyGroup>
+ <A Condition='$(A) == $(B)'>Equal</A>
+ </PropertyGroup>
+ <Message Text='$(A)' />
+ </Target>
+ </Project>", "Foo", "Bar", "Bar", "Equal");
}
+
+ [Test]
+ public void ItemGroupInsideTarget_ModifyMetadata ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Server Include='Server1'>
+ <AdminContact>Mono</AdminContact>
+ </Server>
+ <Server Include='Server2'>
+ <AdminContact>Mono</AdminContact>
+ </Server>
+ <Server Include='Server3'>
+ <AdminContact>Root</AdminContact>
+ </Server>
+ </ItemGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Server Condition=""'%(Server.AdminContact)' == 'Mono'"">
+ <AdminContact>Monkey</AdminContact>
+ </Server>
+ </ItemGroup>
+
+ <Message Text='%(Server.Identity) : %(Server.AdminContact)' />
+ </Target>
+ </Project>", "Server1 : Monkey", "Server2 : Monkey", "Server3 : Root");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_RemoveItem ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A;B;C;D' />
+ </ItemGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Foo Remove='B' />
+ </ItemGroup>
+
+ <Message Text='@(Foo)' />
+ </Target>
+ </Project>", "A;C;D");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_DontKeepDuplicates ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A;B' />
+ <Foo Include='C'>
+ <Hello>World</Hello>
+ </Foo>
+ <Foo Include='D'>
+ <Hello>Boston</Hello>
+ </Foo>
+ </ItemGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Foo Include='B;C;D' KeepDuplicates='false'>
+ <Hello>Boston</Hello>
+ </Foo>
+ </ItemGroup>
+
+ <Message Text='@(Foo)' />
+ </Target>
+ </Project>", "A;B;C;D;B;C");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_RemoveMetadata ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A' />
+ <Foo Include='B'>
+ <Hello>World</Hello>
+ </Foo>
+ <Foo Include='C'>
+ <Hello>Boston</Hello>
+ </Foo>
+ <Foo Include='D'>
+ <Test>Monkey</Test>
+ </Foo>
+ </ItemGroup>
+ <PropertyGroup>
+ <Foo>Hello</Foo>
+ </PropertyGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Bar Include='@(Foo)' RemoveMetadata='$(Foo)' />
+ <Bar Include='E'>
+ <Hello>Monkey</Hello>
+ </Bar>
+ </ItemGroup>
+
+ <Message Text='%(Bar.Identity)' Condition=""'%(Bar.Hello)' != ''""/>
+ </Target>
+ </Project>", "E");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_RemoveMetadata2 ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A' />
+ <Foo Include='B'>
+ <Hello>World</Hello>
+ </Foo>
+ <Foo Include='C'>
+ <Hello>Boston</Hello>
+ </Foo>
+ <Foo Include='D'>
+ <Test>Monkey</Test>
+ </Foo>
+ </ItemGroup>
+ <PropertyGroup>
+ <Foo>Hello</Foo>
+ </PropertyGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Foo RemoveMetadata='$(Foo)' />
+ <Foo Include='E'>
+ <Hello>Monkey</Hello>
+ </Foo>
+ </ItemGroup>
+
+ <Message Text='%(Foo.Identity)' Condition=""'%(Foo.Hello)' != ''""/>
+ </Target>
+ </Project>", "E");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_KeepMetadata ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A' />
+ <Foo Include='B'>
+ <Hello>World</Hello>
+ </Foo>
+ <Foo Include='C'>
+ <Hello>Boston</Hello>
+ </Foo>
+ <Foo Include='D'>
+ <Test>Monkey</Test>
+ </Foo>
+ </ItemGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Foo KeepMetadata='Test' />
+ <Foo Include='E'>
+ <Hello>Monkey</Hello>
+ </Foo>
+ </ItemGroup>
+
+ <Message Text='%(Foo.Identity)' Condition=""'%(Foo.Test)' != ''""/>
+ </Target>
+ </Project>", "D");
+ }
+
#endif
[Test]
#if NET_4_0
[Test]
+ [Category ("NotDotNet")]
public void TestBeforeAndAfterTargets ()
{
Engine engine;
}
[Test]
+ [Category ("NotDotNet")]
public void TestDuplicate1 ()
{
string documentString = @"
}
[Test]
+ [Category ("NotDotNet")]
public void TestLazyLoad2 ()
{
string documentString = @"
}
[Test]
+ [Category ("NotDotNet")]
public void TestCondition10 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestImportOrder1 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (InvalidProjectFileException))]
public void TestImportOrder2 ()
{
}
[Test]
+ [Category ("NotDotNet")]
public void TestImportOrder5 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestImportOrder6 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestImportOrder7 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestEmptyItemsWithBatching ()
{
string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestItemsInTarget1 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestItemsInTarget3 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
//Test with ITaskItem[]
public void TestItemsInTarget3a ()
{
}
[Test]
+ [Category ("NotDotNet")]
//Test with string[]
public void TestItemsInTarget3b ()
{
}
[Test]
+ [Category ("NotDotNet")]
//Test with string
public void TestItemsInTarget3c ()
{
}
[Test]
+ [Category ("NotDotNet")]
public void TestSingleTaskItem1 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(D)$(C)");
}
[Test]
+ [Category ("NotDotNet")]
public void TestSingleTaskItem2 ()
{
Project proj = BuildProjectForSingleTaskItem ("@(Item1)");
}
[Test]
+ [Category ("NotDotNet")]
public void TestSingleTaskItem3 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(A).foo");
}
[Test]
+ [Category ("NotDotNet")]
public void TestSingleTaskItem4 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(C)");
}
[Test]
+ [Category ("NotDotNet")]
public void TestProperties2 ()
{
Engine engine = new Engine (Consts.BinPath);
val = CreateArg (vm, arg.value);
- if (arg.is_property) {
- foreach (var prop in ctor.DeclaringType.GetProperties ()) {
- if (prop.Id == arg.id)
- named_args [j] = new CustomAttributeNamedArgumentMirror (prop, null, val);
- }
- } else {
- foreach (var field in ctor.DeclaringType.GetFields ()) {
- if (field.Id == arg.id)
- named_args [j] = new CustomAttributeNamedArgumentMirror (null, field, val);
+ TypeMirror t = ctor.DeclaringType;
+ while (named_args [j] == null && t != null) {
+ if (arg.is_property) {
+ foreach (var prop in t.GetProperties ()) {
+ if (prop.Id == arg.id)
+ named_args [j] = new CustomAttributeNamedArgumentMirror (prop, null, val);
+ }
+ } else {
+ foreach (var field in t.GetFields ()) {
+ if (field.Id == arg.id)
+ named_args [j] = new CustomAttributeNamedArgumentMirror (null, field, val);
+ }
}
+ t = t.BaseType;
}
if (named_args [j] == null)
throw new NotImplementedException ();
}
}
- internal class CommandException : Exception {
+ public class CommandException : Exception {
- public CommandException (ErrorCode error_code) : base ("Debuggee returned error code " + error_code + ".") {
+ internal CommandException (ErrorCode error_code) : base ("Debuggee returned error code " + error_code + ".") {
ErrorCode = error_code;
}
}
}
+public class AAttribute : Attribute {
+ public int afield;
+}
+
+public class BAttribute : AAttribute {
+ public int bfield;
+}
+
[DebuggerDisplay ("Tests", Name="FOO", Target=typeof (int))]
[DebuggerTypeProxy (typeof (Tests))]
+[BAttribute (afield = 1, bfield = 2)]
public class Tests2 {
[DebuggerBrowsableAttribute (DebuggerBrowsableState.Collapsed)]
public int field_j;
t = frame.Method.GetParameters ()[8].ParameterType;
Assert.AreEqual ("Tests2", t.Name);
var attrs = t.GetCustomAttributes (true);
- Assert.AreEqual (2, attrs.Length);
+ Assert.AreEqual (3, attrs.Length);
foreach (var attr in attrs) {
if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
Assert.AreEqual (1, attr.ConstructorArguments.Count);
Assert.AreEqual (1, attr.ConstructorArguments.Count);
Assert.IsInstanceOfType (typeof (TypeMirror), attr.ConstructorArguments [0].Value);
Assert.AreEqual ("Tests", (attr.ConstructorArguments [0].Value as TypeMirror).Name);
+ } else if (attr.Constructor.DeclaringType.Name == "BAttribute") {
+ Assert.AreEqual (2, attr.NamedArguments.Count);
+ Assert.AreEqual ("afield", attr.NamedArguments [0].Field.Name);
+ Assert.AreEqual ("bfield", attr.NamedArguments [1].Field.Name);
} else {
Assert.Fail (attr.Constructor.DeclaringType.Name);
}
run_until ("objrefs2");
// child should be gc'd now
- Assert.IsTrue (child.IsCollected);
+ // This is not deterministic
+ //Assert.IsTrue (child.IsCollected);
/*
* No longer works since Type is read eagerly
TypeMirror t = child.Type;
});
*/
-
+ /*
AssertThrows<ObjectCollectedException> (delegate () {
long addr = child.Address;
});
+ */
}
[Test]
internal static extern int OCICharSetToUnicode (
IntPtr svchp,
[MarshalAs (UnmanagedType.LPWStr)] StringBuilder dst,
- [MarshalAs (UnmanagedType.U4)] int dstlen,
+ [MarshalAs (UnmanagedType.SysUInt)] int dstlen,
byte [] src,
- [MarshalAs (UnmanagedType.U4)] int srclen,
- [MarshalAs (UnmanagedType.U4)] out int rsize);
+ [MarshalAs (UnmanagedType.SysUInt)] int srclen,
+ [MarshalAs (UnmanagedType.SysUInt)] out int rsize);
[DllImport ("oci")]
internal static extern int OCIUnicodeToCharSet (
IntPtr svchp,
byte [] dst,
- [MarshalAs (UnmanagedType.U4)] int dstlen,
+ [MarshalAs (UnmanagedType.SysUInt)] int dstlen,
[MarshalAs (UnmanagedType.LPWStr)] string src,
- [MarshalAs (UnmanagedType.U4)] int srclen,
- [MarshalAs (UnmanagedType.U4)] out int rsize);
+ [MarshalAs (UnmanagedType.SysUInt)] int srclen,
+ [MarshalAs (UnmanagedType.SysUInt)] out int rsize);
}
#endregion
IntPtr svchp,
byte [] dst,
[MarshalAs (UnmanagedType.LPWStr)] string src,
- [MarshalAs (UnmanagedType.U4)] out int rsize)
+ [MarshalAs (UnmanagedType.SysUInt)] out int rsize)
{
#if TRACE
Trace.WriteLineIf(traceOci, "OCIUnicodeToCharSet", "OCI");
private void SetOracleType (OracleType type, bool inferring)
{
+ Type valType;
FreeHandle ();
- Type valType = value.GetType ();
+
+ if (value == null)
+ valType = typeof(System.DBNull);
+ else
+ valType = value.GetType ();
+
string exception = String.Format ("No mapping exists from OracleType {0} to a known DbType.", type);
switch (type) {
case OracleType.BFile:
}
[Test]
+ [NUnit.Framework.Category ("MobileNotWorking")] // DefaultMemberAttribute is removed by the tuner, causing #3 to fail
public void ICTD_GetClassNameTest ()
{
ICustomTypeDescriptor ictd = (ICustomTypeDescriptor) builder;
PREBUILT = $(RESX_RESOURCES:=.prebuilt)
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
-r:System.Reactive.Linq.dll
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
-r:System.Reactive.Linq.dll
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
-r:System.Core.dll
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
PREBUILT = $(RESX_RESOURCES:=.prebuilt)
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
PREBUILT = $(RESX_RESOURCES:=.prebuilt)
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
NO_TASK_DELAY := $(filter 4.5 2.1, $(FRAMEWORK_VERSION))
PREBUILT = $(RESX_RESOURCES:=.prebuilt)
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
-r:System.Windows.Forms.dll
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
PREBUILT = $(RESX_RESOURCES:=.prebuilt)
ifeq (2.1, $(FRAMEWORK_VERSION))
-LIB_MCS_FLAGS += -d:NO_TASK_DELAY
+LIB_MCS_FLAGS += -d:NO_TASK_DELAY -d:HAS_AWAIT
endif
NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION))
ifdef NET_4_5
-LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC
+LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC -d:HAS_AWAIT
endif
TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
// First, check XmlSchemaProviderAttribute and try GetSchema() to see if it returns a schema in the expected format.
var xpa = type.GetCustomAttribute<XmlSchemaProviderAttribute> (true);
if (xpa != null) {
+ if (xpa.IsAny)
+ return XmlQualifiedName.Empty;
var mi = type.GetMethod (xpa.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (mi != null) {
try {
QName qname = GetSerializableQName (type);
- if (FindUserMap (qname, type) != null)
+ if (!QName.Empty.Equals (qname) && FindUserMap (qname, type) != null)
throw new InvalidOperationException (String.Format ("There is already a registered type for XML name {0}", qname));
XmlSerializableMap ret = new XmlSerializableMap (type, qname, this);
ser.WriteObject (sw, 1);
string expected = "<int xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">1</int>";
byte[] buf = sw.ToArray ();
- Assert.AreEqual (expected, Encoding.UTF8.GetString (buf, 0, buf.Length));
+ // Skip the utf8 bom
+ Assert.AreEqual (expected, Encoding.UTF8.GetString (buf, 3, buf.Length - 3));
}
[Test]
// http://www.myelin.co.nz
// (c) 2004-2011 Novell, Inc. (http://www.novell.com)
//
-
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
private bool useoverlappedIO;
private const int SOCKET_CLOSED = 10004;
+ private static readonly string timeout_exc_msg = "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond";
+
static void AddSockets (List<Socket> sockets, IList list, string name)
{
if (list != null) {
public int Receive (byte [] buffer)
{
- if (disposed && closed)
- throw new ObjectDisposedException (GetType ().ToString ());
-
- if (buffer == null)
- throw new ArgumentNullException ("buffer");
-
- SocketError error;
-
- int ret = Receive_nochecks (buffer, 0, buffer.Length, SocketFlags.None, out error);
-
- if (error != SocketError.Success)
- throw new SocketException ((int) error);
-
- return ret;
+ return Receive (buffer, SocketFlags.None);
}
public int Receive (byte [] buffer, SocketFlags flags)
if (error != SocketError.Success) {
if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
- throw new SocketException ((int) error, "Operation timed out.");
+ throw new SocketException ((int) error, timeout_exc_msg);
throw new SocketException ((int) error);
}
if (error != SocketError.Success) {
if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
- throw new SocketException ((int) error, "Operation timed out.");
+ throw new SocketException ((int) error, timeout_exc_msg);
throw new SocketException ((int) error);
}
if (error != SocketError.Success) {
if (error == SocketError.WouldBlock && blocking) // This might happen when ReceiveTimeout is set
- throw new SocketException ((int) error, "Operation timed out.");
+ throw new SocketException ((int) error, timeout_exc_msg);
throw new SocketException ((int) error);
}
connected = false;
else if (err == SocketError.WouldBlock && blocking) { // This might happen when ReceiveTimeout is set
if (throwOnError)
- throw new SocketException ((int) SocketError.TimedOut, "Operation timed out");
+ throw new SocketException ((int) SocketError.TimedOut, timeout_exc_msg);
error = (int) SocketError.TimedOut;
return 0;
}
#if SECURITY_DEP
+extern alias MonoSecurity;
+
using System.Collections;
using System.Text;
-using Mono.Security;
-using MX = Mono.Security.X509;
+using MonoSecurity::Mono.Security;
+using MX = MonoSecurity::Mono.Security.X509;
namespace System.Security.Cryptography.X509Certificates {
RawData = new byte [2] { 0x30, 0x00 };
DecodeRawData ();
} else {
- ASN1 dn = MX.X501.FromString (distinguishedName);
+ var dn = MX.X501.FromString (distinguishedName);
if ((flag & X500DistinguishedNameFlags.Reversed) != 0) {
ASN1 rdn = new ASN1 (0x30);
for (int i = dn.Count - 1; i >= 0; i--)
#if SECURITY_DEP
+extern alias MonoSecurity;
+
using System.Text;
-using Mono.Security;
+using MonoSecurity::Mono.Security;
namespace System.Security.Cryptography.X509Certificates {
string ski = GetSubjectKeyIdentifier (caCertificate);
// consider that the LocalMachine directories could not exists... and cannot be created by the user
- MX.X509Crl result = (LMCAStore.Store == null) ? null : CheckCrls (subject, ski, LMCAStore.Store.Crls);
+ var result = (LMCAStore.Store == null) ? null : CheckCrls (subject, ski, LMCAStore.Store.Crls);
if (result != null)
return result;
if (location == StoreLocation.CurrentUser) {
#if SECURITY_DEP
+extern alias MonoSecurity;
+
using System.Text;
-using Mono.Security;
+using MonoSecurity::Mono.Security;
namespace System.Security.Cryptography.X509Certificates {
#if SECURITY_DEP
+extern alias MonoSecurity;
+
using System.Text;
-using Mono.Security;
+using MonoSecurity::Mono.Security;
namespace System.Security.Cryptography.X509Certificates {
#if SECURITY_DEP
+extern alias MonoSecurity;
+
using System.Security.Permissions;
-using MX = Mono.Security.X509;
+using MX = MonoSecurity::Mono.Security.X509;
namespace System.Security.Cryptography.X509Certificates {
#if SECURITY_DEP
+extern alias MonoSecurity;
+
using System.Text;
-using Mono.Security;
-using Mono.Security.Cryptography;
+using MonoSecurity::Mono.Security;
+using MonoSecurity::Mono.Security.Cryptography;
namespace System.Security.Cryptography.X509Certificates {
#if SECURITY_DEP
+extern alias MonoSecurity;
+
using System.Security.Cryptography.X509Certificates;
using System.Text;
-using Mono.Security;
-using Mono.Security.Cryptography;
+using MonoSecurity::Mono.Security;
+using MonoSecurity::Mono.Security.Cryptography;
namespace System.Security.Cryptography {
threads[i].Start ();
}
foreach (var t in threads)
- Assert.IsTrue (t.Join (200));
+ Assert.IsTrue (t.Join (2000));
Assert.IsFalse (bag.IsEmpty);
Assert.AreEqual (threads.Length, bag.Count);
public class ComponentConverterTests
{
[Test]
+ [NUnit.Framework.Category ("MobileNotWorking")] // IComponent doesn't have the TypeConverter attribute
public void DataSetConversions ()
{
TypeConverter converter = TypeDescriptor.GetConverter (typeof (DataSet));
// Not technically a 2.0 only test, but I use lambdas, so I need gmcs
[Test]
+ [NUnit.Framework.Category ("MobileNotWorking")]
// This was for bug #459450
public void TestEventRaising ()
{
}
[Test]
+ [NUnit.Framework.Category ("MobileNotWorking")]
public void ProcessName_AfterExit ()
{
Process p = new Process ();
// Lawrence Pit (loz@cable.a2000.nl)
// Martin Willemoes Hansen (mwh@sysrq.dk)
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+// Andres G. Aragoneses (andres@7digital.com)
//
// (C) 2003 Martin Willemoes Hansen
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com
+// Copyright (c) 2013 7digital Media Ltd (http://www.7digital.com)
//
using NUnit.Framework;
}
}
+
+ #region Timeout_Bug // https://bugzilla.novell.com/show_bug.cgi?id=317553
+
+ class TimeoutTestHelper {
+
+ string url_to_test;
+ internal DateTime? Start { get; private set; }
+ internal DateTime? End { get; private set; }
+ internal Exception Exception { get; private set; }
+ internal string Body { get; private set; }
+ internal int TimeOutInMilliSeconds { get; private set; }
+
+ internal TimeoutTestHelper (string url, int timeoutInMilliseconds)
+ {
+ url_to_test = url;
+ TimeOutInMilliSeconds = timeoutInMilliseconds;
+ }
+
+ internal void LaunchWebRequest ()
+ {
+ var req = (HttpWebRequest) WebRequest.Create (url_to_test);
+ req.Timeout = TimeOutInMilliSeconds;
+
+ Start = DateTime.Now;
+ try {
+ using (var resp = (HttpWebResponse) req.GetResponse ())
+ {
+ var sr = new StreamReader (resp.GetResponseStream (), Encoding.UTF8);
+ Body = sr.ReadToEnd ();
+ }
+ } catch (Exception e) {
+ End = DateTime.Now;
+ Exception = e;
+ }
+ }
+ }
+
+ void TestTimeOut (string url)
+ {
+ var timeoutWorker = new TimeoutTestHelper (url, three_seconds_in_milliseconds);
+ var threadStart = new ThreadStart (timeoutWorker.LaunchWebRequest);
+ var thread = new Thread (threadStart);
+ thread.Start ();
+ Thread.Sleep (three_seconds_in_milliseconds * 3);
+
+ if (timeoutWorker.End == null) {
+ thread.Abort ();
+ Assert.Fail ("Thread did not finish after double the timout specified passed");
+ }
+
+ if (!String.IsNullOrEmpty (timeoutWorker.Body)) {
+ if (timeoutWorker.Body == response_of_timeout_handler) {
+ Assert.Fail ("Should not be reached, timeout exception was not thrown and webrequest managed to retrieve proper body");
+ }
+ Assert.Fail ("Should not be reached, timeout exception was not thrown and webrequest managed to retrieve an incorrect body: " + timeoutWorker.Body);
+ }
+
+ Assert.IsNotNull (timeoutWorker.Exception,
+ "Timeout exception was not thrown");
+
+ var webEx = timeoutWorker.Exception as WebException;
+ Assert.IsNotNull (webEx, "Exception thrown should be WebException, but was: " +
+ timeoutWorker.Exception.GetType ().FullName);
+
+ Assert.AreEqual (webEx.Status, WebExceptionStatus.Timeout,
+ "WebException was thrown, but with a wrong status (should be timeout): " + webEx.Status);
+
+ Assert.IsFalse (timeoutWorker.End > (timeoutWorker.Start + TimeSpan.FromMilliseconds (three_seconds_in_milliseconds + 500)));
+ }
+
+ [Test] // 1st possible case of https://bugzilla.novell.com/show_bug.cgi?id=MONO74177
+ public void TestTimeoutPropertyWithServerThatExistsAndRespondsButTooLate ()
+ {
+ var ep = new IPEndPoint (IPAddress.Loopback, 8123);
+ string url = "http://" + ep + "/foobar/";
+
+ using (var responder = new SocketResponder (ep, TimeOutHandler))
+ {
+ responder.Start ();
+
+ TestTimeOut (url);
+
+ responder.Stop ();
+ }
+ }
+
+ [Test] // 2nd possible case of https://bugzilla.novell.com/show_bug.cgi?id=MONO74177
+ public void TestTimeoutPropertyWithServerThatDoesntExist ()
+ {
+ string url = "http://10.128.200.100:8271/"; // some endpoint that is unlikely to exist
+
+ TestTimeOut (url);
+ }
+
+ const string response_of_timeout_handler = "RESPONSE_OF_TIMEOUT_HANDLER";
+ const int three_seconds_in_milliseconds = 3000;
+
+ private static byte[] TimeOutHandler (Socket socket)
+ {
+ socket.Receive (new byte[4096]);
+
+ Thread.Sleep (three_seconds_in_milliseconds * 2);
+
+ var sw = new StringWriter ();
+ sw.WriteLine ("HTTP/1.1 200 OK");
+ sw.WriteLine ("Content-Type: text/plain");
+ sw.WriteLine ("Content-Length: " + response_of_timeout_handler.Length);
+ sw.WriteLine ();
+ sw.Write (response_of_timeout_handler);
+ sw.Flush ();
+
+ return Encoding.UTF8.GetBytes (sw.ToString ());
+ }
+
+ #endregion
+
internal static byte [] EchoRequestHandler (Socket socket)
{
MemoryStream ms = new MemoryStream ();
}
[Test]
+ [Category ("MobileNotWorking")]
public void Constructor_IntIntStringBoolSecurity ()
{
bool created = false;
}
[Test]
+ [Category ("MobileNotWorking")]
[ExpectedException (typeof (ArgumentNullException))]
public void OpenExisting_NullName ()
{
}
[Test]
+ [Category ("MobileNotWorking")]
[ExpectedException (typeof (ArgumentException))]
public void OpenExisting_EmptyName ()
{
}
[Test]
+ [Category ("MobileNotWorking")]
[ExpectedException (typeof (ArgumentException))]
public void OpenExisting_TooLongName ()
{
}
[Test]
+ [Category ("MobileNotWorking")]
[ExpectedException (typeof (WaitHandleCannotBeOpenedException))]
public void OpenExisting_Unexisting ()
{
, IReadOnlyList<T>
#endif
{
- IList <T> list;
+ IList <T> items;
+ [field:NonSerializedAttribute()]
object syncRoot;
public Collection ()
List <T> l = new List <T> ();
IList l2 = l as IList;
syncRoot = l2.SyncRoot;
- list = l;
+ items = l;
}
- public Collection (IList <T> list)
+ public Collection (IList <T> items)
{
- if (list == null)
- throw new ArgumentNullException ("list");
- this.list = list;
- ICollection l = list as ICollection;
+ if (items == null)
+ throw new ArgumentNullException ("items");
+ this.items = items;
+ ICollection l = items as ICollection;
syncRoot = (l != null) ? l.SyncRoot : new object ();
}
public void Add (T item)
{
- int idx = list.Count;
+ int idx = items.Count;
InsertItem (idx, item);
}
protected virtual void ClearItems ()
{
- list.Clear ();
+ items.Clear ();
}
public bool Contains (T item)
{
- return list.Contains (item);
+ return items.Contains (item);
}
public void CopyTo (T [] array, int index)
{
- list.CopyTo (array, index);
+ items.CopyTo (array, index);
}
public IEnumerator <T> GetEnumerator ()
{
- return list.GetEnumerator ();
+ return items.GetEnumerator ();
}
public int IndexOf (T item)
{
- return list.IndexOf (item);
+ return items.IndexOf (item);
}
public void Insert (int index, T item)
protected virtual void InsertItem (int index, T item)
{
- list.Insert (index, item);
+ items.Insert (index, item);
}
protected IList<T> Items {
- get { return list; }
+ get { return items; }
}
public bool Remove (T item)
protected virtual void RemoveItem (int index)
{
- list.RemoveAt (index);
+ items.RemoveAt (index);
}
public int Count {
- get { return list.Count; }
+ get { return items.Count; }
}
public T this [int index] {
- get { return list [index]; }
+ get { return items [index]; }
set { SetItem (index, value); }
}
bool ICollection<T>.IsReadOnly {
- get { return list.IsReadOnly; }
+ get { return items.IsReadOnly; }
}
protected virtual void SetItem (int index, T item)
{
- list[index] = item;
+ items[index] = item;
}
throw new ArgumentException ("item");
}
- internal static void CheckWritable (IList <T> list)
+ internal static void CheckWritable (IList <T> items)
{
- if (list.IsReadOnly)
+ if (items.IsReadOnly)
throw new NotSupportedException ();
}
- internal static bool IsSynchronized (IList <T> list)
+ internal static bool IsSynchronized (IList <T> items)
{
- ICollection c = list as ICollection;
+ ICollection c = items as ICollection;
return (c != null) ? c.IsSynchronized : false;
}
- internal static bool IsFixedSize (IList <T> list)
+ internal static bool IsFixedSize (IList <T> items)
{
- IList l = list as IList;
+ IList l = items as IList;
return (l != null) ? l.IsFixedSize : false;
}
#endregion
#region Not generic interface implementations
void ICollection.CopyTo (Array array, int index)
{
- ((ICollection)list).CopyTo (array, index);
+ ((ICollection)items).CopyTo (array, index);
}
IEnumerator IEnumerable.GetEnumerator ()
{
- return (IEnumerator) list.GetEnumerator ();
+ return (IEnumerator) items.GetEnumerator ();
}
int IList.Add (object value)
{
- int idx = list.Count;
+ int idx = items.Count;
InsertItem (idx, ConvertItem (value));
return idx;
}
bool IList.Contains (object value)
{
if (CollectionHelpers.IsValidItem<T> (value))
- return list.Contains ((T) value);
+ return items.Contains ((T) value);
return false;
}
int IList.IndexOf (object value)
{
if (CollectionHelpers.IsValidItem<T> (value))
- return list.IndexOf ((T) value);
+ return items.IndexOf ((T) value);
return -1;
}
void IList.Remove (object value)
{
- CheckWritable (list);
+ CheckWritable (items);
int idx = IndexOf (ConvertItem (value));
}
bool ICollection.IsSynchronized {
- get { return IsSynchronized (list); }
+ get { return IsSynchronized (items); }
}
object ICollection.SyncRoot {
get { return syncRoot; }
}
bool IList.IsFixedSize {
- get { return IsFixedSize (list); }
+ get { return IsFixedSize (items); }
}
bool IList.IsReadOnly {
- get { return list.IsReadOnly; }
+ get { return items.IsReadOnly; }
}
object IList.this [int index] {
- get { return list [index]; }
+ get { return items [index]; }
set { SetItem (index, ConvertItem (value)); }
}
#endregion
return(buf_start + buf_offset);
}
set {
- if (handle == MonoIO.InvalidHandle)
- throw new ObjectDisposedException ("Stream has been closed");
-
- if(CanSeek == false) {
- throw new NotSupportedException("The stream does not support seeking");
- }
-
if(value < 0) {
throw new ArgumentOutOfRangeException("Attempt to set the position to a negative value");
}
public void OnCompleted (Action continuation)
{
- if (continuation == null)
- throw new ArgumentNullException ("continuation");
-
- if (TaskScheduler.Current == TaskScheduler.Default) {
- //
- // Pass continuation as an argument to avoid allocating
- // hoisting class
- //
- ThreadPool.QueueUserWorkItem (l => ((Action) l) (), continuation);
- } else {
- new Task (continuation).Start (TaskScheduler.Current);
- }
+ OnCompleted (continuation, false);
}
-
+
public void UnsafeOnCompleted (Action continuation)
+ {
+ OnCompleted (continuation, true);
+ }
+
+ void OnCompleted (Action continuation, bool isUnsafe)
{
if (continuation == null)
throw new ArgumentNullException ("continuation");
+ var ctx = SynchronizationContext.Current;
+ if (ctx != null) {
+ ctx.Post (l => ((Action) l) (), continuation);
+ return;
+ }
+
if (TaskScheduler.Current == TaskScheduler.Default) {
//
- // Pass the continuation as an argument to avoid allocating
+ // Pass continuation as an argument to avoid allocating
// hoisting class
//
- ThreadPool.UnsafeQueueUserWorkItem (l => ((Action) l) (), continuation);
- } else {
- new Task (continuation).Start (TaskScheduler.Current);
+ WaitCallback callBack = l => ((Action) l) ();
+ if (isUnsafe) {
+ ThreadPool.UnsafeQueueUserWorkItem (callBack, continuation);
+ } else {
+ ThreadPool.QueueUserWorkItem (callBack, continuation);
+ }
+ return;
}
+
+ new Task (continuation).Start (TaskScheduler.Current);
}
public void GetResult ()
+//
// AggregateException.cs
//
+// Authors:
+// Marek Safar (marek.safar@gmail.com)
+//
// Copyright (c) 2008 Jérémie "Garuma" Laval
+// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
namespace System
{
-
[System.SerializableAttribute]
[System.Diagnostics.DebuggerDisplay ("Count = {InnerExceptions.Count}")]
public class AggregateException : Exception
public void Handle (Func<Exception, bool> predicate)
{
+ if (predicate == null)
+ throw new ArgumentNullException ("predicate");
+
List<Exception> failed = new List<Exception> ();
foreach (var e in innerExceptions) {
- try {
- if (!predicate (e))
- failed.Add (e);
- } catch {
- throw new AggregateException (failed);
- }
+ if (!predicate (e))
+ failed.Add (e);
}
+
if (failed.Count > 0)
throw new AggregateException (failed);
}
return MemberwiseClone ();
}
- public override bool Equals (object obj)
+ internal bool Compare (Delegate d)
{
- Delegate d = obj as Delegate;
-
if (d == null)
return false;
return false;
}
+ public override bool Equals (object obj)
+ {
+ return Compare (obj as Delegate);
+ }
+
public override int GetHashCode ()
{
return method.GetHashCode () ^ (m_target != null ? m_target.GetHashCode () : 0);
MulticastDelegate d = obj as MulticastDelegate;
if (d == null)
return false;
-
- if (this.prev == null) {
- if (d.prev == null)
- return true;
- else
- return false;
- }
- return this.prev.Equals (d.prev);
+ MulticastDelegate this_prev = this.prev;
+ MulticastDelegate obj_prev = d.prev;
+
+ do {
+ if (this_prev == null)
+ return obj_prev == null;
+
+ if (!this_prev.Compare (obj_prev))
+ return false;
+
+ this_prev = this_prev.prev;
+ obj_prev = obj_prev.prev;
+ } while (true);
}
//
int[] lens = new int [3];
int index = 0;
int lastPos = 0;
- char literal = '\0';
+ bool quoted = false;
+
for (int i = 0; i < format.Length; i++) {
char c = format [i];
- if (c == literal || (literal == '\0' && (c == '\"' || c == '\''))) {
- if (literal == '\0')
- literal = c;
- else
- literal = '\0';
+ if (c == '\"' || c == '\'') {
+ if (i == 0 || format [i - 1] != '\\')
+ quoted = !quoted;
+
continue;
}
- if (literal == '\0' && format [i] == ';' && (i == 0 || format [i - 1] != '\\')) {
+ if (c == ';' && !quoted && (i == 0 || format [i - 1] != '\\')) {
lens [index++] = i - lastPos;
lastPos = i + 1;
if (index == 3)
Throws (typeof (ArgumentNullException), () => new AggregateException ((Exception[])null));
}
+ [Test]
+ [ExpectedException (typeof (ArgumentNullException))]
+ public void Handle_Invalid ()
+ {
+ e.Handle (null);
+ }
+
+ [Test]
+ public void Handle_AllHandled ()
+ {
+ e.Handle (l => true);
+ }
+
+ [Test]
+ public void Handle_Unhandled ()
+ {
+ try {
+ e.Handle (l => l is AggregateException);
+ Assert.Fail ();
+ } catch (AggregateException e) {
+ Assert.AreEqual (1, e.InnerExceptions.Count);
+ }
+ }
+
static void Throws (Type t, Action action)
{
Exception e = null;
{
Assert.AreEqual ("", 0.0.ToString ("X99", _nfi) , "#01");
}
+
+ [Test]
+ public void Test18000 ()
+ {
+ string formatString = "p 00.0000\\';n 0000.00\\';0.#\\'";
+
+ Assert.AreEqual ("p 08.3266'", 8.32663472.ToString (formatString, CultureInfo.InvariantCulture), "#1");
+ Assert.AreEqual ("n 0001.13'", (-1.1345343).ToString (formatString, CultureInfo.InvariantCulture), "#2");
+ Assert.AreEqual ("0'", 0.0.ToString (formatString, CultureInfo.InvariantCulture), "#3");
+ }
}
}
$(IMAGES)
EXTRA_DISTFILES = \
+ jay.sh \
monodoc.dll.config.in \
$(RESOURCE_FILES) \
Monodoc.Ecma/EcmaUrlParser.jay \
$(the_lib).config: Makefile monodoc.dll.config.in
sed 's,@monodoc_refdir@,$(mono_libdir)/monodoc,g' monodoc.dll.config.in > $@
-Monodoc.Ecma/EcmaUrlParser.cs: Monodoc.Ecma/EcmaUrlParser.jay $(topdir)/jay/skeleton.cs
- $(topdir)/jay/jay $(JAY_FLAGS) < $(topdir)/jay/skeleton.cs $< > jay-tmp.out && mv jay-tmp.out $@
+Monodoc.Ecma/EcmaUrlParser.cs: Monodoc.Ecma/EcmaUrlParser.jay $(topdir)/jay/skeleton.cs jay.sh
+ $(topdir)/$(thisdir)/jay.sh $(topdir) $< $@ $(JAY_FLAGS)
parser.exe: Monodoc.Ecma/EcmaUrlParser.cs Monodoc.Ecma/EcmaUrlTokenizer.cs Monodoc.Ecma/EcmaUrlParserDriver.cs Monodoc.Ecma/EcmaDesc.cs
mcs /out:$@ /debug $^
--- /dev/null
+#!/bin/sh
+
+TOPDIR=$1
+INPUT=$2
+OUTPUT=$3
+FLAGS=$4
+
+TEMPFILE=jay-tmp-$RANDOM.out
+
+$TOPDIR/jay/jay $FLAGS < $TOPDIR/jay/skeleton.cs $INPUT > $TEMPFILE && mv $TEMPFILE $OUTPUT
--- /dev/null
+// CS0761: Partial method declarations of `C.Foo<U>()' have inconsistent constraints for type parameter `U'
+// Line: 8
+
+partial class C
+{
+ partial void Foo<T> () where T : new ();
+
+ partial void Foo<U> ()
+ {
+ }
+}
--- /dev/null
+// CS0761: Partial method declarations of `C.Foo<T>()' have inconsistent constraints for type parameter `T'
+// Line: 8
+
+partial class C
+{
+ partial void Foo<U> ();
+
+ partial void Foo<T> () where T : class
+ {
+ }
+}
--- /dev/null
+// CS1705: Assembly `CS1705-lib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' references `CS1705-lib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=36f3ae7e947792e3' which has a higher version number than imported assembly `CS1705-lib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=36f3ae7e947792e3'
+// Line: 0
+// Compiler options: -r:CS1705-lib.dll -r:dlls/second/CS1705-lib.dll -keyfile:key.snk
+
+class C
+{
+ public static void Main ()
+ {
+ A.Test (new B ());
+ }
+}
//
method = DoCreateMethodHost (ec);
method.Define ();
+ method.PrepareEmit ();
}
bool is_static = (method.ModFlags & Modifiers.STATIC) != 0;
equals.Block = equals_block;
equals.Define ();
+ equals.PrepareEmit ();
Members.Add (equals);
//
hashcode_block.AddStatement (new Return (hash_variable, loc));
hashcode.Block = hashcode_top;
hashcode.Define ();
+ hashcode.PrepareEmit ();
Members.Add (hashcode);
//
tostring_block.AddStatement (new Return (string_concat, loc));
tostring.Block = tostring_block;
tostring.Define ();
+ tostring.PrepareEmit ();
Members.Add (tostring);
return true;
// no working SRE API
foreach (var entry in Importer.Assemblies) {
var a = entry as ImportedAssemblyDefinition;
- if (a == null)
+ if (a == null || a.IsMissing)
continue;
if (public_key != null && !a.HasStrongName) {
all_tp_builders = TypeBuilder.DefineGenericParameters (tparam_names);
- if (CurrentTypeParameters != null)
- CurrentTypeParameters.Define (all_tp_builders, spec, CurrentTypeParametersStartIndex, this);
+ if (CurrentTypeParameters != null) {
+ CurrentTypeParameters.Create (spec, CurrentTypeParametersStartIndex, this);
+ CurrentTypeParameters.Define (all_tp_builders);
+ }
}
return true;
members.Add (proxy_method);
proxy_method.Define ();
+ proxy_method.PrepareEmit ();
hoisted_base_call_proxies.Add (method, proxy_method);
}
foreach (var member in members) {
var pm = member as IParametersMember;
if (pm != null) {
+ var mc = member as MethodOrOperator;
+ if (mc != null) {
+ mc.PrepareEmit ();
+ }
var p = pm.Parameters;
if (p.IsEmpty)
current_type = null;
}
- void UpdateTypeParameterConstraints (TypeDefinition part)
- {
- for (int i = 0; i < CurrentTypeParameters.Count; i++) {
- if (CurrentTypeParameters[i].AddPartialConstraints (part, part.MemberName.TypeParameters[i]))
- continue;
-
- Report.SymbolRelatedToPreviousError (Location, "");
- Report.Error (265, part.Location,
- "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
- GetSignatureForError (), CurrentTypeParameters[i].GetSignatureForError ());
- }
- }
-
public override void RemoveContainer (TypeContainer cont)
{
base.RemoveContainer (cont);
}
if (IsPartialPart) {
- PartialContainer.UpdateTypeParameterConstraints (this);
+ PartialContainer.CurrentTypeParameters.UpdateConstraints (this);
}
return true;
;
named_argument
- : identifier_inside_body COLON opt_named_modifier expression
+ : identifier_inside_body COLON opt_named_modifier expression_or_error
{
if (lang_version <= LanguageVersion.V_3)
FeatureIsNotAvailable (GetLocation ($1), "named argument");
async_block = (method.ModFlags & Modifiers.ASYNC) != 0;
- if ($11 != null)
- method.SetConstraints ((List<Constraints>) $11);
+ if ($12 != null)
+ method.SetConstraints ((List<Constraints>) $12);
if (doc_support)
method.DocComment = Lexer.consume_doc_comment ();
void SetIsUsed ();
}
+ public interface IMethodDefinition : IMemberDefinition
+ {
+ MethodBase Metadata { get; }
+ }
+
public interface IParametersMember : IInterfaceMemberSpec
{
AParametersCollection Parameters { get; }
if (!Parameters.IsEmpty) {
parameters.ResolveDefaultValues (this);
}
+
+ InvokeBuilder.PrepareEmit ();
+ if (BeginInvokeBuilder != null) {
+ BeginInvokeBuilder.PrepareEmit ();
+ EndInvokeBuilder.PrepareEmit ();
+ }
}
public override void Emit ()
d.CreateContainer ();
d.DefineContainer ();
d.Define ();
+ d.PrepareEmit ();
site.AddTypeContainer (d);
del_type = new TypeExpression (d.CurrentType, loc);
{
if (rhs == EmptyExpression.LValueMemberAccess || rhs == EmptyExpression.LValueMemberOutAccess) {
// Already reported as CS1612
+ } else if (rhs == EmptyExpression.OutAccess) {
+ rc.Report.Error (1510, loc, "A ref or out argument must be an assignable variable");
} else {
rc.Report.Error (131, loc, "The left-hand side of an assignment must be a variable, a property or an indexer");
}
if (e == null) {
if (errors == ec.Report.Errors) {
- if (out_access)
- ec.Report.Error (1510, loc, "A ref or out argument must be an assignable variable");
- else
- Error_ValueAssignment (ec, right_side);
+ Error_ValueAssignment (ec, right_side);
}
return null;
}
if (ExtensionExpression == null)
return null;
+ var cand = candidates;
arguments.Insert (0, new Argument (ExtensionExpression, Argument.AType.ExtensionType));
var res = base.OverloadResolve (ec, ref arguments, ehandler ?? this, restr);
+
+ // Restore candidates in case we are running in probing mode
+ candidates = cand;
// Store resolved argument and restore original arguments
if (res == null) {
string index = (idx + 1).ToString ();
if (((mod & Parameter.Modifier.RefOutMask) ^ (a.Modifier & Parameter.Modifier.RefOutMask)) != 0) {
if ((mod & Parameter.Modifier.RefOutMask) == 0)
- ec.Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier",
+ ec.Report.Error (1615, a.Expr.Location, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier",
index, Parameter.GetModifierSignature (a.Modifier));
else
- ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
+ ec.Report.Error (1620, a.Expr.Location, "Argument `#{0}' is missing `{1}' modifier",
index, Parameter.GetModifierSignature (mod));
} else {
string p1 = a.GetSignatureForError ();
}
if (host != null){
+ host.PrepareEmit ();
host.EmitContainer ();
}
//
// If partial type parameters constraints are not null and we don't
// already have constraints they become our constraints. If we already
- // have constraints, we must check that they're the same.
+ // have constraints, we must check that they're same.
//
public bool AddPartialConstraints (TypeDefinition part, TypeParameter tp)
{
// with SRE (by calling `DefineGenericParameters()' on the TypeBuilder /
// MethodBuilder).
//
- public void Define (GenericTypeParameterBuilder type, TypeSpec declaringType, TypeContainer parent)
+ public void Create (TypeSpec declaringType, TypeContainer parent)
{
if (builder != null)
throw new InternalErrorException ();
// Needed to get compiler reference
this.Parent = parent;
- this.builder = type;
spec.DeclaringType = declaringType;
+ }
+
+ public void Define (GenericTypeParameterBuilder type)
+ {
+ this.builder = type;
spec.SetMetaInfo (type);
}
names.AddRange (tparams.names);
}
- public void Define (GenericTypeParameterBuilder[] buiders, TypeSpec declaringType, int parentOffset, TypeContainer parent)
+ public void Create (TypeSpec declaringType, int parentOffset, TypeContainer parent)
{
types = new TypeParameterSpec[Count];
for (int i = 0; i < types.Length; ++i) {
var tp = names[i];
- tp.Define (buiders[i + parentOffset], declaringType, parent);
+ tp.Create (declaringType, parent);
types[i] = tp.Type;
types[i].DeclaredPosition = i + parentOffset;
}
}
+ public void Define (GenericTypeParameterBuilder[] builders)
+ {
+ for (int i = 0; i < types.Length; ++i) {
+ var tp = names[i];
+ tp.Define (builders [types [i].DeclaredPosition]);
+ }
+ }
+
public TypeParameter this[int index] {
get {
return names [index];
return sb.ToString ();
}
+
+ public void CheckPartialConstraints (Method part)
+ {
+ var partTypeParameters = part.CurrentTypeParameters;
+
+ for (int i = 0; i < Count; i++) {
+ var tp_a = names[i];
+ var tp_b = partTypeParameters [i];
+ if (tp_a.Constraints == null) {
+ if (tp_b.Constraints == null)
+ continue;
+ } else if (tp_b.Constraints != null && tp_a.Type.HasSameConstraintsDefinition (tp_b.Type)) {
+ continue;
+ }
+
+ part.Compiler.Report.SymbolRelatedToPreviousError (this[i].CurrentMemberDefinition.Location, "");
+ part.Compiler.Report.Error (761, part.Location,
+ "Partial method declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
+ part.GetSignatureForError (), partTypeParameters[i].GetSignatureForError ());
+ }
+ }
+
+ public void UpdateConstraints (TypeDefinition part)
+ {
+ var partTypeParameters = part.MemberName.TypeParameters;
+
+ for (int i = 0; i < Count; i++) {
+ var tp = names [i];
+ if (tp.AddPartialConstraints (part, partTypeParameters [i]))
+ continue;
+
+ part.Compiler.Report.SymbolRelatedToPreviousError (this[i].CurrentMemberDefinition);
+ part.Compiler.Report.Error (265, part.Location,
+ "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
+ part.GetSignatureForError (), tp.GetSignatureForError ());
+ }
+ }
+
public void VerifyClsCompliance ()
{
foreach (var tp in names) {
}
}
- IMemberDefinition definition;
+ IMethodDefinition definition;
if (tparams != null) {
var gmd = new ImportedGenericMethodDefinition ((MethodInfo) mb, returnType, parameters, tparams, this);
foreach (var tp in gmd.TypeParameters) {
definition = gmd;
} else {
- definition = new ImportedParameterMemberDefinition (mb, returnType, parameters, this);
+ definition = new ImportedMethodDefinition (mb, returnType, parameters, this);
}
- MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
+ MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, parameters, mod);
if (tparams != null)
ms.IsGeneric = true;
{
readonly AParametersCollection parameters;
- public ImportedParameterMemberDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
+ protected ImportedParameterMemberDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
: base (provider, type, importer)
{
this.parameters = parameters;
#endregion
}
- class ImportedGenericMethodDefinition : ImportedParameterMemberDefinition, IGenericMethodDefinition
+ class ImportedMethodDefinition : ImportedParameterMemberDefinition, IMethodDefinition
+ {
+ public ImportedMethodDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
+ : base (provider, type, parameters, importer)
+ {
+ }
+
+ MethodBase IMethodDefinition.Metadata {
+ get {
+ return (MethodBase) provider;
+ }
+ }
+ }
+
+ class ImportedGenericMethodDefinition : ImportedMethodDefinition, IGenericMethodDefinition
{
readonly TypeParameterSpec[] tparams;
"A partial method declaration and partial method implementation must be both `static' or neither");
}
- Report.SymbolRelatedToPreviousError (ce);
- Report.Error (764, member.Location,
- "A partial method declaration and partial method implementation must be both `unsafe' or neither");
+ if ((method_a.ModFlags & Modifiers.UNSAFE) != (method_b.ModFlags & Modifiers.UNSAFE)) {
+ Report.SymbolRelatedToPreviousError (ce);
+ Report.Error (764, member.Location,
+ "A partial method declaration and partial method implementation must be both `unsafe' or neither");
+ }
+
return false;
}
}
}
- public interface IGenericMethodDefinition : IMemberDefinition
+ public interface IGenericMethodDefinition : IMethodDefinition
{
TypeParameterSpec[] TypeParameters { get; }
int TypeParametersCount { get; }
public sealed class MethodSpec : MemberSpec, IParametersMember
{
- MethodBase metaInfo, inflatedMetaInfo;
+ MethodBase inflatedMetaInfo;
AParametersCollection parameters;
TypeSpec returnType;
TypeSpec[] targs;
TypeParameterSpec[] constraints;
- public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType,
- MethodBase info, AParametersCollection parameters, Modifiers modifiers)
+ public MethodSpec (MemberKind kind, TypeSpec declaringType, IMethodDefinition details, TypeSpec returnType,
+ AParametersCollection parameters, Modifiers modifiers)
: base (kind, declaringType, details, modifiers)
{
- this.metaInfo = info;
this.parameters = parameters;
this.returnType = returnType;
}
}
}
+ public new IMethodDefinition MemberDefinition {
+ get {
+ return (IMethodDefinition) definition;
+ }
+ }
+
public IGenericMethodDefinition GenericDefinition {
get {
return (IGenericMethodDefinition) definition;
if (DeclaringType.IsTypeBuilder) {
if (IsConstructor)
- inflatedMetaInfo = TypeBuilder.GetConstructor (dt_meta, (ConstructorInfo) metaInfo);
+ inflatedMetaInfo = TypeBuilder.GetConstructor (dt_meta, (ConstructorInfo) MemberDefinition.Metadata);
else
- inflatedMetaInfo = TypeBuilder.GetMethod (dt_meta, (MethodInfo) metaInfo);
+ inflatedMetaInfo = TypeBuilder.GetMethod (dt_meta, (MethodInfo) MemberDefinition.Metadata);
} else {
#if STATIC
// it should not be reached
throw new NotImplementedException ();
#else
- inflatedMetaInfo = MethodInfo.GetMethodFromHandle (metaInfo.MethodHandle, dt_meta.TypeHandle);
+ inflatedMetaInfo = MethodInfo.GetMethodFromHandle (MemberDefinition.Metadata.MethodHandle, dt_meta.TypeHandle);
#endif
}
state &= ~StateFlags.PendingMetaInflate;
} else {
- inflatedMetaInfo = metaInfo;
+ inflatedMetaInfo = MemberDefinition.Metadata;
}
}
return missing;
}
-
- public void SetMetaInfo (MethodInfo info)
- {
- if (this.metaInfo != null)
- throw new InternalErrorException ("MetaInfo reset");
-
- this.metaInfo = info;
- }
}
- public abstract class MethodOrOperator : MethodCore, IMethodData
+ public abstract class MethodOrOperator : MethodCore, IMethodData, IMethodDefinition
{
- public MethodBuilder MethodBuilder;
ReturnParameter return_attributes;
SecurityType declarative_security;
protected MethodData MethodData;
}
}
+ MethodBase IMethodDefinition.Metadata {
+ get {
+ return MethodData.MethodBuilder;
+ }
+ }
+
+ // TODO: Remove and use MethodData abstraction
+ public MethodBuilder MethodBuilder {
+ get {
+ return MethodData.MethodBuilder;
+ }
+ }
+
protected override bool CheckForDuplications ()
{
return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
else
kind = MemberKind.Method;
+ string explicit_name;
+
if (IsPartialDefinition) {
caching_flags &= ~Flags.Excluded_Undetected;
caching_flags |= Flags.Excluded;
// Add to member cache only when a partial method implementation has not been found yet
- if ((caching_flags & Flags.PartialDefinitionExists) == 0) {
-// MethodBase mb = new PartialMethodDefinitionInfo (this);
+ if ((caching_flags & Flags.PartialDefinitionExists) != 0)
+ return true;
- spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
- if (MemberName.Arity > 0) {
- spec.IsGeneric = true;
+ if (IsExplicitImpl)
+ return true;
- // TODO: Have to move DefineMethod after Define (ideally to Emit)
- throw new NotImplementedException ("Generic partial methods");
- }
+ explicit_name = null;
+ } else {
+ MethodData = new MethodData (this, ModFlags, flags, this, base_method);
- Parent.MemberCache.AddMember (spec);
- }
+ if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
+ return false;
- return true;
+ explicit_name = MethodData.MetadataName;
}
- MethodData = new MethodData (
- this, ModFlags, flags, this, MethodBuilder, base_method);
-
- if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
- return false;
-
- MethodBuilder = MethodData.MethodBuilder;
-
- spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
+ spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, parameters, ModFlags);
if (MemberName.Arity > 0)
spec.IsGeneric = true;
-
- Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);
+
+ Parent.MemberCache.AddMember (this, explicit_name, spec);
return true;
}
if (MethodData != null)
MethodData.Emit (Parent);
- Block = null;
+ if ((ModFlags & Modifiers.PARTIAL) == 0)
+ Block = null;
}
protected void Error_ConditionalAttributeIsNotValid ()
#endregion
+ public virtual void PrepareEmit ()
+ {
+ var mb = MethodData.DefineMethodBuilder (Parent);
+
+ if (CurrentTypeParameters != null) {
+ string[] gnames = new string[CurrentTypeParameters.Count];
+ for (int i = 0; i < gnames.Length; ++i) {
+ gnames[i] = CurrentTypeParameters[i].Name;
+ }
+
+ var gen_params = MethodBuilder.DefineGenericParameters (gnames);
+
+ for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
+ var tp = CurrentTypeParameters[i];
+
+ tp.Define (gen_params[i]);
+ }
+ }
+
+ //
+ // Generic method has been already defined to resolve method parameters
+ // correctly when they use type parameters
+ //
+ mb.SetParameters (parameters.GetMetaInfo ());
+ mb.SetReturnType (ReturnType.GetMetaInfo ());
+ }
+
public override void WriteDebugSymbol (MonoSymbolFile file)
{
- if (MethodData != null)
+ if (MethodData != null && !IsPartialDefinition)
MethodData.WriteDebugSymbol (file);
}
}
}
}
-#endregion
+ #endregion
public override void Accept (StructuralVisitor visitor)
{
void CreateTypeParameters ()
{
var tparams = MemberName.TypeParameters;
- string[] snames = new string[MemberName.Arity];
var parent_tparams = Parent.TypeParametersAll;
- for (int i = 0; i < snames.Length; i++) {
+ for (int i = 0; i < MemberName.Arity; i++) {
string type_argument_name = tparams[i].MemberName.Name;
if (block == null) {
tparams[i].WarningParentNameConflict (tp);
}
}
-
- snames[i] = type_argument_name;
}
- GenericTypeParameterBuilder[] gen_params = MethodBuilder.DefineGenericParameters (snames);
- tparams.Define (gen_params, null, 0, Parent);
+ tparams.Create (null, 0, Parent);
}
protected virtual void DefineTypeParameters ()
"Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
}
- if (partialMethodImplementation != null && IsPartialDefinition)
- MethodBuilder = partialMethodImplementation.MethodBuilder;
-
if (Compiler.Settings.StdLib && ReturnType.IsSpecialRuntimeType) {
Error1599 (Location, ReturnType, Report);
return false;
return true;
}
+ public override void PrepareEmit ()
+ {
+ if (IsPartialDefinition) {
+ //
+ // Use partial method implementation builder for partial method declaration attributes
+ //
+ if (partialMethodImplementation != null) {
+ MethodData = partialMethodImplementation.MethodData;
+ }
+
+ return;
+ }
+
+ base.PrepareEmit ();
+ }
+
//
// Emits the code
//
{
try {
if (IsPartialDefinition) {
- //
- // Use partial method implementation builder for partial method declaration attributes
- //
- if (partialMethodImplementation != null) {
- MethodBuilder = partialMethodImplementation.MethodBuilder;
+ if (partialMethodImplementation != null && CurrentTypeParameters != null) {
+ CurrentTypeParameters.CheckPartialConstraints (partialMethodImplementation);
}
return;
if (CurrentTypeParameters != null) {
for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
var tp = CurrentTypeParameters [i];
+
tp.CheckGenericConstraints (false);
tp.Emit ();
}
Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder);
base.Emit ();
- } catch {
- Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
- Location, MethodBuilder);
- throw;
+ } catch (Exception e) {
+ throw new InternalErrorException (this, e);
}
}
protected override bool ResolveMemberType ()
{
if (CurrentTypeParameters != null) {
- MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
CreateTypeParameters ();
}
}
}
- public class Constructor : MethodCore, IMethodData
+ public class Constructor : MethodCore, IMethodData, IMethodDefinition
{
public ConstructorBuilder ConstructorBuilder;
public ConstructorInitializer Initializer;
}
}
+
+ MethodBase IMethodDefinition.Metadata {
+ get {
+ return ConstructorBuilder;
+ }
+ }
+
//
// Returns true if this is a default constructor
//
ca, CallingConventions,
parameters.GetMetaInfo ());
- spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, ConstructorBuilder, parameters, ModFlags);
+ spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, parameters, ModFlags);
Parent.MemberCache.AddMember (spec);
//
public class MethodData
{
-#if !STATIC
- static FieldInfo methodbuilder_attrs_field;
-#endif
-
public readonly IMethodData method;
//
protected TypeSpec declaring_type;
protected MethodSpec parent_method;
SourceMethodBuilder debug_builder;
+ string full_name;
MethodBuilder builder;
public MethodBuilder MethodBuilder {
}
}
+ public string MetadataName {
+ get {
+ return full_name;
+ }
+ }
+
public MethodData (InterfaceMemberBase member,
Modifiers modifiers, MethodAttributes flags, IMethodData method)
{
public MethodData (InterfaceMemberBase member,
Modifiers modifiers, MethodAttributes flags,
- IMethodData method, MethodBuilder builder,
+ IMethodData method,
MethodSpec parent_method)
: this (member, modifiers, flags, method)
{
- this.builder = builder;
this.parent_method = parent_method;
}
method_full_name = implementing.MemberDefinition.Name;
}
- DefineMethodBuilder (container, method_full_name, method.ParameterInfo);
+ full_name = method_full_name;
+ declaring_type = container.Definition;
- if (builder == null)
- return false;
+ return true;
+ }
-// if (container.CurrentType != null)
-// declaring_type = container.CurrentType;
-// else
- declaring_type = container.Definition;
+ void DefineOverride (TypeDefinition container)
+ {
+ if (implementing == null)
+ return;
- if (implementing != null && member.IsExplicitImpl) {
- container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
- }
+ if (!member.IsExplicitImpl)
+ return;
- return true;
+ container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
}
-
- /// <summary>
- /// Create the MethodBuilder for the method
- /// </summary>
- void DefineMethodBuilder (TypeDefinition container, string method_name, ParametersCompiled param)
+ //
+ // Creates partial MethodBuilder for the method when has generic parameters used
+ // as arguments or return type
+ //
+ public MethodBuilder DefineMethodBuilder (TypeDefinition container)
{
- var return_type = method.ReturnType.GetMetaInfo ();
- var p_types = param.GetMetaInfo ();
+ if (builder != null)
+ throw new InternalErrorException ();
- if (builder == null) {
- builder = container.TypeBuilder.DefineMethod (
- method_name, flags, method.CallingConventions,
- return_type, p_types);
- return;
- }
+ builder = container.TypeBuilder.DefineMethod (full_name, flags, method.CallingConventions);
+ return builder;
+ }
- //
- // Generic method has been already defined to resolve method parameters
- // correctly when they use type parameters
- //
- builder.SetParameters (p_types);
- builder.SetReturnType (return_type);
- if (builder.Attributes != flags) {
-#if STATIC
- builder.__SetAttributes (flags);
-#else
- try {
- if (methodbuilder_attrs_field == null)
- methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
- methodbuilder_attrs_field.SetValue (builder, flags);
- } catch {
- container.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
- }
-#endif
- }
+ //
+ // Creates full MethodBuilder for the method
+ //
+ public MethodBuilder DefineMethodBuilder (TypeDefinition container, ParametersCompiled param)
+ {
+ DefineMethodBuilder (container);
+ builder.SetReturnType (method.ReturnType.GetMetaInfo ());
+ builder.SetParameters (param.GetMetaInfo ());
+ return builder;
}
//
//
public void Emit (TypeDefinition parent)
{
+ DefineOverride (parent);
+
var mc = (IMemberContext) method;
method.ParameterInfo.ApplyAttributes (mc, MethodBuilder);
// Ooouh Martin, templates are missing here.
// When it will be possible move here a lot of child code and template method type.
- public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
+ public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData, IMethodDefinition {
protected MethodData method_data;
protected ToplevelBlock block;
protected SecurityType declarative_security;
}
}
+ MethodBase IMethodDefinition.Metadata {
+ get {
+ return method_data.MethodBuilder;
+ }
+ }
+
public abstract ParametersCompiled ParameterInfo { get ; }
public abstract TypeSpec ReturnType { get; }
// about mismatch at return type when the check bellow rejects them
//
var parameters = mi.Parameters;
+ MethodSpec close_match = null;
+
while (true) {
var candidates = MemberCache.FindMembers (base_type, mi.Name, false);
- if (candidates == null)
+ if (candidates == null) {
+ base_method = close_match;
return false;
+ }
MethodSpec similar_candidate = null;
foreach (var candidate in candidates) {
// From this point the candidate is used for detailed error reporting
// because it's very close match to what we are looking for
//
- base_method = (MethodSpec) candidate;
+ var m = (MethodSpec) candidate;
+
+ if (!m.IsPublic) {
+ if (close_match == null)
+ close_match = m;
- if (!candidate.IsPublic)
- return false;
+ continue;
+ }
- if (!TypeSpecComparer.Override.IsEqual (mi.ReturnType, base_method.ReturnType))
- return false;
+ if (!TypeSpecComparer.Override.IsEqual (mi.ReturnType, m.ReturnType)) {
+ if (close_match == null)
+ close_match = m;
- if (mi.IsGeneric && !Method.CheckImplementingMethodConstraints (container, base_method, mi)) {
+ continue;
+ }
+
+ base_method = m;
+
+ if (mi.IsGeneric && !Method.CheckImplementingMethodConstraints (container, m, mi)) {
return true;
}
}
-
+
if (base_method != null) {
if (similar_candidate != null) {
Report.SymbolRelatedToPreviousError (similar_candidate);
}
base_type = candidates[0].DeclaringType.BaseType;
- if (base_type == null)
+ if (base_type == null) {
+ base_method = close_match;
return false;
+ }
}
if (!base_method.IsVirtual) {
{
base.Define (parent);
- Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
+ Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, ModFlags);
method_data = new MethodData (method, ModFlags, flags, this);
if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
return null;
- Spec.SetMetaInfo (method_data.MethodBuilder);
+ method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo);
return method_data.MethodBuilder;
}
base.Define (parent);
- Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
+ Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, ModFlags);
method_data = new MethodData (method, ModFlags, flags, this);
if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
return null;
- Spec.SetMetaInfo (method_data.MethodBuilder);
+ method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo);
return method_data.MethodBuilder;
}
if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
return null;
+ method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo);
+
if (Compiler.Settings.WriteMetadataOnly)
block = null;
- MethodBuilder mb = method_data.MethodBuilder;
-
- Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags);
+ Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, method.ModFlags);
Spec.IsAccessor = true;
- return mb;
+ return method_data.MethodBuilder;
}
public override TypeSpec ReturnType {
}
storey.Define ();
+ storey.PrepareEmit ();
storey.Parent.PartialContainer.AddCompilerGeneratedClass (storey);
}
if (finally_host != null) {
finally_host.Define ();
+ finally_host.PrepareEmit ();
finally_host.Emit ();
// Now it's safe to add, to close it properly and emit sequence points
--- /dev/null
+using System;
+using System.Collections.Generic;
+
+namespace ExtensionTest.Two
+{
+ public delegate TResult AxFunc<in T1, out TResult> (T1 first);
+
+ public static class Extensions
+ {
+ public static bool Contains<T> (this IEnumerable<T> source, T item)
+ {
+ return true;
+ }
+
+ public static bool All<T> (this IEnumerable<T> source, AxFunc<T, bool> predicate)
+ {
+ return true;
+ }
+
+ }
+}
+
+namespace ExtensionTest
+{
+ using ExtensionTest.Two;
+
+ public static class MyClass
+ {
+ public static bool IsCharacters (this string text, params char[] chars)
+ {
+ return text.All (chars.Contains);
+ }
+
+ public static bool Contains (this string text, string value, StringComparison comp)
+ {
+ return text.IndexOf (value, comp) >= 0;
+ }
+
+ public static void Main ()
+ {
+ }
+ }
+}
--- /dev/null
+partial class Test
+{
+ static partial void Foo<T> ();
+
+ static partial void Baz<T> ();
+
+ static partial void Baz<U> ()
+ {
+ }
+
+ static partial void Bar<T> (T t) where T : class;
+
+ static partial void Bar<U> (U u) where U : class
+ {
+ }
+
+ public static void Main ()
+ {
+ Foo<long> ();
+ Baz<string> ();
+ Bar<Test> (null);
+ }
+}
\ No newline at end of file
--- /dev/null
+class Test
+{
+ public static void Main ()
+ {
+ new BaseJobController ();
+ new JobController ();
+ }
+}
+
+public interface IUser
+{
+}
+
+public class User : IUser
+{
+}
+
+public interface IJobController
+{
+ IUser User { get; }
+}
+
+public class BaseController
+{
+ public virtual IUser User { get; set; }
+}
+
+public class BaseJobController : BaseController
+{
+ public new User User { get; set; }
+}
+
+public class JobController : BaseJobController, IJobController
+{
+}
\ No newline at end of file
</files>
<methods>
<method token="0x6000001">
- <sequencepoints>
- <entry il="0x0" row="4" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="5" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000002">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="4" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="5" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
<scopes />
</method>
<method token="0x6000007">
- <sequencepoints>
- <entry il="0x0" row="47" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="48" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000008">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="47" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="48" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
<scopes />
</method>
<method token="0x6000007">
- <sequencepoints>
- <entry il="0x0" row="25" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="26" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000008">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="25" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="26" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
<scopes />
</method>
<method token="0x6000004">
- <sequencepoints>
- <entry il="0x0" row="22" col="2" file_ref="2" hidden="false" />
- <entry il="0x1" row="23" col="2" file_ref="2" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000005">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="22" col="2" file_ref="2" hidden="false" />
+ <entry il="0x1" row="23" col="2" file_ref="2" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="4" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="5" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="12" col="2" file_ref="1" hidden="false" />
<entry il="0x9" row="55" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="59" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="60" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000004">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="6" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="7" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="10" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="12" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0xa" end="0xa" />
</scopes>
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="20" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="22" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0xa" end="0xc" />
</scopes>
</method>
- <method token="0x6000004">
+ <method token="0x6000005">
<sequencepoints>
<entry il="0x0" row="31" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="33" col="3" file_ref="1" hidden="false" />
<entry index="2" start="0x14" end="0x19" />
</scopes>
</method>
- <method token="0x6000005">
+ <method token="0x6000006">
<sequencepoints>
<entry il="0x0" row="46" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="48" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x9" end="0x9" />
</scopes>
</method>
- <method token="0x6000006">
+ <method token="0x6000007">
<sequencepoints>
<entry il="0x0" row="56" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="58" col="3" file_ref="1" hidden="false" />
<entry index="2" start="0x13" end="0x13" />
</scopes>
</method>
- <method token="0x6000007">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="4" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="5" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="9" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="10" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="14" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="15" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x3" end="0xa" />
</scopes>
</method>
- <method token="0x6000004">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="7" col="3" file_ref="1" hidden="false" />
</sequencepoints>
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints />
<locals />
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="16" col="3" file_ref="1" hidden="false" />
</sequencepoints>
<locals />
<scopes />
</method>
- <method token="0x6000004">
+ <method token="0x6000005">
<sequencepoints>
<entry il="0x0" row="23" col="5" file_ref="1" hidden="false" />
</sequencepoints>
<entry index="1" start="0x0" end="0x2" />
</scopes>
</method>
- <method token="0x6000005">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
<scopes />
</method>
<method token="0x6000003">
- <sequencepoints>
- <entry il="0x0" row="10" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="12" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000004">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="10" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="12" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
</files>
<methods>
<method token="0x6000001">
- <sequencepoints>
- <entry il="0x0" row="4" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="5" col="3" file_ref="1" hidden="false" />
- <entry il="0x7" row="6" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
- <locals />
- <scopes />
- </method>
- <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="10" col="7" file_ref="1" hidden="false" />
<entry il="0x1" row="11" col="4" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="14" col="7" file_ref="1" hidden="false" />
<entry il="0x1" row="15" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000004">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="20" col="3" file_ref="1" hidden="false" />
</sequencepoints>
<locals />
<scopes />
</method>
- <method token="0x6000005">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="21" col="3" file_ref="1" hidden="false" />
</sequencepoints>
<locals />
<scopes />
</method>
- <method token="0x6000006">
+ <method token="0x6000005">
<sequencepoints />
<locals />
<scopes />
</method>
+ <method token="0x6000006">
+ <sequencepoints>
+ <entry il="0x0" row="4" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="5" col="3" file_ref="1" hidden="false" />
+ <entry il="0x7" row="6" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
+ <locals />
+ <scopes />
+ </method>
</methods>
</symbols>
\ No newline at end of file
<scopes />
</method>
<method token="0x6000003">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="20" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="21" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000004">
+ <method token="0x6000005">
<sequencepoints>
<entry il="0x0" row="24" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="25" col="10" file_ref="1" hidden="false" />
<entry index="1" start="0xa" end="0xa" />
</scopes>
</method>
- <method token="0x6000005">
+ <method token="0x6000006">
<sequencepoints>
<entry il="0x0" row="31" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="32" col="10" file_ref="1" hidden="false" />
<entry index="1" start="0x12" end="0x12" />
</scopes>
</method>
- <method token="0x6000006">
+ <method token="0x6000007">
<sequencepoints>
<entry il="0x0" row="38" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="39" col="10" file_ref="1" hidden="false" />
<entry index="1" start="0x11" end="0x11" />
</scopes>
</method>
- <method token="0x6000007">
+ <method token="0x6000008">
<sequencepoints>
<entry il="0x0" row="45" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="46" col="10" file_ref="1" hidden="false" />
<entry index="1" start="0x8" end="0x12" />
</scopes>
</method>
- <method token="0x6000008">
+ <method token="0x6000009">
<sequencepoints>
<entry il="0x0" row="53" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="54" col="3" file_ref="1" hidden="false" />
<entry index="0" start="0xe" end="0xe" />
</scopes>
</method>
- <method token="0x6000009">
+ <method token="0x600000a">
<sequencepoints>
<entry il="0x0" row="60" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="61" col="3" file_ref="1" hidden="false" />
<entry index="0" start="0xe" end="0x13" />
</scopes>
</method>
- <method token="0x600000a">
+ <method token="0x600000b">
<sequencepoints>
<entry il="0x0" row="68" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="70" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x28" end="0x2d" />
</scopes>
</method>
- <method token="0x600000b">
+ <method token="0x600000c">
<sequencepoints>
<entry il="0x0" row="88" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="89" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x2e" end="0x33" />
</scopes>
</method>
- <method token="0x600000c">
+ <method token="0x600000d">
<sequencepoints>
<entry il="0x0" row="103" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="105" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0xb9" end="0xbe" />
</scopes>
</method>
- <method token="0x600000d">
+ <method token="0x600000e">
<sequencepoints>
<entry il="0x0" row="127" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="129" col="3" file_ref="1" hidden="false" />
<entry index="0" start="0x2c" end="0x3b" />
</scopes>
</method>
- <method token="0x600000e">
+ <method token="0x600000f">
<sequencepoints>
<entry il="0x0" row="140" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="142" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x6" end="0x8" />
</scopes>
</method>
- <method token="0x600000f">
+ <method token="0x6000010">
<sequencepoints>
<entry il="0x0" row="153" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="155" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0xf" end="0xf" />
</scopes>
</method>
- <method token="0x6000010">
+ <method token="0x6000011">
<sequencepoints>
<entry il="0x0" row="165" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="167" col="3" file_ref="1" hidden="false" />
<entry index="0" start="0x2" end="0x4" />
</scopes>
</method>
- <method token="0x6000011">
+ <method token="0x6000012">
<sequencepoints>
<entry il="0x0" row="174" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="175" col="3" file_ref="1" hidden="false" />
<entry index="0" start="0x3" end="0xd" />
</scopes>
</method>
- <method token="0x6000012">
+ <method token="0x6000013">
<sequencepoints>
<entry il="0x0" row="182" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="183" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x19" end="0x19" />
</scopes>
</method>
- <method token="0x6000013">
+ <method token="0x6000014">
<sequencepoints>
<entry il="0x0" row="192" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="193" col="3" file_ref="1" hidden="false" />
<entry index="2" start="0x30" end="0x30" />
</scopes>
</method>
- <method token="0x6000014">
+ <method token="0x6000015">
<sequencepoints>
<entry il="0x0" row="205" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="206" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x10" end="0x10" />
</scopes>
</method>
- <method token="0x6000015">
+ <method token="0x6000016">
<sequencepoints>
<entry il="0x0" row="215" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="216" col="8" file_ref="1" hidden="false" />
<entry index="3" start="0x1b" end="0x1b" />
</scopes>
</method>
- <method token="0x6000016">
+ <method token="0x6000017">
<sequencepoints>
<entry il="0x0" row="230" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="231" col="8" file_ref="1" hidden="false" />
<entry index="1" start="0x9" end="0x9" />
</scopes>
</method>
- <method token="0x6000017">
+ <method token="0x6000018">
<sequencepoints>
<entry il="0x0" row="237" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="238" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x10" end="0x10" />
</scopes>
</method>
- <method token="0x6000018">
+ <method token="0x6000019">
<sequencepoints>
<entry il="0x0" row="246" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="247" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x17" end="0x17" />
</scopes>
</method>
- <method token="0x6000019">
+ <method token="0x600001a">
<sequencepoints>
<entry il="0x0" row="256" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="257" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x17" end="0x17" />
</scopes>
</method>
- <method token="0x600001a">
+ <method token="0x600001b">
<sequencepoints>
<entry il="0x0" row="266" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="267" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x30" end="0x30" />
</scopes>
</method>
- <method token="0x600001b">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
</files>
<methods>
<method token="0x6000001">
- <sequencepoints>
- <entry il="0x0" row="7" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="8" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000002">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="7" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="8" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
</files>
<methods>
<method token="0x6000001">
- <sequencepoints>
- <entry il="0x0" row="7" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="9" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000002">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="7" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="9" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
<scopes />
</method>
<method token="0x6000008">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
- <method token="0x6000009">
<sequencepoints>
<entry il="0x21" row="12" col="2" file_ref="1" hidden="false" />
<entry il="0x22" row="13" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
+ <method token="0x6000009">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
<method token="0x600000a">
<sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000010">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
- <method token="0x6000011">
<sequencepoints>
<entry il="0x12" row="17" col="2" file_ref="1" hidden="false" />
<entry il="0x13" row="18" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
+ <method token="0x6000011">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
<method token="0x6000012">
<sequencepoints />
<locals />
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="6" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="7" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="10" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="11" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="17" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="18" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000004">
+ <method token="0x6000005">
<sequencepoints>
<entry il="0x0" row="26" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="27" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000005">
+ <method token="0x6000006">
<sequencepoints>
<entry il="0xd" row="34" col="2" file_ref="1" hidden="false" />
<entry il="0xe" row="35" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000006">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
<method token="0x6000007">
<sequencepoints>
<entry il="0x0" row="13" col="3" file_ref="1" hidden="false" />
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="6" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="7" col="3" file_ref="1" hidden="false" />
<entry index="1" start="0x15" end="0x1b" />
</scopes>
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="11" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="12" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000003">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="10" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="11" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="14" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="15" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="27" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="28" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000004">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="7" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="8" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x2a" row="11" col="2" file_ref="1" hidden="false" />
<entry il="0x2b" row="12" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="20" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="21" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000004">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
<scopes />
</method>
<method token="0x6000003">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="8" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="9" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000004">
+ <method token="0x6000005">
<sequencepoints>
<entry il="0x0" row="12" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="13" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000005">
+ <method token="0x6000006">
<sequencepoints>
<entry il="0x0" row="17" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="18" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000006">
+ <method token="0x6000007">
<sequencepoints>
<entry il="0x0" row="24" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="25" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000007">
+ <method token="0x6000008">
<sequencepoints>
<entry il="0x0" row="30" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="31" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000008">
+ <method token="0x6000009">
<sequencepoints>
<entry il="0x0" row="38" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="39" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000009">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
<method token="0x600000a">
<sequencepoints>
<entry il="0x0" row="40" col="38" file_ref="1" hidden="false" />
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="7" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="8" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints />
<locals />
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="16" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="17" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000004">
+ <method token="0x6000005">
<sequencepoints />
<locals />
<scopes />
</method>
- <method token="0x6000005">
+ <method token="0x6000006">
<sequencepoints>
<entry il="0x0" row="29" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="30" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000006">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
<method token="0x6000007">
<sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000002">
- <sequencepoints>
- <entry il="0x0" row="17" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="18" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000003">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="17" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="18" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
<scopes />
</method>
<method token="0x6000002">
- <sequencepoints>
- <entry il="0x0" row="22" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="23" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000003">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="22" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="23" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
<scopes />
</method>
<method token="0x6000007">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
- <method token="0x6000008">
<sequencepoints>
<entry il="0x27" row="7" col="2" file_ref="1" hidden="false" />
<entry il="0x28" row="8" col="3" file_ref="1" hidden="false" />
<entry index="0" start="0x42" end="0x5f" />
</scopes>
</method>
+ <method token="0x6000008">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
<method token="0x6000009">
<sequencepoints />
<locals />
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="7" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="8" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints />
<locals />
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints />
<locals />
<scopes />
</method>
- <method token="0x6000004">
+ <method token="0x6000005">
<sequencepoints>
<entry il="0x0" row="20" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="21" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000005">
+ <method token="0x6000006">
<sequencepoints>
<entry il="0x0" row="25" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="26" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000006">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
<method token="0x6000007">
<sequencepoints />
<locals />
<scopes />
</method>
<method token="0x600000b">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
- <method token="0x600000c">
<sequencepoints>
<entry il="0x21" row="15" col="2" file_ref="1" hidden="false" />
<entry il="0x22" row="16" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
+ <method token="0x600000c">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
<method token="0x600000d">
<sequencepoints />
<locals />
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints>
+ <entry il="0x0" row="39" col="7" file_ref="1" hidden="false" />
+ <entry il="0x1" row="40" col="4" file_ref="1" hidden="false" />
+ <entry il="0x8" row="41" col="3" file_ref="1" hidden="false" />
+ </sequencepoints>
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="8" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="9" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="13" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="14" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000003">
+ <method token="0x6000005">
<sequencepoints>
<entry il="0x0" row="18" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="19" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000004">
+ <method token="0x6000006">
<sequencepoints>
<entry il="0x0" row="23" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="24" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000005">
+ <method token="0x6000007">
<sequencepoints>
<entry il="0x0" row="29" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="30" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000006">
+ <method token="0x6000008">
<sequencepoints>
<entry il="0x0" row="34" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="35" col="3" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000007">
- <sequencepoints>
- <entry il="0x0" row="39" col="7" file_ref="1" hidden="false" />
- <entry il="0x1" row="40" col="4" file_ref="1" hidden="false" />
- <entry il="0x8" row="41" col="3" file_ref="1" hidden="false" />
- </sequencepoints>
- <locals />
- <scopes />
- </method>
- <method token="0x6000008">
+ <method token="0x6000009">
<sequencepoints>
<entry il="0x0" row="45" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="46" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000009">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
<method token="0x600000a">
<sequencepoints>
<entry il="0x0" row="24" col="27" file_ref="1" hidden="false" />
</files>
<methods>
<method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
<sequencepoints>
<entry il="0x0" row="6" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="7" col="3" file_ref="1" hidden="false" />
</locals>
<scopes />
</method>
- <method token="0x6000002">
+ <method token="0x6000003">
<sequencepoints>
<entry il="0x0" row="11" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="12" col="8" file_ref="1" hidden="false" />
<entry index="1" start="0x9" end="0x9" />
</scopes>
</method>
- <method token="0x6000003">
+ <method token="0x6000004">
<sequencepoints>
<entry il="0x0" row="16" col="2" file_ref="1" hidden="false" />
<entry il="0x1" row="17" col="2" file_ref="1" hidden="false" />
<locals />
<scopes />
</method>
- <method token="0x6000004">
- <sequencepoints />
- <locals />
- <scopes />
- </method>
</methods>
</symbols>
\ No newline at end of file
</files>
<methods>
<method token="0x6000001">
- <sequencepoints>
- <entry il="0x0" row="6" col="2" file_ref="1" hidden="false" />
- <entry il="0x1" row="7" col="2" file_ref="1" hidden="false" />
- </sequencepoints>
+ <sequencepoints />
<locals />
<scopes />
</method>
<method token="0x6000002">
- <sequencepoints />
+ <sequencepoints>
+ <entry il="0x0" row="6" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="7" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
<locals />
<scopes />
</method>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<symbols>
+ <files>
+ <file id="1" name="test-debug-26.cs" checksum="9517379bedd3abcc97156ab28d9cb3da" />
+ </files>
+ <methods>
+ <method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
+ <sequencepoints>
+ <entry il="0x0" row="9" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="10" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000003">
+ <sequencepoints>
+ <entry il="0x0" row="13" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="14" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
+ <locals />
+ <scopes />
+ </method>
+ </methods>
+</symbols>
\ No newline at end of file
--- /dev/null
+partial class P
+{
+ partial void Foo ();
+}
+
+partial class P
+{
+ partial void Foo ()
+ {
+ }
+
+ public static void Main ()
+ {
+ }
+}
\ No newline at end of file
</method>\r
</type>\r
</test>\r
+ <test name="gtest-exmethod-46.cs">\r
+ <type name="ExtensionTest.Two.AxFunc`2[T1,TResult]">\r
+ <method name="TResult Invoke(T1)" attrs="454">\r
+ <size>0</size>\r
+ </method>\r
+ <method name="IAsyncResult BeginInvoke(T1, System.AsyncCallback, System.Object)" attrs="454">\r
+ <size>0</size>\r
+ </method>\r
+ <method name="TResult EndInvoke(IAsyncResult)" attrs="454">\r
+ <size>0</size>\r
+ </method>\r
+ <method name="Void .ctor(Object, IntPtr)" attrs="6278">\r
+ <size>0</size>\r
+ </method>\r
+ </type>\r
+ <type name="ExtensionTest.Two.Extensions">\r
+ <method name="Boolean Contains[T](IEnumerable`1, T)" attrs="150">\r
+ <size>10</size>\r
+ </method>\r
+ <method name="Boolean All[T](IEnumerable`1, ExtensionTest.Two.AxFunc`2[T,System.Boolean])" attrs="150">\r
+ <size>10</size>\r
+ </method>\r
+ </type>\r
+ <type name="ExtensionTest.MyClass">\r
+ <method name="Boolean IsCharacters(System.String, System.Char[])" attrs="150">\r
+ <size>27</size>\r
+ </method>\r
+ <method name="Boolean Contains(System.String, System.String, StringComparison)" attrs="150">\r
+ <size>23</size>\r
+ </method>\r
+ <method name="Void Main()" attrs="150">\r
+ <size>2</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="gtest-fixedbuffer-01.cs">\r
<type name="TestNew">\r
<method name="Void SetTest()" attrs="134">\r
</method>\r
</type>\r
</test>\r
+ <test name="gtest-partial-06.cs">\r
+ <type name="Test">\r
+ <method name="Void Baz[U]()" attrs="145">\r
+ <size>2</size>\r
+ </method>\r
+ <method name="Void Bar[U](U)" attrs="145">\r
+ <size>2</size>\r
+ </method>\r
+ <method name="Void Main()" attrs="150">\r
+ <size>13</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="gtest-var-04.cs">\r
<type name="Test">\r
<method name="Int32 Main()" attrs="150">\r
</method>\r
</type>\r
</test>\r
+ <test name="test-867.cs">\r
+ <type name="Test">\r
+ <method name="Void Main()" attrs="150">\r
+ <size>14</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="User">\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="BaseController">\r
+ <method name="IUser get_User()" attrs="2502">\r
+ <size>14</size>\r
+ </method>\r
+ <method name="Void set_User(IUser)" attrs="2502">\r
+ <size>8</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="BaseJobController">\r
+ <method name="User get_User()" attrs="2182">\r
+ <size>14</size>\r
+ </method>\r
+ <method name="Void set_User(User)" attrs="2182">\r
+ <size>8</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="JobController">\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="test-87.cs">\r
<type name="Top">\r
<method name="Int32 Main()" attrs="150">\r
</method>\r
</type>\r
</test>\r
+ <test name="test-debug-26.cs">\r
+ <type name="P">\r
+ <method name="Void Foo()" attrs="129">\r
+ <size>2</size>\r
+ </method>\r
+ <method name="Void Main()" attrs="150">\r
+ <size>2</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="test-externalias-01.cs">\r
<type name="Test">\r
<method name="Int32 Main()" attrs="150">\r
// Preallocate the strings we need.
if (chars [0] == null) {
for (int i = 0; i < chars.Length; i++)
- chars [i] = string.Format ("\t.byte {0}\n", i.ToString ());
+ chars [i] = string.Format ("{0}", i.ToString ());
}
while ((n = stream.Read (buffer, 0, buffer.Length)) != 0) {
- for (int i = 0; i < n; i++)
+ int count = 0;
+ for (int i = 0; i < n; i++) {
+ if (count % 32 == 0) {
+ ts.Write ("\n\t.byte ");
+ } else {
+ ts.Write (",");
+ }
ts.Write (chars [buffer [i]]);
+ count ++;
+ }
}
ts.WriteLine ();
object monitor = new object ();
+ var streams = new Dictionary<string, Stream> ();
+ var sizes = new Dictionary<string, long> ();
+
// Do the file reading and compression in parallel
Action<string> body = delegate (string url) {
string fname = new Uri (url).LocalPath;
- string aname = Path.GetFileName (fname);
- string encoded = aname.Replace ("-", "_").Replace (".", "_");
-
- if (prog == null)
- prog = aname;
-
Stream stream = File.OpenRead (fname);
long real_size = stream.Length;
stream = new MemoryStream (bytes, 0, (int) ms.Length, false, false);
}
- // The non-parallel part
lock (monitor) {
- Console.WriteLine (" embedding: " + fname);
-
- WriteSymbol (ts, "assembly_data_" + encoded, stream.Length);
-
- WriteBuffer (ts, stream, buffer);
-
- if (compress) {
- tc.WriteLine ("extern const unsigned char assembly_data_{0} [];", encoded);
- tc.WriteLine ("static CompressedAssembly assembly_bundle_{0} = {{{{\"{1}\"," +
- " assembly_data_{0}, {2}}}, {3}}};",
- encoded, aname, real_size, stream.Length);
- double ratio = ((double) stream.Length * 100) / real_size;
- Console.WriteLine (" compression ratio: {0:.00}%", ratio);
- } else {
- tc.WriteLine ("extern const unsigned char assembly_data_{0} [];", encoded);
- tc.WriteLine ("static const MonoBundledAssembly assembly_bundle_{0} = {{\"{1}\", assembly_data_{0}, {2}}};",
- encoded, aname, real_size);
- }
- stream.Close ();
-
- c_bundle_names.Add ("assembly_bundle_" + encoded);
-
- try {
- FileStream cf = File.OpenRead (fname + ".config");
- Console.WriteLine (" config from: " + fname + ".config");
- tc.WriteLine ("extern const unsigned char assembly_config_{0} [];", encoded);
- WriteSymbol (ts, "assembly_config_" + encoded, cf.Length);
- WriteBuffer (ts, cf, buffer);
- ts.WriteLine ();
- config_names.Add (new string[] {aname, encoded});
- } catch (FileNotFoundException) {
- /* we ignore if the config file doesn't exist */
- }
+ streams [url] = stream;
+ sizes [url] = real_size;
}
};
body (url);
#endif
+ // The non-parallel part
+ foreach (var url in files) {
+ string fname = new Uri (url).LocalPath;
+ string aname = Path.GetFileName (fname);
+ string encoded = aname.Replace ("-", "_").Replace (".", "_");
+
+ if (prog == null)
+ prog = aname;
+
+ var stream = streams [url];
+ var real_size = sizes [url];
+
+ Console.WriteLine (" embedding: " + fname);
+
+ WriteSymbol (ts, "assembly_data_" + encoded, stream.Length);
+
+ WriteBuffer (ts, stream, buffer);
+
+ if (compress) {
+ tc.WriteLine ("extern const unsigned char assembly_data_{0} [];", encoded);
+ tc.WriteLine ("static CompressedAssembly assembly_bundle_{0} = {{{{\"{1}\"," +
+ " assembly_data_{0}, {2}}}, {3}}};",
+ encoded, aname, real_size, stream.Length);
+ double ratio = ((double) stream.Length * 100) / real_size;
+ Console.WriteLine (" compression ratio: {0:.00}%", ratio);
+ } else {
+ tc.WriteLine ("extern const unsigned char assembly_data_{0} [];", encoded);
+ tc.WriteLine ("static const MonoBundledAssembly assembly_bundle_{0} = {{\"{1}\", assembly_data_{0}, {2}}};",
+ encoded, aname, real_size);
+ }
+ stream.Close ();
+
+ c_bundle_names.Add ("assembly_bundle_" + encoded);
+
+ try {
+ FileStream cf = File.OpenRead (fname + ".config");
+ Console.WriteLine (" config from: " + fname + ".config");
+ tc.WriteLine ("extern const unsigned char assembly_config_{0} [];", encoded);
+ WriteSymbol (ts, "assembly_config_" + encoded, cf.Length);
+ WriteBuffer (ts, cf, buffer);
+ ts.WriteLine ();
+ config_names.Add (new string[] {aname, encoded});
+ } catch (FileNotFoundException) {
+ /* we ignore if the config file doesn't exist */
+ }
+ }
+
if (config_file != null){
FileStream conf;
try {
-DIST_SUBDIRS = x86 ppc sparc arm s390 s390x amd64 ia64 mips
+DIST_SUBDIRS = x86 ppc sparc arm s390x amd64 ia64 mips
AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)
+++ /dev/null
-/Makefile.in
-/Makefile
-/.deps
-/.cvsignore
+++ /dev/null
-2007-04-12 Neale Ferguson <neale@sinenomine.net>
-
- * tramp.c: Add MONO_TYPE_PTR case.
-
-2005-12-13 Neale Ferguson <neale@sinenomine.net>
-
- * s390-codegen.h: Add some new instructions (conditional jumps)
-
-2004-12-15 Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
-
- * s390-codegen.h: Add some new instructions (CS, CDS)
-
-2004-11-15 Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
-
- * s390-codegen.h: Minor macro modifications
-
-2004-07-30 Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
-
- * s390-codegen.h: reworked macros for code generation.
+++ /dev/null
-
-AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)
-
-noinst_LTLIBRARIES = libmonoarch-s390.la
-
-libmonoarch_s390_la_SOURCES = tramp.c s390-codegen.h
-
+++ /dev/null
-/*
- Copyright (C) 2001 Radek Doulik
-*/
-
-#ifndef S390_H
-#define S390_H
-#include <glib.h>
-#include <assert.h>
-
-#define FLOAT_REGS 2 /* No. float registers for parms */
-#define GENERAL_REGS 5 /* No. general registers for parms */
-
-#define ARG_BASE s390_r10 /* Register for addressing arguments*/
-#define STKARG \
- (i*(sizeof(stackval))) /* Displacement of ith argument */
-
-#define MINV_POS 96 /* MonoInvocation stack offset */
-#define STACK_POS (MINV_POS - sizeof (stackval) * sig->param_count)
-#define OBJ_POS 8
-#define TYPE_OFFSET (G_STRUCT_OFFSET (stackval, type))
-
-#define MIN_CACHE_LINE 256
-
-/*------------------------------------------------------------------*/
-/* Sequence to add an int/long long to parameters to stack_from_data*/
-/*------------------------------------------------------------------*/
-#define ADD_ISTACK_PARM(r, i) \
- if (reg_param < GENERAL_REGS-(r)) { \
- s390_la (p, s390_r4, 0, STK_BASE, \
- local_start + (reg_param - this_flag) * sizeof(long)); \
- reg_param += (i); \
- } else { \
- s390_la (p, s390_r4, 0, STK_BASE, \
- sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
- stack_param += (i); \
- }
-
-/*------------------------------------------------------------------*/
-/* Sequence to add a float/double to parameters to stack_from_data */
-/*------------------------------------------------------------------*/
-#define ADD_RSTACK_PARM(i) \
- if (fpr_param < FLOAT_REGS) { \
- s390_la (p, s390_r4, 0, STK_BASE, \
- float_pos + (fpr_param * sizeof(float) * (i))); \
- fpr_param++; \
- } else { \
- stack_param += (stack_param % (i)); \
- s390_la (p, s390_r4, 0, STK_BASE, \
- sz.stack_size + MINV_POS + stack_param * sizeof(float) * (i)); \
- stack_param += (i); \
- }
-
-/*------------------------------------------------------------------*/
-/* Sequence to add a structure ptr to parameters to stack_from_data */
-/*------------------------------------------------------------------*/
-#define ADD_TSTACK_PARM \
- if (reg_param < GENERAL_REGS) { \
- s390_l (p, s390_r4, 0, STK_BASE, \
- local_start + (reg_param - this_flag) * sizeof(long)); \
- reg_param++; \
- } else { \
- s390_l (p, s390_r4, 0, STK_BASE, \
- sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
- stack_param++; \
- }
-
-#define ADD_PSTACK_PARM(r, i) \
- if (reg_param < GENERAL_REGS-(r)) { \
- s390_la (p, s390_r4, 0, STK_BASE, \
- local_start + (reg_param - this_flag) * sizeof(long)); \
- reg_param += (i); \
- } else { \
- s390_l (p, s390_r4, 0, STK_BASE, \
- sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
- stack_param++; \
- }
-typedef enum {
- s390_r0 = 0,
- s390_r1,
- s390_r2,
- s390_r3,
- s390_r4,
- s390_r5,
- s390_r6,
- s390_r7,
- s390_r8,
- s390_r9,
- s390_r10,
- s390_r11,
- s390_r12,
- s390_r13,
- s390_r14,
- s390_r15,
-} S390IntRegister;
-
-typedef enum {
- s390_f0 = 0,
- s390_f1,
- s390_f2,
- s390_f3,
- s390_f4,
- s390_f5,
- s390_f6,
- s390_f7,
- s390_f8,
- s390_f9,
- s390_f10,
- s390_f11,
- s390_f12,
- s390_f13,
- s390_f14,
- s390_f15,
-} S390FloatRegister;
-
-typedef enum {
- s390_a0 = 0,
- s390_a1,
- s390_a2,
- s390_a3,
- s390_a4,
- s390_a5,
- s390_a6,
- s390_a7,
- s390_a8,
- s390_a9,
- s390_a10,
- s390_a11,
- s390_a12,
- s390_a13,
- s390_a14,
- s390_a15,
-} S390AccRegister;
-
-typedef enum {
- s390_fpc = 256,
-} S390SpecialRegister;
-
-#define s390_is_imm16(val) ((gint)val >= (gint)-(1<<15) && \
- (gint)val <= (gint)((1<<15)-1))
-#define s390_is_uimm16(val) ((gint)val >= 0 && (gint)val <= 32767)
-#define s390_is_imm12(val) ((gint)val >= (gint)-(1<<11) && \
- (gint)val <= (gint)((1<<11)-1))
-#define s390_is_uimm12(val) ((gint)val >= 0 && (gint)val <= 4095)
-
-#define STK_BASE s390_r15
-#define S390_MINIMAL_STACK_SIZE 96
-#define S390_PARM_SAVE_OFFSET 8
-#define S390_REG_SAVE_OFFSET 24
-#define S390_RET_ADDR_OFFSET 56
-#define S390_FLOAT_SAVE_OFFSET 64
-
-#define S390_CC_ZR 8
-#define S390_CC_NE 7
-#define S390_CC_NZ 7
-#define S390_CC_LT 4
-#define S390_CC_GT 2
-#define S390_CC_GE 11
-#define S390_CC_NM 11
-#define S390_CC_LE 13
-#define S390_CC_OV 1
-#define S390_CC_NO 14
-#define S390_CC_CY 3
-#define S390_CC_NC 12
-#define S390_CC_UN 15
-
-#define s390_word(addr, value) do \
-{ \
- * (guint32 *) addr = (guint32) value; \
- addr += sizeof(guint32); \
-} while (0)
-
-#define s390_float(addr, value) do \
-{ \
- * (gfloat *) addr = (gfloat) value; \
- addr += sizeof(gfloat); \
-} while (0)
-
-#define s390_llong(addr, value) do \
-{ \
- * (guint64 *) addr = (guint64) value; \
- addr += sizeof(guint64); \
-} while (0)
-
-#define s390_double(addr, value) do \
-{ \
- * (gdouble *) addr = (gdouble) value; \
- addr += sizeof(gdouble); \
-} while (0)
-
-typedef struct {
- short op;
-} E_Format;
-
-typedef struct {
- char op;
- int im;
-} I_Format;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r2 : 4;
-} RR_Format;
-
-typedef struct {
- short op;
- char xx;
- char r1 : 4;
- char r2 : 4;
-} RRE_Format;
-
-typedef struct {
- short op;
- char r1 : 4;
- char xx : 4;
- char r3 : 4;
- char r2 : 4;
-} RRF_Format_1;
-
-typedef struct {
- short op;
- char m3 : 4;
- char xx : 4;
- char r1 : 4;
- char r2 : 4;
-} RRF_Format_2;
-
-typedef struct {
- short op;
- char r3 : 4;
- char m4 : 4;
- char r1 : 4;
- char r2 : 4;
-} RRF_Format_3;
-
-typedef struct {
- char op;
- char r1 : 4;
- char x2 : 4;
- char b2 : 4;
- short d2 : 12;
-} RX_Format;
-
-typedef struct {
- char op1;
- char r1 : 4;
- char x2 : 4;
- char b2 : 4;
- int d2 : 12;
- char xx;
- char op2;
-} RXE_Format;
-
-typedef struct {
- char op1;
- char r3 : 4;
- char x2 : 4;
- char b2 : 4;
- int d2 : 12;
- char r1 : 4;
- char xx : 4;
- char op2;
-} RXF_Format;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char r1 : 4;
- char x2 : 4;
- char b2 : 4;
- int d2 : 20;
- char op2;
-} RXY_Format;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r3 : 4;
- char b2 : 4;
- int d2 : 12;
-} RS_Format_1;
-
-typedef struct {
- char op;
- char r1 : 4;
- char m3 : 4;
- char b2 : 4;
- int d2 : 12;
-} RS_Format_2;
-
-typedef struct {
- char op;
- char r1 : 4;
- char xx : 4;
- char b2 : 4;
- int d2 : 12;
-} RS_Format_3;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char r1 : 4;
- char r3 : 4;
- char b2 : 4;
- int d2 : 20;
- char op2;
-} RSY_Format_1;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char r1 : 4;
- char m3 : 4;
- char b2 : 4;
- int d2 : 20;
- char op2;
-} RSY_Format_2;
-
-typedef struct {
- char op1;
- char l1 : 4;
- char xx : 4;
- char b1 : 4;
- int d1 : 12;
- char yy;
- char op2;
-} RSL_Format;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r3 : 4;
- short i2;
-} RSI_Format;
-
-typedef struct {
- char op1;
- char r1 : 4;
- char op2 : 4;
- short i2;
-} RI_Format;
-
-typedef struct {
- char op1;
- char r1 : 4;
- char r3 : 4;
- short i2;
- char xx;
- char op2;
-} RIE_Format;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char r1 : 4;
- char op2 : 4;
- int i2;
-} RIL_Format_1;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char m1 : 4;
- char op2 : 4;
- int i2;
-} RIL_Format_2;
-
-typedef struct {
- char op;
- char i2;
- char b1 : 4;
- short d1 : 12;
-} SI_Format;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char i2;
- char b1 : 4;
- int d1 : 20;
- char op2;
-} SIY_Format;
-
-typedef struct {
- short op;
- char b2 : 4;
- short d2 : 12;
-} S_Format;
-
-typedef struct {
- char op;
- char ll;
- char b1 : 4;
- short d1 : 12;
- char b2 : 4;
- short d2 : 12;
-} SS_Format_1;
-
-typedef struct {
- char op;
- char l1 : 4;
- char l2 : 4;
- char b1 : 4;
- short d1 : 12;
- char b2 : 4;
- short d2 : 12;
-} SS_Format_2;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r3 : 4;
- char b1 : 4;
- short d1 : 12;
- char b2 : 4;
- short d2 : 12;
-} SS_Format_3;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r3 : 4;
- char b2 : 4;
- short d2 : 12;
- char b4 : 4;
- short d4 : 12;
-} SS_Format_4;
-
-typedef struct __attribute__ ((packed)) {
- short op;
- char b1 : 4;
- short d1 : 12;
- char b2 : 4;
- short d2 : 12;
-} SSE_Format;
-
-#define s390_emit16(c, x) do \
-{ \
- *((guint16 *) c) = x; \
- c += sizeof(guint16); \
-} while(0)
-
-#define s390_emit32(c, x) do \
-{ \
- *((guint32 *) c) = x; \
- c += sizeof(guint32); \
-} while(0)
-
-#define S390_E(c,opc) s390_emit16(c,opc)
-
-#define S390_I(c,opc,imm) s390_emit16(c, (opc << 8 | imm))
-
-#define S390_RR(c,opc,g1,g2) s390_emit16(c, (opc << 8 | (g1) << 4 | g2))
-
-#define S390_RRE(c,opc,g1,g2) s390_emit32(c, (opc << 16 | (g1) << 4 | g2))
-
-#define S390_RRF_1(c,opc,g1,g2,g3) s390_emit32(c, (opc << 16 | (g1) << 12 | (g3) << 4 | g2))
-
-#define S390_RRF_2(c,opc,g1,k3,g2) s390_emit32(c, (opc << 16 | (k3) << 12 | (g1) << 4 | g2))
-
-#define S390_RRF_3(c,opc,g1,g2,k4,g3) s390_emit32(c, (opc << 16 | (g3) << 12 | (k4) << 8 | (g1) << 4 | g2))
-
-#define S390_RX(c,opc,g1,n2,s2,p2) s390_emit32(c, (opc << 24 | (g1) << 20 | (n2) << 16 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_RXE(c,opc,g1,n2,s2,p2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | n2)); \
- s390_emit32(c, ((s2) << 28 | (((p2) & 0xfff) << 16) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RXY(c,opc,g1,n2,s2,p2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | n2)); \
- s390_emit32(c, ((s2) << 28 | (((p2) & 0xfffff) << 8) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RS_1(c,opc,g1,g3,s2,p2) s390_emit32(c, (opc << 24 | (g1) << 20 | (g3) << 16 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_RS_2(c,opc,g1,k3,s2,p2) s390_emit32(c, (opc << 24 | (g1) << 20 | (k3) << 16 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_RS_3(c,opc,g1,s2,p2) s390_emit32(c, (opc << 24 | (g1) << 20 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_RSY_1(c,opc,g1,g3,s2,p2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | g3)); \
- s390_emit32(c, ((s2) << 28 | (((p2) & 0xfffff) << 8) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RSY_2(c,opc,g1,k3,s2,p2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | k3)); \
- s390_emit32(c, ((s2) << 28 | (((p2) & 0xfffff) << 8) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RSL(c,opc,ln,s1,p1) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (ln) << 4)); \
- s390_emit32(c, ((s1) << 28 | ((s1 & 0xfff) << 16) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RSI(c,opc,g1,g3,m2) s390_emit32(c, (opc << 24 | (g1) << 20 | (g3) << 16 | (m2 & 0xffff)))
-
-#define S390_RI(c,opc,g1,m2) s390_emit32(c, ((opc >> 4) << 24 | (g1) << 20 | (opc & 0x0f) << 16 | (m2 & 0xffff)))
-
-#define S390_RIE(c,opc,g1,g3,m2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | g3)); \
- s390_emit32(c, ((m2) << 16 | (opc & 0xff))); \
-} while (0)
-
-#define S390_RIL_1(c,opc,g1,m2) do \
-{ \
- s390_emit16(c, ((opc >> 4) << 8 | (g1) << 4 | (opc & 0xf))); \
- s390_emit32(c, m2); \
-} while (0)
-
-#define S390_RIL_2(c,opc,k1,m2) do \
-{ \
- s390_emit16(c, ((opc >> 4) << 8 | (k1) << 4 | (opc & 0xf))); \
- s390_emit32(c, m2); \
-} while (0)
-
-#define S390_SI(c,opc,s1,p1,m2) s390_emit32(c, (opc << 24 | (m2) << 16 | (s1) << 12 | ((p1) & 0xfff)));
-
-#define S390_SIY(c,opc,s1,p1,m2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | m2)); \
- s390_emit32(c, ((s1) << 24 | (((p2) & 0xfffff) << 8) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_S(c,opc,s2,p2) s390_emit32(c, (opc << 16 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_SS_1(c,opc,ln,s1,p1,s2,p2) do \
-{ \
- s390_emit32(c, (opc << 24 | ((ln-1) & 0xff) << 16 | \
- (s1) << 12 | ((p1) & 0xfff))); \
- s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
-} while (0)
-
-#define S390_SS_2(c,opc,n1,n2,s1,p1,s2,p2) do \
-{ \
- s390_emit32(c, (opc << 24 | (n1) << 16 | (n2) << 12 | \
- (s1) << 12 | ((p1) & 0xfff))); \
- s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
-} while (0)
-
-#define S390_SS_3(c,opc,g1,g3,s1,p1,s2,p2) do \
-{ \
- s390_emit32(c, (opc << 24 | (g1) << 16 | (g3) << 12 | \
- (s1) << 12 | ((p1) & 0xfff))); \
- s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
-} while (0)
-
-#define S390_SS_4(c,opc,g1,g3,s2,p2,s4,p4) do \
-{ \
- s390_emit32(c, (opc << 24 | (g1) << 16 | (g3) << 12 | \
- (s2) << 12 | ((p2) & 0xfff))); \
- s390_emit16(c, ((s4) << 12 | ((p4) & 0xfff))); \
-} while (0)
-
-#define S390_SSE(c,opc,s1,p1,s2,p2) do \
-{ \
- s390_emit16(c, opc); \
- s390_emit16(c, ((s1) << 12 | ((p1) & 0xfff))); \
- s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
-} while (0)
-
-#define s390_a(c, r, x, b, d) S390_RX(c, 0x5a, r, x, b, d)
-#define s390_adb(c, r, x, b, d) S390_RXE(c, 0xed1a, r, x, b, d)
-#define s390_adbr(c, r1, r2) S390_RRE(c, 0xb31a, r1, r2)
-#define s390_aebr(c, r1, r2) S390_RRE(c, 0xb30a, r1, r2)
-#define s390_ahi(c, r, v) S390_RI(c, 0xa7a, r, v)
-#define s390_alc(c, r, x, b, d) S390_RXY(c, 0xe398, r, x, b, d)
-#define s390_alcr(c, r1, r2) S390_RRE(c, 0xb998, r1, r2)
-#define s390_al(c, r, x, b, d) S390_RX(c, 0x5e, r, x, b, d)
-#define s390_alr(c, r1, r2) S390_RR(c, 0x1e, r1, r2)
-#define s390_ar(c, r1, r2) S390_RR(c, 0x1a, r1, r2)
-#define s390_basr(c, r1, r2) S390_RR(c, 0x0d, r1, r2)
-#define s390_bctr(c, r1, r2) S390_RR(c, 0x06, r1, r2)
-#define s390_bras(c, r, o) S390_RI(c, 0xa75, r, o)
-#define s390_brasl(c, r, o) S390_RIL_1(c, 0xc05, r, o)
-#define s390_brc(c, m, d) S390_RI(c, 0xa74, m, d)
-#define s390_br(c, r) S390_RR(c, 0x07, 0xf, r)
-#define s390_break(c) S390_RR(c, 0, 0, 0)
-#define s390_c(c, r, x, b, d) S390_RX(c, 0x59, r, x, b, d)
-#define s390_cdb(c, r, x, b, d) S390_RXE(c, 0xed19, r, x, b, d)
-#define s390_cdbr(c, r1, r2) S390_RRE(c, 0xb319, r1, r2)
-#define s390_cdfbr(c, r1, r2) S390_RRE(c, 0xb395, r1, r2)
-#define s390_cds(c, r1, r2, b, d) S390_RX(c, 0xbb, r1, r2, b, d)
-#define s390_cebr(c, r1, r2) S390_RRE(c, 0xb309, r1, r2)
-#define s390_cfdbr(c, r1, m, r2) S390_RRF_2(c, 0xb399, r1, m, r2)
-#define s390_chi(c, r, i) S390_RI(c, 0xa7e, r, i)
-#define s390_cl(c, r, x, b, d) S390_RX(c, 0x55, r, x, b, d)
-#define s390_clr(c, r1, r2) S390_RR(c, 0x15, r1, r2)
-#define s390_cr(c, r1, r2) S390_RR(c, 0x19, r1, r2)
-#define s390_cs(c, r1, r2, b, d) S390_RX(c, 0xba, r1, r2, b, d)
-#define s390_ddbr(c, r1, r2) S390_RRE(c, 0xb31d, r1, r2)
-#define s390_debr(c, r1, r2) S390_RRE(c, 0xb30d, r1, r2)
-#define s390_didbr(c, r1, r2, m, r3) S390_RRF_3(c, 0xb35b, r1, r2, m, r3)
-#define s390_dlr(c, r1, r2) S390_RRE(c, 0xb997, r1, r2)
-#define s390_dr(c, r1, r2) S390_RR(c, 0x1d, r1, r2)
-#define s390_ear(c, r1, r2) S390_RRE(c, 0xb24f, r1, r2)
-#define s390_ic(c, r, x, b, d) S390_RX(c, 0x43, r, x, b, d)
-#define s390_icm(c, r, m, b, d) S390_RX(c, 0xbf, r, m, b, d)
-#define s390_jc(c, m, d) s390_brc(c, m, d)
-#define s390_j(c,d) s390_brc(c, S390_CC_UN, d)
-#define s390_jcl(c, m, d) S390_RIL_2(c, 0xc04, m, d)
-#define s390_je(c, d) s390_brc(c, S390_CC_EQ, d)
-#define s390_jeo(c, d) s390_brc(c, S390_CC_ZR|S390_CC_OV, d)
-#define s390_jh(c, d) s390_brc(c, S390_CC_GT, d)
-#define s390_jho(c, d) s390_brc(c, S390_CC_GT|S390_CC_OV, d)
-#define s390_jl(c, d) s390_brc(c, S390_CC_LT, d)
-#define s390_jlo(c, d) s390_brc(c, S390_CC_LT|S390_CC_OV, d)
-#define s390_jm(c, d) s390_brc(c, S390_CC_LT, d)
-#define s390_jne(c, d) s390_brc(c, S390_CC_NZ, d)
-#define s390_jnh(c, d) s390_brc(c, S390_CC_LE, d)
-#define s390_jnl(c, d) s390_brc(c, S390_CC_GE, d)
-#define s390_jnz(c, d) s390_brc(c, S390_CC_NZ, d)
-#define s390_jo(c, d) s390_brc(c, S390_CC_OV, d)
-#define s390_jno(c, d) s390_brc(c, S390_CC_NO, d)
-#define s390_jp(c, d) s390_brc(c, S390_CC_GT, d)
-#define s390_jz(c, d) s390_brc(c, S390_CC_ZR, d)
-#define s390_jcy(c, d) s390_brc(c, S390_CC_CY, d)
-#define s390_jnc(c, d) s390_brc(c, S390_CC_NC, d)
-#define s390_la(c, r, x, b, d) S390_RX(c, 0x41, r, x, b, d)
-#define s390_lam(c, r1, r2, b, d) S390_RS_1(c, 0x9a, r1, r2, b, d)
-#define s390_larl(c, r, o) S390_RIL_1(c, 0xc00, r, o)
-#define s390_lcdbr(c, r1, r2) S390_RRE(c, 0xb313, r1, r2)
-#define s390_lcr(c, r1, r2) S390_RR(c, 0x13, r1, r2)
-#define s390_l(c, r, x, b, d) S390_RX(c, 0x58, r, x, b, d)
-#define s390_ld(c, f, x, b, d) S390_RX(c, 0x68, f, x, b, d)
-#define s390_ldeb(c, r, x, b, d) S390_RXE(c, 0xed04, r, x, b, d)
-#define s390_ldebr(c, r1, r2) S390_RRE(c, 0xb304, r1, r2)
-#define s390_ldr(c, r1, r2) S390_RR(c, 0x28, r1, r2)
-#define s390_le(c, f, x, b, d) S390_RX(c, 0x78, f, x, b, d)
-#define s390_ledbr(c, r1, r2) S390_RRE(c, 0xb344, r1, r2)
-#define s390_ler(c, r1, r2) S390_RR(c, 0x38, r1, r2)
-#define s390_lh(c, r, x, b, d) S390_RX(c, 0x48, r, x, b, d)
-#define s390_lhi(c, r, v) S390_RI(c, 0xa78, r, v)
-#define s390_lm(c, r1, r2, b, d) S390_RS_1(c, 0x98, r1, r2, b, d)
-#define s390_lndbr(c, r1, r2) S390_RRE(c, 0xb311, r1, r2)
-#define s390_lnr(c, r1, r2) S390_RR(c, 0x11, r1, r2)
-#define s390_lpr(c, r1, r2) S390_RR(c, 0x10, r1, r2)
-#define s390_lr(c, r1, r2) S390_RR(c, 0x18, r1, r2)
-#define s390_ltr(c, r1, r2) S390_RR(c, 0x12, r1, r2)
-#define s390_lzdr(c, r) S390_RRE(c, 0xb375, r, 0)
-#define s390_lzer(c, r) S390_RRE(c, 0xb374, r, 0)
-#define s390_m(c, r, x, b, d) S390_RX(c, 0x5c, r, x, b, d)
-#define s390_mdbr(c, r1, r2) S390_RRE(c, 0xb31c, r1, r2)
-#define s390_meebr(c, r1, r2) S390_RRE(c, 0xb317, r1, r2)
-#define s390_mlr(c, r1, r2) S390_RRE(c, 0xb996, r1, r2)
-#define s390_mr(c, r1, r2) S390_RR(c, 0x1c, r1, r2)
-#define s390_ms(c, r, x, b, d) S390_RX(c, 0x71, r, x, b, d)
-#define s390_msr(c, r1, r2) S390_RRE(c, 0xb252, r1, r2)
-#define s390_mvc(c, l, b1, d1, b2, d2) S390_SS_1(c, 0xd2, l, b1, d1, b2, d2)
-#define s390_mvcl(c, r1, r2) S390_RR(c, 0x0e, r1, r2)
-#define s390_mvcle(c, r1, r3, d2, b2) S390_RS_1(c, 0xa8, r1, r3, d2, b2)
-#define s390_n(c, r, x, b, d) S390_RX(c, 0x54, r, x, b, d)
-#define s390_nilh(c, r, v) S390_RI(c, 0xa56, r, v)
-#define s390_nill(c, r, v) S390_RI(c, 0xa57, r, v)
-#define s390_nr(c, r1, r2) S390_RR(c, 0x14, r1, r2)
-#define s390_o(c, r, x, b, d) S390_RX(c, 0x56, r, x, b, d)
-#define s390_or(c, r1, r2) S390_RR(c, 0x16, r1, r2)
-#define s390_s(c, r, x, b, d) S390_RX(c, 0x5b, r, x, b, d)
-#define s390_sdb(c, r, x, b, d) S390_RXE(c, 0xed1b, r, x, b, d)
-#define s390_sdbr(c, r1, r2) S390_RRE(c, 0xb31b, r1, r2)
-#define s390_sebr(c, r1, r2) S390_RRE(c, 0xb30b, r1, r2)
-#define s390_sla(c, r, b, d) S390_RS_3(c, 0x8b, r, b, d)
-#define s390_slb(c, r, x, b, d) S390_RXY(c, 0xe399, r, x, b, d)
-#define s390_slbr(c, r1, r2) S390_RRE(c, 0xb999, r1, r2)
-#define s390_sl(c, r, x, b, d) S390_RX(c, 0x5f, r, x, b, d)
-#define s390_slda(c, r, b, d) S390_RS_3(c, 0x8f, r, b, d)
-#define s390_sldl(c, r, b, d) S390_RS_3(c, 0x8d, r, b, d)
-#define s390_sll(c, r, b, d) S390_RS_3(c, 0x89, r, b, d)
-#define s390_slr(c, r1, r2) S390_RR(c, 0x1f, r1, r2)
-#define s390_sqdbr(c, r1, r2) S390_RRE(c, 0xb315, r1, r2)
-#define s390_sqebr(c, r1, r2) S390_RRE(c, 0xb314, r1, r2)
-#define s390_sra(c, r, b, d) S390_RS_3(c, 0x8a, r, b, d)
-#define s390_sr(c, r1, r2) S390_RR(c, 0x1b, r1, r2)
-#define s390_srda(c, r, b, d) S390_RS_3(c, 0x8e, r, b, d)
-#define s390_srdl(c, r, b, d) S390_RS_3(c, 0x8c, r, b, d)
-#define s390_srl(c, r, b, d) S390_RS_3(c, 0x88, r, b, d)
-#define s390_stam(c, r1, r2, b, d) S390_RS_1(c, 0x9b, r1, r2, b, d)
-#define s390_stc(c, r, x, b, d) S390_RX(c, 0x42, r, x, b, d)
-#define s390_stcm(c, r, m, b, d) S390_RX(c, 0xbe, r, m, b, d)
-#define s390_st(c, r, x, b, d) S390_RX(c, 0x50, r, x, b, d)
-#define s390_std(c, f, x, b, d) S390_RX(c, 0x60, f, x, b, d)
-#define s390_ste(c, f, x, b, d) S390_RX(c, 0x70, f, x, b, d)
-#define s390_stfpc(c, b, d) S390_S(c, 0xb29c, b, d)
-#define s390_sth(c, r, x, b, d) S390_RX(c, 0x40, r, x, b, d)
-#define s390_stm(c, r1, r2, b, d) S390_RS_1(c, 0x90, r1, r2, b, d)
-#define s390_tcdb(c, r, x, b, d) S390_RXE(c, 0xed11, r, x, b, d)
-#define s390_tceb(c, r, x, b, d) S390_RXE(c, 0xed10, r, x, b, d)
-#define s390_x(c, r, x, b, d) S390_RX(c, 0x57, r, x, b, d)
-#define s390_xr(c, r1, r2) S390_RR(c, 0x17, r1, r2)
-#endif
+++ /dev/null
-/*------------------------------------------------------------------*/
-/* */
-/* Name - tramp.c */
-/* */
-/* Function - Create trampolines to invoke arbitrary functions. */
-/* */
-/* Name - Neale Ferguson. */
-/* */
-/* Date - October, 2002 */
-/* */
-/* */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* D e f i n e s */
-/*------------------------------------------------------------------*/
-
-#define PROLOG_INS 24 /* Size of emitted prolog */
-#define CALL_INS 4 /* Size of emitted call */
-#define EPILOG_INS 18 /* Size of emitted epilog */
-
-#define DEBUG(x)
-
-/*========================= End of Defines =========================*/
-
-/*------------------------------------------------------------------*/
-/* I n c l u d e s */
-/*------------------------------------------------------------------*/
-
-#ifdef NEED_MPROTECT
-# include <sys/mman.h>
-# include <limits.h> /* for PAGESIZE */
-# ifndef PAGESIZE
-# define PAGESIZE 4096
-# endif
-#endif
-
-#include "config.h"
-#include <stdlib.h>
-#include <string.h>
-#include "s390-codegen.h"
-#include "mono/metadata/class.h"
-#include "mono/metadata/tabledefs.h"
-#include "mono/interpreter/interp.h"
-#include "mono/metadata/appdomain.h"
-#include "mono/metadata/marshal.h"
-
-/*========================= End of Includes ========================*/
-
-/*------------------------------------------------------------------*/
-/* T y p e d e f s */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* Structure used to accummulate size of stack, code, and locals */
-/*------------------------------------------------------------------*/
-typedef struct {
- guint stack_size,
- local_size,
- code_size,
- retStruct;
-} size_data;
-
-/*========================= End of Typedefs ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - add_general */
-/* */
-/* Function - Determine code and stack size incremements for a */
-/* parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-add_general (guint *gr, size_data *sz, gboolean simple)
-{
- if (simple) {
- if (*gr >= GENERAL_REGS) {
- sz->stack_size += sizeof(long);
- sz->code_size += 12;
- } else {
- sz->code_size += 8;
- }
- } else {
- if (*gr >= GENERAL_REGS - 1) {
- sz->stack_size += 8 + (sz->stack_size % 8);
- sz->code_size += 10;
- } else {
- sz->code_size += 8;
- }
- (*gr) ++;
- }
- (*gr) ++;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - calculate_sizes */
-/* */
-/* Function - Determine the amount of space required for code */
-/* and stack. In addition determine starting points */
-/* for stack-based parameters, and area for struct- */
-/* ures being returned on the stack. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-calculate_sizes (MonoMethodSignature *sig, size_data *sz,
- gboolean string_ctor)
-{
- guint i, fr, gr, size;
- guint32 simpletype, align;
-
- fr = 0;
- gr = 2;
- sz->retStruct = 0;
- sz->stack_size = S390_MINIMAL_STACK_SIZE;
- sz->code_size = (PROLOG_INS + CALL_INS + EPILOG_INS);
- sz->local_size = 0;
-
- if (sig->hasthis) {
- add_general (&gr, sz, TRUE);
- }
-
- /*----------------------------------------------------------*/
- /* We determine the size of the return code/stack in case we*/
- /* need to reserve a register to be used to address a stack */
- /* area that the callee will use. */
- /*----------------------------------------------------------*/
-
- if (sig->ret->byref || string_ctor) {
- sz->code_size += 8;
- } else {
- simpletype = sig->ret->type;
-enum_retvalue:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_PTR:
- case MONO_TYPE_STRING:
- sz->code_size += 4;
- break;
- case MONO_TYPE_I8:
- sz->code_size += 4;
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->ret->data.klass->enumtype) {
- simpletype = sig->ret->data.klass->enum_basetype->type;
- goto enum_retvalue;
- }
- gr++;
- if (sig->pinvoke)
- size = mono_class_native_size (sig->ret->data.klass, &align);
- else
- size = mono_class_value_size (sig->ret->data.klass, &align);
- if (align > 1)
- sz->code_size += 10;
- switch (size) {
- /*----------------------------------*/
- /* On S/390, structures of size 1, */
- /* 2, 4, and 8 bytes are returned */
- /* in (a) register(s). */
- /*----------------------------------*/
- case 1:
- case 2:
- case 4:
- case 8:
- sz->code_size += 16;
- sz->stack_size += 4;
- break;
- default:
- sz->retStruct = 1;
- sz->code_size += 32;
- }
- break;
- case MONO_TYPE_VOID:
- break;
- default:
- g_error ("tramp: cannot handle as return value 0x%x", sig->ret->type);
- }
- }
-
- /*----------------------------------------------------------*/
- /* We determine the size of the parameter code and stack */
- /* requirements by checking the types and sizes of the */
- /* parameters. */
- /*----------------------------------------------------------*/
-
- for (i = 0; i < sig->param_count; ++i) {
- if (sig->params [i]->byref) {
- add_general (&gr, sz, TRUE);
- continue;
- }
- simpletype = sig->params [i]->type;
- enum_calc_size:
- switch (simpletype) {
- 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_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- add_general (&gr, sz, TRUE);
- break;
- case MONO_TYPE_SZARRAY:
- add_general (&gr, sz, TRUE);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->params [i]->data.klass->enumtype) {
- simpletype = sig->params [i]->data.klass->enum_basetype->type;
- goto enum_calc_size;
- }
- if (sig->pinvoke)
- size = mono_class_native_size (sig->params [i]->data.klass, &align);
- else
- size = mono_class_value_size (sig->params [i]->data.klass, &align);
- DEBUG(printf("%d typesize: %d (%d)\n",i,size,align));
- switch (size) {
- /*----------------------------------*/
- /* On S/390, structures of size 1, */
- /* 2, 4, and 8 bytes are passed in */
- /* (a) register(s). */
- /*----------------------------------*/
- case 0:
- case 1:
- case 2:
- case 4:
- add_general(&gr, sz, TRUE);
- break;
- case 8:
- add_general(&gr, sz, FALSE);
- break;
- default:
- sz->local_size += (size + (size % align));
- sz->code_size += 40;
- }
- break;
- case MONO_TYPE_I8:
- add_general (&gr, sz, FALSE);
- break;
- case MONO_TYPE_R4:
- if (fr < FLOAT_REGS) {
- sz->code_size += 4;
- fr++;
- }
- else {
- sz->code_size += 4;
- sz->stack_size += 8;
- }
- break;
- case MONO_TYPE_R8:
- if (fr < FLOAT_REGS) {
- sz->code_size += 4;
- fr++;
- } else {
- sz->code_size += 4;
- sz->stack_size += 8 + (sz->stack_size % 8);
- }
- break;
- default:
- g_error ("Can't trampoline 0x%x", sig->params [i]->type);
- }
- }
-
-
- /* align stack size to 8 */
- DEBUG (printf (" stack size: %d (%d)\n"
- " code size: %d\n"
- " local size: %d\n",
- (sz->stack_size + 8) & ~8, sz->stack_size,
- (sz->code_size),(sz->local_size + 8) & ~8));
- sz->stack_size = (sz->stack_size + 8) & ~8;
- sz->local_size = (sz->local_size + 8) & ~8;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_prolog */
-/* */
-/* Function - Create the instructions that implement the stand- */
-/* ard function prolog according to the S/390 ABI. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-emit_prolog (guint8 *p, MonoMethodSignature *sig, size_data *sz)
-{
- guint stack_size;
-
- stack_size = sz->stack_size + sz->local_size;
-
- /* function prolog */
- s390_stm (p, s390_r6, STK_BASE, STK_BASE, 24);
- s390_l (p, s390_r7, 0, STK_BASE, MINV_POS);
- s390_lr (p, s390_r11, STK_BASE);
- s390_ahi (p, STK_BASE, -stack_size);
- s390_st (p, s390_r11, 0, STK_BASE, 0);
-
- /*-----------------------------------------*/
- /* Save: */
- /* - address of "callme" */
- /* - address of "retval" */
- /* - address of "arguments" */
- /*-----------------------------------------*/
- s390_lr (p, s390_r9, s390_r2);
- s390_lr (p, s390_r8, s390_r3);
- s390_lr (p, s390_r10, s390_r5);
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_save_parameters */
-/* */
-/* Function - Create the instructions that load registers with */
-/* parameters, place others on the stack according */
-/* to the S/390 ABI. */
-/* */
-/* The resulting function takes the form: */
-/* void func (void (*callme)(), void *retval, */
-/* void *this_obj, stackval *arguments); */
-/* */
-/*------------------------------------------------------------------*/
-
-inline static guint8*
-emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
-{
- guint i, fr, gr, act_strs, align,
- stack_par_pos, size, local_pos;
- guint32 simpletype;
-
- /*----------------------------------------------------------*/
- /* If a structure on stack is being returned, reserve r2 */
- /* to point to an area where it can be passed. */
- /*----------------------------------------------------------*/
- if (sz->retStruct)
- gr = 1;
- else
- gr = 0;
- fr = 0;
- act_strs = 0;
- stack_par_pos = S390_MINIMAL_STACK_SIZE;
- local_pos = sz->stack_size;
-
- if (sig->hasthis) {
- s390_lr (p, s390_r2 + gr, s390_r4);
- gr++;
- }
-
- act_strs = 0;
- for (i = 0; i < sig->param_count; ++i) {
- DEBUG(printf("par: %d type: %d ref: %d\n",i,sig->params[i]->type,sig->params[i]->byref));
- if (sig->params [i]->byref) {
- if (gr < GENERAL_REGS) {
- s390_l (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
- gr ++;
- } else {
- s390_l (p, s390_r0, 0, ARG_BASE, STKARG);
- s390_st (p, s390_r0, 0, STK_BASE, stack_par_pos);
- stack_par_pos += sizeof(long);
- }
- continue;
- }
- simpletype = sig->params [i]->type;
- enum_calc_size:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_PTR:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_SZARRAY:
- if (gr < GENERAL_REGS) {
- s390_l (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
- gr ++;
- } else {
- s390_l (p, s390_r0, 0, ARG_BASE, STKARG);
- s390_st (p, s390_r0, 0, STK_BASE, stack_par_pos);
- stack_par_pos += sizeof(long);
- }
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->params [i]->data.klass->enumtype) {
- simpletype = sig->params [i]->data.klass->enum_basetype->type;
- goto enum_calc_size;
- }
- if (sig->pinvoke)
- size = mono_class_native_size (sig->params [i]->data.klass, &align);
- else
- size = mono_class_value_size (sig->params [i]->data.klass, &align);
- DEBUG(printf("parStruct - size %d pinvoke: %d\n",size,sig->pinvoke));
- switch (size) {
- case 0:
- case 1:
- case 2:
- case 4:
- if (gr < GENERAL_REGS) {
- s390_l (p, s390_r2 + gr, 0,ARG_BASE, STKARG);
- s390_l (p, s390_r2 + gr, 0, s390_r2 + gr, 0);
- gr++;
- } else {
- stack_par_pos += (stack_par_pos % align);
- s390_l (p, s390_r10, 0,ARG_BASE, STKARG);
- s390_l (p, s390_r10, 0, s390_r10, 0);
- s390_st (p, s390_r10, 0, STK_BASE, stack_par_pos);
- stack_par_pos += sizeof(long);
- }
- break;
- case 8:
- if (gr < GENERAL_REGS-1) {
- s390_l (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
- s390_lm (p, s390_r2 + gr, s390_r3 + gr, s390_r2 + gr, 0);
- } else {
- stack_par_pos += (stack_par_pos % align);
- s390_l (p, s390_r10, 0, ARG_BASE, STKARG);
- s390_mvc (p, sizeof(long long), STK_BASE, stack_par_pos, s390_r10, 0);
- stack_par_pos += sizeof(long long);
- }
- break;
- default:
- if (size <= 256) {
- local_pos += (local_pos % align);
- s390_l (p, s390_r13, 0, ARG_BASE, STKARG);
- s390_mvc (p, size, STK_BASE, local_pos, s390_r13, 0);
- s390_la (p, s390_r13, 0, STK_BASE, local_pos);
- local_pos += size;
- } else {
- local_pos += (local_pos % align);
- s390_bras (p, s390_r13, 4);
- s390_word (p, size);
- s390_l (p, s390_r1, 0, s390_r13, 0);
- s390_l (p, s390_r0, 0, ARG_BASE, STKARG);
- s390_lr (p, s390_r14, s390_r12);
- s390_la (p, s390_r12, 0, STK_BASE, local_pos);
- s390_lr (p, s390_r13, s390_r1);
- s390_mvcl (p, s390_r12, s390_r0);
- s390_lr (p, s390_r12, s390_r14);
- s390_la (p, s390_r13, 0, STK_BASE, local_pos);
- local_pos += size;
- }
- if (gr < GENERAL_REGS) {
- s390_lr (p, s390_r2 + gr, s390_r13);
- gr++;
- } else {
- s390_st (p, s390_r13, 0, STK_BASE, stack_par_pos);
- stack_par_pos += sizeof(long);
- }
- }
- break;
- case MONO_TYPE_I8:
- if (gr < GENERAL_REGS-1) {
- s390_lm (p, s390_r2 + gr, s390_r2 + gr + 1, ARG_BASE, STKARG);
- gr += 2;
- } else {
- *(guint32 *) p += 7;
- *(guint32 *) p &= ~7;
- s390_mvc (p, sizeof(long long), STK_BASE, stack_par_pos, ARG_BASE, STKARG);
- stack_par_pos += sizeof(long long) + (stack_par_pos % sizeof(long long));
- }
- break;
- case MONO_TYPE_R4:
- if (fr < FLOAT_REGS) {
- s390_le (p, s390_r0 + fr, 0, ARG_BASE, STKARG);
- fr++;
- } else {
- s390_mvc (p, sizeof(float), STK_BASE, stack_par_pos, ARG_BASE, STKARG);
- stack_par_pos += sizeof(float);
- }
- break;
- case MONO_TYPE_R8:
- if (fr < FLOAT_REGS) {
- s390_ld (p, s390_r0 + fr, 0, ARG_BASE, STKARG);
- fr++;
- } else {
- *(guint32 *) p += 7;
- *(guint32 *) p &= ~7;
- s390_mvc (p, sizeof(double), STK_BASE, stack_par_pos, ARG_BASE, STKARG);
- stack_par_pos += sizeof(long long) + (stack_par_pos % sizeof(long long));
- }
- break;
- default:
- g_error ("Can't trampoline 0x%x", sig->params [i]->type);
- }
- }
-
- /*----------------------------------------------------------*/
- /* If we're returning a structure but not in a register */
- /* then point the result area for the called routine */
- /*----------------------------------------------------------*/
- if (sz->retStruct) {
- s390_l (p, s390_r2, 0, s390_r8, 0);
- }
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - alloc_code_memory */
-/* */
-/* Function - Allocate space to place the emitted code. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-alloc_code_memory (guint code_size)
-{
- guint8 *p;
-
-#ifdef NEED_MPROTECT
- p = g_malloc (code_size + PAGESIZE - 1);
-
- /* Align to a multiple of PAGESIZE, assumed to be a power of two */
- p = (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));
-#else
- p = g_malloc (code_size);
-#endif
- DEBUG (printf (" align: %p (%d)\n", p, (guint)p % 4));
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_call_and_store_retval */
-/* */
-/* Function - Emit code that will implement the call to the */
-/* desired function, and unload the result according */
-/* to the S390 ABI for the type of value returned */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-emit_call_and_store_retval (guint8 *p, MonoMethodSignature *sig,
- size_data *sz, gboolean string_ctor)
-{
- guint32 simpletype;
- guint retSize, align;
-
- /* call "callme" */
- s390_basr (p, s390_r14, s390_r9);
-
- /* get return value */
- if (sig->ret->byref || string_ctor) {
- s390_st (p, s390_r2, 0, s390_r8, 0);
- } else {
- simpletype = sig->ret->type;
-enum_retvalue:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- s390_stc (p, s390_r2, 0, s390_r8, 0);
- break;
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- s390_sth (p, s390_r2, 0, s390_r8, 0);
- break;
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_STRING:
- s390_st (p, s390_r2, 0, s390_r8, 0);
- break;
- case MONO_TYPE_R4:
- s390_ste (p, s390_f0, 0, s390_r8, 0);
- break;
- case MONO_TYPE_R8:
- s390_std (p, s390_f0, 0, s390_r8, 0);
- break;
- case MONO_TYPE_I8:
- s390_stm (p, s390_r2, s390_r3, s390_r8, 0);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->ret->data.klass->enumtype) {
- simpletype = sig->ret->data.klass->enum_basetype->type;
- goto enum_retvalue;
- }
- if (sig->pinvoke)
- retSize = mono_class_native_size (sig->ret->data.klass, &align);
- else
- retSize = mono_class_value_size (sig->ret->data.klass, &align);
-printf("Returning %d bytes for type %d (%d)\n",retSize,simpletype,sig->pinvoke);
- switch(retSize) {
- case 0:
- break;
- case 1:
- s390_stc (p, s390_r2, 0, s390_r8, 0);
- break;
- case 2:
- s390_sth (p, s390_r2, 0, s390_r8, 0);
- break;
- case 4:
- s390_st (p, s390_r2, 0, s390_r8, 0);
- break;
- case 8:
- s390_stm (p, s390_r2, s390_r3, s390_r8, 0);
- break;
- default: ;
- /*------------------------------------------*/
- /* The callee has already placed the result */
- /* in the required area */
- /*------------------------------------------*/
- break;
- }
- break;
- case MONO_TYPE_VOID:
- break;
- default:
- g_error ("Can't handle as return value 0x%x",
- sig->ret->type);
- }
- }
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_epilog */
-/* */
-/* Function - Create the instructions that implement the stand- */
-/* ard function epilog according to the S/390 ABI. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-emit_epilog (guint8 *p, MonoMethodSignature *sig, size_data *sz)
-{
- /* function epilog */
- s390_l (p, STK_BASE, 0, STK_BASE, 0);
- s390_l (p, s390_r4, 0, STK_BASE, 56);
- s390_lm (p, s390_r6, STK_BASE, STK_BASE, 24);
- s390_br (p, s390_r4);
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_trampoline. */
-/* */
-/* Function - Create the code that will allow a mono method to */
-/* invoke a system subroutine. */
-/* */
-/*------------------------------------------------------------------*/
-
-MonoPIFunc
-mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor)
-{
- guint8 *p, *code_buffer;
- size_data sz;
-
- DEBUG (printf ("\nPInvoke [start emiting]\n"));
- calculate_sizes (sig, &sz, string_ctor);
-
- p = code_buffer = alloc_code_memory (sz.code_size);
- p = emit_prolog (p, sig, &sz);
- p = emit_save_parameters (p, sig, &sz);
- p = emit_call_and_store_retval (p, sig, &sz, string_ctor);
- p = emit_epilog (p, sig, &sz);
-
-#ifdef NEED_MPROTECT
- if (mprotect (code_buffer, 1024, PROT_READ | PROT_WRITE | PROT_EXEC)) {
- g_error ("Cannot mprotect trampoline\n");
- }
-#endif
-
- DEBUG (printf ("emited code size: %d\n", p - code_buffer));
-
- DEBUG (printf ("PInvoke [end emiting]\n"));
-
- return (MonoPIFunc) code_buffer;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_method_pointer */
-/* */
-/* Function - Returns a pointer to a native function that can */
-/* be used to call the specified method. */
-/* */
-/* The function created will receive the arguments */
-/* according to the calling convention specified in */
-/* in the method. */
-/* */
-/* This function works by creating a MonoInvocation */
-/* structure, filling the fields in and calling */
-/* ves_exec_method() on it. */
-/* */
-/* Logic: */
-/* ------ */
-/* mono_arch_create_method_pointer (MonoMethod *method) */
-/* create the unmanaged->managed wrapper */
-/* register it with mono_jit_info_table_add() */
-/* */
-/* What does the unmanaged->managed wrapper do? */
-/* allocate a MonoInvocation structure (inv) on the stack */
-/* allocate an array of stackval on the stack with length = */
-/* method->signature->param_count + 1 [call it stack_args] */
-/* set inv->ex, inv->ex_handler, inv->parent to NULL */
-/* set inv->method to method */
-/* if method is an instance method, set inv->obj to the */
-/* 'this' argument (the first argument) else set to NULL */
-/* for each argument to the method call: */
-/* stackval_from_data (sig->params[i], &stack_args[i], */
-/* arg, sig->pinvoke); */
-/* Where: */
-/* ------ */
-/* sig - is method->signature */
-/* &stack_args[i] - is the pointer to the ith element */
-/* in the stackval array */
-/* arg - is a pointer to the argument re- */
-/* ceived by the function according */
-/* to the call convention. If it */
-/* gets passed in a register, save */
-/* on the stack first. */
-/* */
-/* set inv->retval to the address of the last element of */
-/* stack_args [recall we allocated param_count+1 of them] */
-/* call ves_exec_method(inv) */
-/* copy the returned value from inv->retval where the calling */
-/* convention expects to find it on return from the wrap- */
-/* per [if it's a structure, use stackval_to_data] */
-/* */
-/*------------------------------------------------------------------*/
-
-void *
-mono_arch_create_method_pointer (MonoMethod *method)
-{
- MonoMethodSignature *sig;
- MonoJitInfo *ji;
- guint8 *p, *code_buffer;
- guint i, align = 0, simple_type, retSize, reg_save = 0,
- stackval_arg_pos, local_pos, float_pos,
- local_start, reg_param = 0, stack_param,
- this_flag, arg_pos, fpr_param, parSize;
- guint32 simpletype;
- size_data sz;
- int *vtbuf, cpos, vt_cur;
-
- sz.code_size = 1024;
- sz.stack_size = 1024;
- stack_param = 0;
- fpr_param = 0;
- arg_pos = 0;
-
- sig = method->signature;
-
- p = code_buffer = g_malloc (sz.code_size);
-
- DEBUG (printf ("\nDelegate [start emiting] %s at 0x%08x\n",
- method->name,p));
-
- /*----------------------------------------------------------*/
- /* prolog */
- /*----------------------------------------------------------*/
- s390_stm (p, s390_r6, STK_BASE, STK_BASE, 24);
- s390_l (p, s390_r7, 0, STK_BASE, MINV_POS);
- s390_lr (p, s390_r0, STK_BASE);
- s390_ahi (p, STK_BASE, -(sz.stack_size+MINV_POS));
- s390_st (p, s390_r0, 0, STK_BASE, 0);
- s390_la (p, s390_r8, 0, STK_BASE, 4);
- s390_lr (p, s390_r10, s390_r8);
- s390_lhi (p, s390_r9, sz.stack_size+92);
- s390_lhi (p, s390_r11, 0);
- s390_mvcl(p, s390_r8, s390_r10);
-
- /*----------------------------------------------------------*/
- /* Let's fill MonoInvocation - first zero some fields */
- /*----------------------------------------------------------*/
- s390_lhi (p, s390_r0, 0);
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex)));
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex_handler)));
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, parent)));
- s390_lhi (p, s390_r0, 1);
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, invoke_trap)));
-
- /*----------------------------------------------------------*/
- /* set method pointer */
- /*----------------------------------------------------------*/
- s390_bras (p, s390_r13, 4);
- s390_word (p, method);
- s390_l (p, s390_r0, 0, s390_r13, 0);
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, method)));
-
- local_start = local_pos = MINV_POS +
- sizeof (MonoInvocation) + (sig->param_count + 1) * sizeof (stackval);
- this_flag = (sig->hasthis ? 1 : 0);
-
- /*----------------------------------------------------------*/
- /* if we are returning a structure, checks it's length to */
- /* see if there's a "hidden" parameter that points to the */
- /* area. If necessary save this hidden parameter for later */
- /*----------------------------------------------------------*/
- if (MONO_TYPE_ISSTRUCT(sig->ret)) {
- if (sig->pinvoke)
- retSize = mono_class_native_size (sig->ret->data.klass, &align);
- else
- retSize = mono_class_value_size (sig->ret->data.klass, &align);
- switch(retSize) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 8:
- sz.retStruct = 0;
- break;
- default:
- sz.retStruct = 1;
- s390_lr(p, s390_r8, s390_r2);
- reg_save = 1;
- }
- } else {
- reg_save = 0;
- }
-
- if (this_flag) {
- s390_st (p, s390_r2 + reg_save, 0, STK_BASE,
- (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)));
- reg_param++;
- } else {
- s390_st (p, s390_r2 + reg_save, 0, STK_BASE, local_pos);
- local_pos += sizeof(int);
- s390_st (p, s390_r0, 0, STK_BASE,
- (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)));
- }
-
- s390_stm (p, s390_r3 + reg_param, s390_r6, STK_BASE, local_pos);
- local_pos += 4 * sizeof(long);
- float_pos = local_pos;
- s390_std (p, s390_f0, 0, STK_BASE, local_pos);
- local_pos += sizeof(double);
- s390_std (p, s390_f2, 0, STK_BASE, local_pos);
- local_pos += sizeof(double);
-
- /*----------------------------------------------------------*/
- /* prepare space for valuetypes */
- /*----------------------------------------------------------*/
- vt_cur = local_pos;
- vtbuf = alloca (sizeof(int)*sig->param_count);
- cpos = 0;
- for (i = 0; i < sig->param_count; i++) {
- MonoType *type = sig->params [i];
- vtbuf [i] = -1;
- DEBUG(printf("par: %d type: %d ref: %d\n",i,type->type,type->byref));
- if (type->type == MONO_TYPE_VALUETYPE) {
- MonoClass *klass = type->data.klass;
- gint size;
-
- if (klass->enumtype)
- continue;
- size = mono_class_native_size (klass, &align);
- cpos += align - 1;
- cpos &= ~(align - 1);
- vtbuf [i] = cpos;
- cpos += size;
- }
- }
- cpos += 3;
- cpos &= ~3;
-
- local_pos += cpos;
-
- /*----------------------------------------------------------*/
- /* set MonoInvocation::stack_args */
- /*----------------------------------------------------------*/
- stackval_arg_pos = MINV_POS + sizeof (MonoInvocation);
- s390_la (p, s390_r0, 0, STK_BASE, stackval_arg_pos);
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, stack_args)));
-
- /*----------------------------------------------------------*/
- /* add stackval arguments */
- /*----------------------------------------------------------*/
- for (i = 0; i < sig->param_count; ++i) {
- if (sig->params [i]->byref) {
- ADD_ISTACK_PARM(0, 1);
- } else {
- simple_type = sig->params [i]->type;
- enum_savechk:
- switch (simple_type) {
- case MONO_TYPE_I8:
- ADD_ISTACK_PARM(-1, 2);
- break;
- case MONO_TYPE_R4:
- ADD_RSTACK_PARM(1);
- break;
- case MONO_TYPE_R8:
- ADD_RSTACK_PARM(2);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->params [i]->data.klass->enumtype) {
- simple_type = sig->params [i]->data.klass->enum_basetype->type;
- goto enum_savechk;
- }
- if (sig->pinvoke)
- parSize = mono_class_native_size (sig->params [i]->data.klass, &align);
- else
- parSize = mono_class_value_size (sig->params [i]->data.klass, &align);
- switch(parSize) {
- case 0:
- case 1:
- case 2:
- case 4:
- ADD_PSTACK_PARM(0, 1);
- break;
- case 8:
- ADD_PSTACK_PARM(-1, 2);
- break;
- default:
- ADD_TSTACK_PARM;
- }
- break;
- default:
- ADD_ISTACK_PARM(0, 1);
- }
- }
-
- if (vtbuf [i] >= 0) {
- s390_la (p, s390_r3, 0, STK_BASE, vt_cur);
- s390_st (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
- s390_la (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
- vt_cur += vtbuf [i];
- } else {
- s390_la (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
- }
-
- /*--------------------------------------*/
- /* Load the parameter registers for the */
- /* call to stackval_from_data */
- /*--------------------------------------*/
- s390_bras (p, s390_r13, 8);
- s390_word (p, sig->params [i]);
- s390_word (p, sig->pinvoke);
- s390_word (p, stackval_from_data);
- s390_l (p, s390_r2, 0, s390_r13, 0);
-
- s390_l (p, s390_r5, 0, s390_r13, 4);
-
- s390_l (p, s390_r1, 0, s390_r13, 8);
- s390_basr (p, s390_r14, s390_r1);
-
- stackval_arg_pos += sizeof(stackval);
-
- /* fixme: alignment */
- DEBUG (printf ("arg_pos %d --> ", arg_pos));
- if (sig->pinvoke)
- arg_pos += mono_type_native_stack_size (sig->params [i], &align);
- else
- arg_pos += mono_type_stack_size (sig->params [i], &align);
-
- DEBUG (printf ("%d\n", stackval_arg_pos));
- }
-
- /*----------------------------------------------------------*/
- /* Set return area pointer. */
- /*----------------------------------------------------------*/
- s390_la (p, s390_r10, 0, STK_BASE, stackval_arg_pos);
- s390_st (p, s390_r10, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)));
- if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) {
- MonoClass *klass = sig->ret->data.klass;
- if (!klass->enumtype) {
- s390_la (p, s390_r9, 0, s390_r10, sizeof(stackval));
- s390_st (p, s390_r9, 0,STK_BASE, stackval_arg_pos);
- stackval_arg_pos += sizeof(stackval);
- }
- }
-
- /*----------------------------------------------------------*/
- /* call ves_exec_method */
- /*----------------------------------------------------------*/
- s390_bras (p, s390_r13, 4);
- s390_word (p, ves_exec_method);
- s390_l (p, s390_r1, 0, s390_r13, 0);
- s390_la (p, s390_r2, 0, STK_BASE, MINV_POS);
- s390_basr (p, s390_r14, s390_r1);
-
- /*----------------------------------------------------------*/
- /* move retval from stackval to proper place (r3/r4/...) */
- /*----------------------------------------------------------*/
- DEBUG(printf("retType: %d byRef: %d\n",sig->ret->type,sig->ret->byref));
- if (sig->ret->byref) {
- DEBUG (printf ("ret by ref\n"));
- s390_st (p, s390_r2, 0, s390_r10, 0);
- } else {
- enum_retvalue:
-DEBUG(printf("Returns: %d\n",sig->ret->type));
- switch (sig->ret->type) {
- case MONO_TYPE_VOID:
- break;
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_U1:
- s390_lhi (p, s390_r2, 0);
- s390_ic (p, s390_r2, 0, s390_r10, 0);
- break;
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- s390_lh (p, s390_r2, 0,s390_r10, 0);
- break;
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_CLASS:
- s390_l (p, s390_r2, 0, s390_r10, 0);
- break;
- case MONO_TYPE_I8:
- s390_lm (p, s390_r2, s390_r3, s390_r10, 0);
- break;
- case MONO_TYPE_R4:
- s390_le (p, s390_f0, 0, s390_r10, 0);
- break;
- case MONO_TYPE_R8:
- s390_ld (p, s390_f0, 0, s390_r10, 0);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->ret->data.klass->enumtype) {
- simpletype = sig->ret->data.klass->enum_basetype->type;
- goto enum_retvalue;
- }
- /*---------------------------------*/
- /* Call stackval_to_data to return */
- /* the structure */
- /*---------------------------------*/
- s390_bras (p, s390_r13, 8);
- s390_word (p, sig->ret);
- s390_word (p, sig->pinvoke);
- s390_word (p, stackval_to_data);
- s390_l (p, s390_r2, 0, s390_r13, 0);
- s390_l (p, s390_r3, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)));
- if (sz.retStruct) {
- /*------------------------------------------*/
- /* Get stackval_to_data to set result area */
- /*------------------------------------------*/
- s390_lr (p, s390_r4, s390_r8);
- } else {
- /*------------------------------------------*/
- /* Give stackval_to_data a temp result area */
- /*------------------------------------------*/
- s390_la (p, s390_r4, 0, STK_BASE, stackval_arg_pos);
- }
- s390_l (p, s390_r5, 0,s390_r13, 4);
- s390_l (p, s390_r1, 0, s390_r13, 8);
- s390_basr (p, s390_r14, s390_r1);
- switch (retSize) {
- case 0:
- break;
- case 1:
- s390_lhi (p, s390_r2, 0);
- s390_ic (p, s390_r2, 0, s390_r10, 0);
- break;
- case 2:
- s390_lh (p, s390_r2, 0, s390_r10, 0);
- break;
- case 4:
- s390_l (p, s390_r2, 0, s390_r10, 0);
- break;
- case 8:
- s390_lm (p, s390_r2, s390_r3, s390_r10, 0);
- break;
- default: ;
- /*-------------------------------------------------*/
- /* stackval_to_data has placed data in result area */
- /*-------------------------------------------------*/
- break;
- }
- break;
- default:
- g_error ("Type 0x%x not handled yet in thunk creation",
- sig->ret->type);
- break;
- }
- }
-
- /*----------------------------------------------------------*/
- /* epilog */
- /*----------------------------------------------------------*/
- s390_l (p, STK_BASE, 0, STK_BASE, 0);
- s390_l (p, s390_r4, 0, STK_BASE, S390_RET_ADDR_OFFSET);
- s390_lm (p, s390_r6, STK_BASE, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_br (p, s390_r4);
-
- DEBUG (printf ("emited code size: %d\n", p - code_buffer));
-
- DEBUG (printf ("Delegate [end emiting]\n"));
-
- ji = g_new0 (MonoJitInfo, 1);
- ji->method = method;
- ji->code_size = p - code_buffer;
- ji->code_start = code_buffer;
-
- mono_jit_info_table_add (mono_get_root_domain (), ji);
-
- return ji->code_start;
-}
-
-/*========================= End of Function ========================*/
#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)
{
io-portability.h \
macros.h \
messages.h \
- mono-mutex.h \
mutexes.h \
processes.h \
security.h \
mutexes.c \
mutexes.h \
mutex-private.h \
- mono-mutex.c \
- mono-mutex.h \
posix.c \
processes.c \
processes.h \
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/critical-section-private.h>
-#include "mono-mutex.h"
+#include <mono/utils/mono-mutex.h>
/* A critical section is really just like a lightweight mutex. It
* can't be waited for, and doesn't have a handle.
*/
-/* According to the MSDN docs, the Microsoft implementation spins a
- * number of times then waits for a semaphore. I could implement that
- * here but I'd need a mutex around the critical section structure
- * anyway. So I may as well just use a pthread mutex.
- */
-static mono_once_t attr_key_once=MONO_ONCE_INIT;
-static mono_mutexattr_t attr;
-
-static void attr_init(void)
-{
- int ret;
-
- ret = mono_mutexattr_init(&attr);
- g_assert (ret == 0);
-
- ret = mono_mutexattr_settype(&attr, MONO_MUTEX_RECURSIVE);
- g_assert (ret == 0);
-}
-
-void _wapi_critical_section_cleanup (void)
-{
- mono_mutexattr_destroy (&attr);
-}
-
/**
* InitializeCriticalSection:
* @section: The critical section to initialise
{
int ret;
- mono_once(&attr_key_once, attr_init);
- ret = mono_mutex_init(§ion->mutex, &attr);
+ ret = mono_mutex_init_recursive (§ion->mutex);
g_assert (ret == 0);
}
#include <glib.h>
#include <pthread.h>
-#include "mono-mutex.h"
+#include <mono/utils/mono-mutex.h>
G_BEGIN_DECLS
#include <glib.h>
#include <pthread.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
extern struct _WapiHandleOps _wapi_event_ops;
extern struct _WapiHandleOps _wapi_namedevent_ops;
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
-
#include <mono/io-layer/event-private.h>
+#include <mono/utils/mono-mutex.h>
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/shared.h>
#include <mono/io-layer/collection.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/critical-section-private.h>
+#include <mono/utils/mono-mutex.h>
#undef DEBUG_REFS
#if 0
}
-static mono_mutex_t scan_mutex = MONO_MUTEX_INITIALIZER;
+static mono_mutex_t scan_mutex;
static void handle_cleanup (void)
{
if (_wapi_shm_enabled ())
_wapi_collection_init ();
#endif
+ _wapi_io_init ();
+ mono_mutex_init (&scan_mutex);
_wapi_global_signal_handle = _wapi_handle_new (WAPI_HANDLE_EVENT, NULL);
_wapi_global_signal_cond = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_cond;
_wapi_global_signal_mutex = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_mutex;
+
/* Using g_atexit here instead of an explicit function call in
* a cleanup routine lets us cope when a third-party library
* calls exit (eg if an X client loses the connection to its
_wapi_has_shut_down = TRUE;
- _wapi_critical_section_cleanup ();
_wapi_error_cleanup ();
_wapi_thread_cleanup ();
}
thr_ret = pthread_cond_init (&handle->signal_cond, NULL);
g_assert (thr_ret == 0);
- thr_ret = mono_mutex_init (&handle->signal_mutex, NULL);
+ thr_ret = mono_mutex_init (&handle->signal_mutex);
g_assert (thr_ret == 0);
if (handle_specific != NULL) {
#include <utime.h>
#include <sys/stat.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/error.h>
#include <mono/io-layer/wapi_glob.h>
#include <mono/io-layer/io-portability.h>
#include <mono/utils/mono-io-portability.h>
+
+#include <mono/utils/mono-mutex.h>
+
#undef DEBUG
int _wapi_open (const char *pathname, int flags, mode_t mode)
}
#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) {
* Return value: the handle, or %INVALID_HANDLE_VALUE on error
*/
-static mono_mutex_t stdhandle_mutex = MONO_MUTEX_INITIALIZER;
+static mono_mutex_t stdhandle_mutex;
gpointer GetStdHandle(WapiStdHandle stdhandle)
{
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;
return status;
}
#endif
+
+
+void
+_wapi_io_init (void)
+{
+ mono_mutex_init (&stdhandle_mutex);
+}
guint32 length_high);
extern gboolean GetVolumeInformation (const gunichar2 *path, gunichar2 *volumename, int volumesize, int *outserial, int *maxcomp, int *fsflags, gunichar2 *fsbuffer, int fsbuffersize);
+
+extern void _wapi_io_init (void);
+
G_END_DECLS
#endif /* _WAPI_IO_H_ */
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * mono-mutex.h: Portability wrappers around POSIX Mutexes
- *
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2002 Ximian, Inc. (www.ximian.com)
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/time.h>
-
-#include "mono-mutex.h"
-
-
-#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
-/* Android does not implement pthread_mutex_timedlock(), but does provide an
- * unusual declaration: http://code.google.com/p/android/issues/detail?id=7807
- */
-#ifdef PLATFORM_ANDROID
-#define CONST_NEEDED
-#else
-#define CONST_NEEDED const
-#endif
-
-int pthread_mutex_timedlock (pthread_mutex_t *mutex,
- CONST_NEEDED struct timespec *timeout);
-int
-pthread_mutex_timedlock (pthread_mutex_t *mutex, CONST_NEEDED struct timespec *timeout)
-{
- struct timeval timenow;
- struct timespec sleepytime;
- int retcode;
-
- /* This is just to avoid a completely busy wait */
- sleepytime.tv_sec = 0;
- sleepytime.tv_nsec = 10000000; /* 10ms */
-
- while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
- gettimeofday (&timenow, NULL);
-
- if (timenow.tv_sec >= timeout->tv_sec &&
- (timenow.tv_usec * 1000) >= timeout->tv_nsec) {
- return ETIMEDOUT;
- }
-
- nanosleep (&sleepytime, NULL);
- }
-
- return retcode;
-}
-#endif /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
-
-
-int
-mono_once (mono_once_t *once, void (*once_init) (void))
-{
- int thr_ret;
-
- if (!once->complete) {
- pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
- (void *)&once->mutex);
- thr_ret = pthread_mutex_lock (&once->mutex);
- g_assert (thr_ret == 0);
-
- if (!once->complete) {
- once_init ();
- once->complete = TRUE;
- }
- thr_ret = pthread_mutex_unlock (&once->mutex);
- g_assert (thr_ret == 0);
-
- pthread_cleanup_pop (0);
- }
-
- return 0;
-}
-
-
-#ifdef USE_MONO_MUTEX
-
-int
-mono_mutexattr_init (mono_mutexattr_t *attr)
-{
- memset (attr, 0, sizeof (mono_mutexattr_t));
- return 0;
-}
-
-int
-mono_mutexattr_settype (mono_mutexattr_t *attr, int type)
-{
- attr->type = type;
- return 0;
-}
-
-int
-mono_mutexattr_gettype (mono_mutexattr_t *attr, int *type)
-{
- *type = attr->type;
- return 0;
-}
-
-int
-mono_mutexattr_setpshared (mono_mutexattr_t *attr, int pshared)
-{
- attr->shared = pshared;
- return 0;
-}
-
-int
-mono_mutexattr_getpshared (mono_mutexattr_t *attr, int *pshared)
-{
- *pshared = attr->shared;
- return 0;
-}
-
-int
-mono_mutexattr_setprotocol (mono_mutexattr_t *attr, int protocol)
-{
- attr->protocol = protocol;
- return 0;
-}
-
-int
-mono_mutexattr_getprotocol (mono_mutexattr_t *attr, int *protocol)
-{
- *protocol = attr->protocol;
- return 0;
-}
-
-int
-mono_mutexattr_setprioceiling (mono_mutexattr_t *attr, int prioceiling)
-{
- attr->priority = prioceiling;
- return 0;
-}
-
-int
-mono_mutexattr_getprioceiling (mono_mutexattr_t *attr, int *prioceiling)
-{
- *prioceiling = attr->priority;
- return 0;
-}
-
-int
-mono_mutexattr_destroy (mono_mutexattr_t *attr)
-{
- return 0;
-}
-
-
-int
-mono_mutex_init (mono_mutex_t *mutex, const mono_mutexattr_t *attr)
-{
- int ret;
- int thr_ret;
-
- mutex->waiters = 0;
- mutex->depth = 0;
- mutex->owner = MONO_THREAD_NONE;
-
- if (!attr || attr->type == MONO_MUTEX_NORMAL) {
- mutex->type = MONO_MUTEX_NORMAL;
- ret = pthread_mutex_init (&mutex->mutex, NULL);
- } else {
- mutex->type = MONO_MUTEX_RECURSIVE;
- ret = pthread_mutex_init (&mutex->mutex, NULL);
- thr_ret = pthread_cond_init (&mutex->cond, NULL);
- g_assert (thr_ret == 0);
- }
-
- return(ret);
-}
-
-int
-mono_mutex_lock (mono_mutex_t *mutex)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_lock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else if (pthread_equal (mutex->owner, id)) {
- mutex->depth++;
- break;
- } else {
- mutex->waiters++;
- if (pthread_cond_wait (&mutex->cond, &mutex->mutex) != 0)
- return EINVAL;
- mutex->waiters--;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_trylock (mono_mutex_t *mutex)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_trylock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
-
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- if (!pthread_equal (mutex->owner, MONO_THREAD_NONE) &&
- !pthread_equal (mutex->owner, id)) {
- pthread_mutex_unlock (&mutex->mutex);
- return EBUSY;
- }
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else {
- mutex->depth++;
- break;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_timedlock (&mutex->mutex, timeout);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
-
- if (pthread_mutex_timedlock (&mutex->mutex, timeout) != 0)
- return ETIMEDOUT;
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else if (pthread_equal (mutex->owner, id)) {
- mutex->depth++;
- break;
- } else {
- mutex->waiters++;
- if (pthread_cond_timedwait (&mutex->cond, &mutex->mutex, timeout) != 0)
- return ETIMEDOUT;
- mutex->waiters--;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_unlock (mono_mutex_t *mutex)
-{
- int thr_ret;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_unlock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- if (pthread_equal (mutex->owner, pthread_self())) {
- /* Not owned by this thread */
- pthread_mutex_unlock (&mutex->mutex);
- return EPERM;
- }
-
- mutex->depth--;
- if (mutex->depth == 0) {
- mutex->owner = MONO_THREAD_NONE;
- if (mutex->waiters > 0) {
- thr_ret = pthread_cond_signal (&mutex->cond);
- g_assert (thr_ret == 0);
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_destroy (mono_mutex_t *mutex)
-{
- int ret = 0;
- int thr_ret;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- ret = pthread_mutex_destroy (&mutex->mutex);
- break;
- case MONO_MUTEX_RECURSIVE:
- if ((ret = pthread_mutex_destroy (&mutex->mutex)) == 0) {
- thr_ret = pthread_cond_destroy (&mutex->cond);
- g_assert (thr_ret == 0);
- }
- }
-
- return ret;
-}
-
-
-int
-mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex)
-{
- return pthread_cond_wait (cond, &mutex->mutex);
-}
-
-int
-mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout)
-{
- return pthread_cond_timedwait (cond, &mutex->mutex, timeout);
-}
-
-#endif /* USE_MONO_MUTEX */
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * mono-mutex.h: Portability wrappers around POSIX Mutexes
- *
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2002 Ximian, Inc. (www.ximian.com)
- */
-
-
-#ifndef __MONO_MUTEX_H__
-#define __MONO_MUTEX_H__
-
-#include <glib.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-#include <time.h>
-
-G_BEGIN_DECLS
-
-#ifndef HOST_WIN32
-
-typedef struct {
- pthread_mutex_t mutex;
- gboolean complete;
-} mono_once_t;
-
-#define MONO_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, FALSE }
-
-int mono_once (mono_once_t *once, void (*once_init) (void));
-
-
-#ifdef USE_MONO_MUTEX
-
-#define MONO_THREAD_NONE ((pthread_t)~0)
-
-/* mutex types... */
-enum {
- MONO_MUTEX_NORMAL,
- MONO_MUTEX_RECURSIVE,
- MONO_MUTEX_ERRORCHECK = MONO_MUTEX_NORMAL,
- MONO_MUTEX_DEFAULT = MONO_MUTEX_NORMAL
-};
-
-/* mutex protocol attributes... */
-enum {
- MONO_THREAD_PRIO_NONE,
- MONO_THREAD_PRIO_INHERIT,
- MONO_THREAD_PRIO_PROTECT,
-};
-
-/* mutex process sharing attributes... */
-enum {
- MONO_THREAD_PROCESS_PRIVATE,
- MONO_THREAD_PROCESS_SHARED
-};
-
-typedef struct _mono_mutexattr_t {
- int type : 1;
- int shared : 1;
- int protocol : 2;
- int priority : 28;
-} mono_mutexattr_t;
-
-typedef struct _mono_mutex_t {
- int type;
- pthread_t owner;
- short waiters;
- short depth;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-} mono_mutex_t;
-
-/* static initializers */
-#define MONO_MUTEX_INITIALIZER { 0, MONO_THREAD_NONE, 0, 0, PTHREAD_MUTEX_INITIALIZER, 0 }
-#define MONO_RECURSIVE_MUTEX_INITIALIZER { 0, MONO_THREAD_NONE, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER }
-
-int mono_mutexattr_init (mono_mutexattr_t *attr);
-int mono_mutexattr_settype (mono_mutexattr_t *attr, int type);
-int mono_mutexattr_gettype (mono_mutexattr_t *attr, int *type);
-int mono_mutexattr_setpshared (mono_mutexattr_t *attr, int pshared);
-int mono_mutexattr_getpshared (mono_mutexattr_t *attr, int *pshared);
-int mono_mutexattr_setprotocol (mono_mutexattr_t *attr, int protocol);
-int mono_mutexattr_getprotocol (mono_mutexattr_t *attr, int *protocol);
-int mono_mutexattr_setprioceiling (mono_mutexattr_t *attr, int prioceiling);
-int mono_mutexattr_getprioceiling (mono_mutexattr_t *attr, int *prioceiling);
-int mono_mutexattr_destroy (mono_mutexattr_t *attr);
-
-
-int mono_mutex_init (mono_mutex_t *mutex, const mono_mutexattr_t *attr);
-int mono_mutex_lock (mono_mutex_t *mutex);
-int mono_mutex_trylock (mono_mutex_t *mutex);
-int mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout);
-int mono_mutex_unlock (mono_mutex_t *mutex);
-int mono_mutex_destroy (mono_mutex_t *mutex);
-
-#define mono_cond_init(cond,attr) pthread_cond_init (cond, attr)
-int mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex);
-int mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout);
-#define mono_cond_signal(cond) pthread_cond_signal (cond)
-#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
-#define mono_cond_destroy(cond)
-
-#else /* system is equipped with a fully-functional pthread mutex library */
-
-#define MONO_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL
-#define MONO_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
-#define MONO_MUTEX_ERRORCHECK PTHREAD_MUTEX_NORMAL
-#define MONO_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
-
-#define MONO_THREAD_PRIO_NONE PTHREAD_PRIO_NONE
-#define MONO_THREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT
-#define MONO_THREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT
-
-#define MONO_THREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
-#define MONO_THREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
-
-typedef pthread_mutex_t mono_mutex_t;
-typedef pthread_mutexattr_t mono_mutexattr_t;
-typedef pthread_cond_t mono_cond_t;
-
-#define MONO_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-#define MONO_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-#define MONO_COND_INITIALIZER PTHREAD_COND_INITIALIZER
-
-#define mono_mutexattr_init(attr) pthread_mutexattr_init (attr)
-#define mono_mutexattr_settype(attr,type) pthread_mutexattr_settype (attr, type)
-#define mono_mutexattr_gettype(attr,type) pthread_mutexattr_gettype (attr, type)
-#define mono_mutexattr_setpshared(attr,pshared) pthread_mutexattr_setpshared (attr, pshared)
-#define mono_mutexattr_getpshared(attr,pshared) pthread_mutexattr_getpshared (attr, pshared)
-#define mono_mutexattr_setprotocol(attr,protocol) pthread_mutexattr_setprotocol (attr, protocol)
-#define mono_mutexattr_getprotocol(attr,protocol) pthread_mutexattr_getprotocol (attr, protocol)
-#define mono_mutexattr_setprioceiling(attr,prioceiling) pthread_mutexattr_setprioceiling (attr, prioceiling)
-#define mono_mutexattr_getprioceiling(attr,prioceiling) pthread_mutexattr_getprioceiling (attr, prioceiling)
-#define mono_mutexattr_destroy(attr) pthread_mutexattr_destroy (attr)
-
-#define mono_mutex_init(mutex,attr) pthread_mutex_init (mutex, attr)
-#define mono_mutex_lock(mutex) pthread_mutex_lock (mutex)
-#define mono_mutex_trylock(mutex) pthread_mutex_trylock (mutex)
-#define mono_mutex_timedlock(mutex,timeout) pthread_mutex_timedlock (mutex, timeout)
-#define mono_mutex_unlock(mutex) pthread_mutex_unlock (mutex)
-#define mono_mutex_destroy(mutex) pthread_mutex_destroy (mutex)
-
-#define mono_cond_init(cond,attr) pthread_cond_init (cond,attr)
-#define mono_cond_wait(cond,mutex) pthread_cond_wait (cond, mutex)
-#define mono_cond_timedwait(cond,mutex,timeout) pthread_cond_timedwait (cond, mutex, timeout)
-#define mono_cond_signal(cond) pthread_cond_signal (cond)
-#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
-#define mono_cond_destroy(cond)
-
-#endif /* USE_MONO_MUTEX */
-
-/* This is a function so it can be passed to pthread_cleanup_push -
- * that is a macro and giving it a macro as a parameter breaks.
- */
-G_GNUC_UNUSED
-static inline int mono_mutex_unlock_in_cleanup (mono_mutex_t *mutex)
-{
- return(mono_mutex_unlock (mutex));
-}
-
-#else
-
-typedef CRITICAL_SECTION mono_mutex_t;
-typedef HANDLE mono_cond_t;
-
-#define mono_mutex_init(mutex,attr) InitializeCriticalSection((mutex))
-#define mono_mutex_lock(mutex) EnterCriticalSection((mutex))
-#define mono_mutex_trylock(mutex) TryEnterCriticalSection((mutex))
-#define mono_mutex_unlock(mutex) LeaveCriticalSection((mutex))
-#define mono_mutex_destroy(mutex) DeleteCriticalSection((mutex))
-
-
-#define mono_cond_init(cond,attr) do{*(cond) = CreateEvent(NULL,FALSE,FALSE,NULL); } while (0)
-#define mono_cond_wait(cond,mutex) WaitForSingleObject(*(cond),INFINITE)
-#define mono_cond_timedwait(cond,mutex,timeout) WaitForSingleObject(*(cond),timeout)
-#define mono_cond_signal(cond) SetEvent(*(cond))
-#define mono_cond_broadcast(cond) (!SetEvent(*(cond)))
-#define mono_cond_destroy(cond) CloseHandle(*(cond))
-
-#define MONO_COND_INITIALIZER NULL
-#endif
-
-G_END_DECLS
-
-#endif /* __MONO_MUTEX_H__ */
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/mutex-private.h>
+#include <mono/utils/mono-mutex.h>
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/threads.h>
#include <mono/utils/strenc.h>
#include <mono/io-layer/timefuncs-private.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-membar.h>
+#include <mono/utils/mono-mutex.h>
/* The process' environment strings */
#if defined(__APPLE__) && !defined (__arm__)
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/semaphore-private.h>
+#include <mono/utils/mono-mutex.h>
+
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
#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
static void
noshm_semaphores_init (void)
{
- int i;
+ int i;
- for (i = 0; i < _WAPI_SHARED_SEM_COUNT; i++)
- mono_mutex_init (&noshm_sems [i], NULL);
+ for (i = 0; i < _WAPI_SHARED_SEM_COUNT; i++)
+ mono_mutex_init (&noshm_sems [i]);
}
static int
if (fd == -1 && domain == AF_INET && type == SOCK_RAW &&
protocol == 0) {
/* Retry with protocol == 4 (see bug #54565) */
+ // https://bugzilla.novell.com/show_bug.cgi?id=MONO54565
socket_handle.protocol = 4;
fd = socket (AF_INET, SOCK_RAW, 4);
}
/* .net seems to set this by default for SOCK_STREAM, not for
* SOCK_DGRAM (see bug #36322)
+ * https://bugzilla.novell.com/show_bug.cgi?id=MONO36322
*
* It seems winsock has a rather different idea of what
* SO_REUSEADDR means. If it's set, then a new socket can be
* behaves as though any other system would when SO_REUSEADDR
* is true, so we don't need to do anything else here. See
* bug 53992.
+ * https://bugzilla.novell.com/show_bug.cgi?id=MONO53992
*/
{
int ret, true = 1;
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/misc-private.h>
+#include <mono/utils/mono-mutex.h>
+
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/thread-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/gc_wrapper.h>
#include <mono/utils/atomic.h>
+#include <mono/utils/mono-mutex.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
*/
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;
{
}
+void
+mono_gc_register_for_finalization (MonoObject *obj, void *user_data)
+{
+ guint offset = 0;
+
+#ifndef GC_DEBUG
+ /* This assertion is not valid when GC_DEBUG is defined */
+ g_assert (GC_base (obj) == (char*)obj - offset);
+#endif
+
+ GC_REGISTER_FINALIZER_NO_ORDER ((char*)obj - offset, user_data, GUINT_TO_POINTER (offset), NULL, NULL);
+}
+
/*
* These will call the redefined versions in libgc.
*/
mono_secman_inheritancedemand_method (cm, im);
}
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_check_override (class, cm, im);
+
TRACE_INTERFACE_VTABLE (printf ("[NAME CHECK OK]"));
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (cm, im, NULL)) {
char *body_name = mono_method_full_name (cm, TRUE);
mono_secman_inheritancedemand_method (cm, im);
}
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_check_override (class, cm, im);
-
+
TRACE_INTERFACE_VTABLE (printf ("[INJECTED INTERFACE CHECK OK]"));
if (is_wcf_hack_disabled () && !mono_method_can_access_method_full (cm, im, NULL)) {
char *body_name = mono_method_full_name (cm, TRUE);
int i, max_vtsize = 0, max_iid, cur_slot = 0;
GPtrArray *ifaces = NULL;
GHashTable *override_map = NULL;
- gboolean security_enabled = mono_is_security_manager_active ();
+ gboolean security_enabled = mono_security_enabled ();
MonoMethod *cm;
gpointer class_iter;
#if (DEBUG_INTERFACE_VTABLE_CODE|TRACE_INTERFACE_VTABLE_CODE)
g_hash_table_insert (override_map, overrides [i * 2], overrides [i * 2 + 1]);
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_check_override (class, vtable [dslot], decl);
}
}
mono_secman_inheritancedemand_method (cm, m1);
}
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_check_override (class, cm, m1);
slot = mono_method_get_vtable_slot (m1);
mono_method_full_name (overrides [i * 2 + 1], 1), overrides [i * 2 + 1]));
g_hash_table_insert (override_map, decl, overrides [i * 2 + 1]);
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_check_override (class, vtable [decl->slot], decl);
}
}
}
/* CAS - SecurityAction.InheritanceDemand */
- if (mono_is_security_manager_active () && class->parent && (class->parent->flags & TYPE_ATTRIBUTE_HAS_SECURITY)) {
+ if (mono_security_enabled () && class->parent && (class->parent->flags & TYPE_ATTRIBUTE_HAS_SECURITY)) {
mono_secman_inheritancedemand_class (class, class->parent);
}
setup_interface_offsets (class, 0, TRUE);
}
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_check_inheritance (class);
if (mono_loader_get_last_error ()) {
init_com_from_comimport (MonoClass *class)
{
/* we don't always allow COM initialization under the CoreCLR (e.g. Moonlight does not require it) */
- if ((mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)) {
+ if (mono_security_core_clr_enabled ()) {
/* but some other CoreCLR user could requires it for their platform (i.e. trusted) code */
if (!mono_security_core_clr_determine_platform_image (class->image)) {
/* but it can not be made available for application (i.e. user code) since all COM calls
return;
}
}
+
/* FIXME : we should add an extra checks to ensure COM can be initialized properly before continuing */
mono_init_com_types ();
}
gpointer exception_data = mono_class_get_exception_data (klass);
switch (klass->exception_type) {
+#ifndef DISABLE_SECURITY
case MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND: {
MonoDomain *domain = mono_domain_get ();
MonoSecurityManager* secman = mono_security_manager_get_methods ();
mono_runtime_invoke (secman->inheritsecurityexception, NULL, args, &exc);
return (MonoException*) exc;
}
+#endif
case MONO_EXCEPTION_TYPE_LOAD: {
MonoString *name;
MonoException *ex;
/* extra safety under CoreCLR - the runtime does not verify the strongname signatures
* anywhere so untrusted friends are not safe to access platform's code internals */
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+ if (mono_security_core_clr_enabled ()) {
if (!mono_security_core_clr_can_access_internals (accessing->image, accessed->image))
return FALSE;
}
*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 */
-
static void
object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*))
{
-#if HAVE_BOEHM_GC
- guint offset = 0;
MonoDomain *domain;
if (obj == NULL)
mono_raise_exception (mono_get_exception_argument_null ("obj"));
-
- domain = obj->vtable->domain;
-#ifndef GC_DEBUG
- /* This assertion is not valid when GC_DEBUG is defined */
- g_assert (GC_base (obj) == (char*)obj - offset);
-#endif
+ domain = obj->vtable->domain;
+#if HAVE_BOEHM_GC
if (mono_domain_is_unloading (domain) && (callback != NULL))
/*
* Can't register finalizers in a dying appdomain, since they
mono_domain_finalizers_unlock (domain);
- GC_REGISTER_FINALIZER_NO_ORDER ((char*)obj - offset, callback, GUINT_TO_POINTER (offset), NULL, NULL);
+ mono_gc_register_for_finalization (obj, callback);
#elif defined(HAVE_SGEN_GC)
- if (obj == NULL)
- mono_raise_exception (mono_get_exception_argument_null ("obj"));
-
/*
* If we register finalizers for domains that are unloading we might
* end up running them while or after the domain is being cleared, so
* the objects will not be valid anymore.
*/
- if (!mono_domain_is_unloading (obj->vtable->domain))
+ if (!mono_domain_is_unloading (domain))
mono_gc_register_for_finalization (obj, callback);
#endif
}
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_raise_exception (mono_get_exception_invalid_operation (
"It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_ensure_reflection_access_field (cf);
return mono_field_get_value_object (domain, cf, obj);
mono_raise_exception (mono_get_exception_invalid_operation (
"It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_ensure_reflection_access_field (cf);
type = mono_field_get_type_checked (cf, &error);
*exc = NULL;
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
mono_security_core_clr_ensure_reflection_access_method (m);
if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
if (type->type == MONO_TYPE_CLASS) {
MonoClass *klass = mono_type_get_class (type);
- if (mono_is_security_manager_active () && !klass->exception_type)
+ if (mono_security_enabled () && !klass->exception_type)
/* Some security problems are detected during generic vtable construction */
mono_class_setup_vtable (klass);
+
/* need to report exceptions ? */
if (throwOnError && klass->exception_type) {
/* report SecurityException (or others) that occured when loading the assembly */
MonoException *exc = mono_class_get_exception_for_failure (klass);
mono_loader_clear_error ();
mono_raise_exception (exc);
- } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
+ } else if (mono_security_enabled () && klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
return NULL;
}
}
MONO_ARCH_SAVE_REGS;
mono_stack_walk_no_il (get_executing, &dest);
+ g_assert (dest);
return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
}
mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+ if (mono_security_core_clr_enabled ()) {
if (!mono_security_core_clr_ensure_delegate_creation (method, throwOnBindFailure))
return NULL;
}
{
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;
handle_enum:
switch (t->type) {
+ /* Can't share these as the argument needs to be loaded using sign/zero extension */
+ /*
case MONO_TYPE_U1:
return &mono_defaults.sbyte_class->byval_arg;
case MONO_TYPE_U2:
return &mono_defaults.int16_class->byval_arg;
case MONO_TYPE_U4:
return &mono_defaults.int32_class->byval_arg;
+ */
case MONO_TYPE_U8:
return &mono_defaults.int64_class->byval_arg;
case MONO_TYPE_BOOLEAN:
- return &mono_defaults.sbyte_class->byval_arg;
+ return &mono_defaults.byte_class->byval_arg;
case MONO_TYPE_CHAR:
- return &mono_defaults.int16_class->byval_arg;
+ return &mono_defaults.uint16_class->byval_arg;
case MONO_TYPE_U:
case MONO_TYPE_PTR:
return &mono_defaults.int_class->byval_arg;
static gboolean
mono_verifier_is_corlib (MonoImage *image)
{
- gboolean trusted_location = (mono_security_get_mode () != MONO_SECURITY_MODE_CORE_CLR) ?
+ gboolean trusted_location = !mono_security_core_clr_enabled () ?
TRUE : mono_security_core_clr_is_platform_image (image);
return trusted_location && image->module_name && !strcmp ("mscorlib.dll", image->module_name);
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
mono_loader_unlock ();
/* Initialization is now complete, we can throw if the InheritanceDemand aren't satisfied */
- if (mono_is_security_manager_active () && (class->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) && raise_on_error)
+ if (mono_security_enabled () && (class->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) && raise_on_error)
mono_raise_exception (mono_class_get_exception_for_failure (class));
/* make sure the parent is initialized */
#elif defined (__native_client__)
+#include <time.h>
+
MonoBoolean
ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngOpen (void)
{
ref = resolve_object (mb->module->image, obj, &handle_class, NULL);
if (!ref)
ex = mono_get_exception_type_load (NULL, NULL);
- else if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ else if (mono_security_core_clr_enabled ())
ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
if (ex) {
gboolean mono_security_core_clr_test = FALSE;
+static MonoSecurityCoreCLROptions security_core_clr_options = MONO_SECURITY_CORE_CLR_OPTIONS_DEFAULT;
+
+/**
+ * mono_security_core_clr_set_options:
+ * @options: the new options for the coreclr system to use
+ *
+ * By default, the CoreCLRs security model forbids execution trough reflection of methods not visible from the calling code.
+ * Even if the method being called is not in a platform assembly. For non moonlight CoreCLR users this restriction does not
+ * make a lot of sense, since the author could have just changed the non platform assembly to allow the method to be called.
+ * This function allows specific relaxations from the default behaviour to be set.
+ *
+ * Use MONO_SECURITY_CORE_CLR_OPTIONS_DEFAULT for the default coreclr coreclr behaviour as used in Moonlight.
+ *
+ * Use MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_REFLECTION to allow transparent code to execute methods and access
+ * fields that are not in platformcode, even if those methods and fields are private or otherwise not visible to the calling code.
+ *
+ * Use MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_DELEGATE to allow delegates to be created that point at methods that are not in
+ * platformcode even if those methods and fields are private or otherwise not visible to the calling code.
+ *
+ */
+void
+mono_security_core_clr_set_options (MonoSecurityCoreCLROptions options) {
+ security_core_clr_options = options;
+}
+
+/**
+ * mono_security_core_clr_get_options:
+ *
+ * Retrieves the current options used by the coreclr system.
+ */
+
+MonoSecurityCoreCLROptions
+mono_security_core_clr_get_options ()
+{
+ return security_core_clr_options;
+}
+
+/*
+ * default_platform_check:
+ *
+ * Default platform check. Always TRUE for current corlib (minimum
+ * trust-able subset) otherwise return FALSE. Any real CoreCLR host
+ * should provide its own callback to define platform code (i.e.
+ * this default is meant for test only).
+ */
+static gboolean
+default_platform_check (const char *image_name)
+{
+ if (mono_defaults.corlib) {
+ return (strcmp (mono_defaults.corlib->name, image_name) == 0);
+ } else {
+ /* this can get called even before we load corlib (e.g. the EXE itself) */
+ const char *corlib = "mscorlib.dll";
+ int ilen = strlen (image_name);
+ int clen = strlen (corlib);
+ return ((ilen >= clen) && (strcmp ("mscorlib.dll", image_name + ilen - clen) == 0));
+ }
+}
+
+static MonoCoreClrPlatformCB platform_callback = default_platform_check;
+
+/*
+ * mono_security_core_clr_determine_platform_image:
+ *
+ * Call the supplied callback (from mono_security_set_core_clr_platform_callback)
+ * to determine if this image represents platform code.
+ */
+gboolean
+mono_security_core_clr_determine_platform_image (MonoImage *image)
+{
+ return platform_callback (image->name);
+}
+
+/*
+ * mono_security_set_core_clr_platform_callback:
+ *
+ * Set the callback function that will be used to determine if an image
+ * is part, or not, of the platform code.
+ */
+void
+mono_security_set_core_clr_platform_callback (MonoCoreClrPlatformCB callback)
+{
+ platform_callback = callback;
+}
+
+/*
+ * mono_security_core_clr_is_platform_image:
+ *
+ * Return the (cached) boolean value indicating if this image represent platform code
+ */
+gboolean
+mono_security_core_clr_is_platform_image (MonoImage *image)
+{
+ return image->core_clr_platform_code;
+}
+
+/* Note: The above functions are outside this guard so that the public API isn't affected. */
+
+#ifndef DISABLE_SECURITY
+
static MonoClass*
security_critical_attribute (void)
{
}
-static MonoSecurityCoreCLROptions security_core_clr_options = MONO_SECURITY_CORE_CLR_OPTIONS_DEFAULT;
-
-/**
- * mono_security_core_clr_set_options:
- * @options: the new options for the coreclr system to use
- *
- * By default, the CoreCLRs security model forbids execution trough reflection of methods not visible from the calling code.
- * Even if the method being called is not in a platform assembly. For non moonlight CoreCLR users this restriction does not
- * make a lot of sense, since the author could have just changed the non platform assembly to allow the method to be called.
- * This function allows specific relaxations from the default behaviour to be set.
- *
- * Use MONO_SECURITY_CORE_CLR_OPTIONS_DEFAULT for the default coreclr coreclr behaviour as used in Moonlight.
- *
- * Use MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_REFLECTION to allow transparent code to execute methods and access
- * fields that are not in platformcode, even if those methods and fields are private or otherwise not visible to the calling code.
- *
- * Use MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_DELEGATE to allow delegates to be created that point at methods that are not in
- * platformcode even if those methods and fields are private or otherwise not visible to the calling code.
- *
- */
-
-void
-mono_security_core_clr_set_options (MonoSecurityCoreCLROptions options) {
- security_core_clr_options = options;
-}
-
-/**
- * mono_security_core_clr_get_options:
- *
- * Retrieves the current options used by the coreclr system.
- */
-
-MonoSecurityCoreCLROptions
-mono_security_core_clr_get_options ()
-{
- return security_core_clr_options;
-}
-
-
/*
* check_field_access:
*
}
/*
- * mono_security_core_clr_is_platform_image:
+ * mono_security_enable_core_clr:
*
- * Return the (cached) boolean value indicating if this image represent platform code
+ * Enable the verifier and the CoreCLR security model
*/
-gboolean
-mono_security_core_clr_is_platform_image (MonoImage *image)
+void
+mono_security_enable_core_clr ()
{
- return image->core_clr_platform_code;
+ mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
+ mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR);
}
-/*
- * default_platform_check:
- *
- * Default platform check. Always TRUE for current corlib (minimum
- * trust-able subset) otherwise return FALSE. Any real CoreCLR host
- * should provide its own callback to define platform code (i.e.
- * this default is meant for test only).
- */
-static gboolean
-default_platform_check (const char *image_name)
+#else
+
+void
+mono_security_core_clr_check_inheritance (MonoClass *class)
{
- if (mono_defaults.corlib) {
- return (strcmp (mono_defaults.corlib->name, image_name) == 0);
- } else {
- /* this can get called even before we load corlib (e.g. the EXE itself) */
- const char *corlib = "mscorlib.dll";
- int ilen = strlen (image_name);
- int clen = strlen (corlib);
- return ((ilen >= clen) && (strcmp ("mscorlib.dll", image_name + ilen - clen) == 0));
- }
}
-static MonoCoreClrPlatformCB platform_callback = default_platform_check;
+void
+mono_security_core_clr_check_override (MonoClass *class, MonoMethod *override, MonoMethod *base)
+{
+}
-/*
- * mono_security_core_clr_determine_platform_image:
- *
- * Call the supplied callback (from mono_security_set_core_clr_platform_callback)
- * to determine if this image represents platform code.
- */
gboolean
-mono_security_core_clr_determine_platform_image (MonoImage *image)
+mono_security_core_clr_require_elevated_permissions (void)
{
- return platform_callback (image->name);
+ return FALSE;
}
-/*
- * mono_security_enable_core_clr:
- *
- * Enable the verifier and the CoreCLR security model
- */
void
-mono_security_enable_core_clr ()
+mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field)
{
- mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
- mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR);
}
-/*
- * mono_security_set_core_clr_platform_callback:
- *
- * Set the callback function that will be used to determine if an image
- * is part, or not, of the platform code.
- */
void
-mono_security_set_core_clr_platform_callback (MonoCoreClrPlatformCB callback)
+mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method)
+{
+}
+
+gboolean
+mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, gboolean throwOnBindFailure)
+{
+ return TRUE;
+}
+
+MonoException*
+mono_security_core_clr_ensure_dynamic_method_resolved_object (gpointer ref, MonoClass *handle_class)
+{
+ return NULL;
+}
+
+gboolean
+mono_security_core_clr_can_access_internals (MonoImage *accessing, MonoImage* accessed)
+{
+ return TRUE;
+}
+
+MonoException*
+mono_security_core_clr_is_field_access_allowed (MonoMethod *caller, MonoClassField *field)
+{
+ return NULL;
+}
+
+MonoException*
+mono_security_core_clr_is_call_allowed (MonoMethod *caller, MonoMethod *callee)
+{
+ return NULL;
+}
+
+MonoSecurityCoreCLRLevel
+mono_security_core_clr_class_level (MonoClass *class)
+{
+ return MONO_SECURITY_CORE_CLR_TRANSPARENT;
+}
+
+MonoSecurityCoreCLRLevel
+mono_security_core_clr_method_level (MonoMethod *method, gboolean with_class_level)
+{
+ return MONO_SECURITY_CORE_CLR_TRANSPARENT;
+}
+
+void
+mono_security_enable_core_clr ()
{
- platform_callback = callback;
}
+#endif /* DISABLE_SECURITY */
#include "security-manager.h"
-
-/* Internal stuff */
-
-static MonoSecurityManager secman;
+static MonoSecurityMode mono_security_mode = MONO_SECURITY_MODE_NONE;
static MonoBoolean mono_security_manager_activated = FALSE;
static MonoBoolean mono_security_manager_enabled = TRUE;
static MonoBoolean mono_security_manager_execution = TRUE;
-static MonoSecurityMode mono_security_mode = MONO_SECURITY_MODE_NONE;
-
-
-/* Public stuff */
void
mono_security_set_mode (MonoSecurityMode mode)
return mono_security_mode;
}
+/*
+ * Note: The security manager is activate once when executing the Mono. This
+ * is not meant to be a turn on/off runtime switch.
+ */
+void
+mono_activate_security_manager (void)
+{
+ mono_security_manager_activated = TRUE;
+}
+
+gboolean
+mono_is_security_manager_active (void)
+{
+ return mono_security_manager_activated;
+}
+
+#ifndef DISABLE_SECURITY
+
+static MonoSecurityManager secman;
+
MonoSecurityManager*
mono_security_manager_get_methods (void)
{
}
}
+#else
+
+MonoSecurityManager*
+mono_security_manager_get_methods (void)
+{
+ return NULL;
+}
-/*
- * Note: The security manager is activate once when executing the Mono. This
- * is not meant to be a turn on/off runtime switch.
- */
void
-mono_activate_security_manager (void)
+mono_secman_inheritancedemand_class (MonoClass *klass, MonoClass *parent)
{
- mono_security_manager_activated = TRUE;
}
-gboolean
-mono_is_security_manager_active (void)
+void
+mono_secman_inheritancedemand_method (MonoMethod *override, MonoMethod *base)
{
- return mono_security_manager_activated;
}
+#endif /* DISABLE_SECURITY */
+
/*
* @publickey An encoded (with header) public key
* @size The length of the public key
MonoClass *suppressunmanagedcodesecurity; /* System.Security.SuppressUnmanagedCodeSecurityAttribute */
} MonoSecurityManager;
-/* Initialization/utility functions */
-void mono_activate_security_manager (void) MONO_INTERNAL;
-gboolean mono_is_security_manager_active (void) MONO_INTERNAL;
-MonoSecurityManager* mono_security_manager_get_methods (void) MONO_INTERNAL;
gboolean mono_is_ecma_key (const char *publickey, int size) MONO_INTERNAL;
MonoMethod* mono_get_context_capture_method (void) MONO_INTERNAL;
void mono_secman_inheritancedemand_class (MonoClass *klass, MonoClass *parent) MONO_INTERNAL;
void mono_secman_inheritancedemand_method (MonoMethod *override, MonoMethod *base) MONO_INTERNAL;
+/* Initialization/utility functions */
+void mono_activate_security_manager (void) MONO_INTERNAL;
+MonoSecurityManager* mono_security_manager_get_methods (void) MONO_INTERNAL;
+
/* Security mode */
+gboolean mono_is_security_manager_active (void) MONO_INTERNAL;
void mono_security_set_mode (MonoSecurityMode mode) MONO_INTERNAL;
MonoSecurityMode mono_security_get_mode (void) MONO_INTERNAL;
void ves_icall_System_Security_SecurityManager_set_CheckExecutionRights (MonoBoolean value) MONO_INTERNAL;
MonoBoolean ves_icall_System_Security_SecurityManager_GetLinkDemandSecurity (MonoReflectionMethod *m, MonoDeclSecurityActions *kactions, MonoDeclSecurityActions *mactions) MONO_INTERNAL;
+#ifndef DISABLE_SECURITY
+#define mono_security_enabled() (mono_is_security_manager_active ())
+#define mono_security_cas_enabled() (mono_security_get_mode () == MONO_SECURITY_MODE_CAS)
+#define mono_security_core_clr_enabled() (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+#define mono_security_smcs_hack_enabled() (mono_security_get_mode () == MONO_SECURITY_MODE_SMCS_HACK)
+#else
+#define mono_security_enabled() (FALSE)
+#define mono_security_cas_enabled() (FALSE)
+#define mono_security_core_clr_enabled() (FALSE)
+#define mono_security_smcs_hack_enabled() (FALSE)
+#endif
#endif /* _MONO_METADATA_SECURITY_MANAGER_H_ */
dyn_array_int_init (&merge_array);
current_time = 0;
+ /*
+ First we insert all bridges into the hash table and then we do dfs1.
+
+ It must be done in 2 steps since the bridge arrays doesn't come in reverse topological order,
+ which means that we can have entry N pointing to entry N + 1.
+
+ If we dfs1 entry N before N + 1 is registered we'll not consider N + 1 for this bridge
+ pass and not create the required xref between the two.
+ */
+ for (i = 0; i < registered_bridges.size; ++i)
+ register_bridge_object (DYN_ARRAY_PTR_REF (®istered_bridges, i));
+
for (i = 0; i < registered_bridges.size; ++i)
- dfs1 (register_bridge_object (DYN_ARRAY_PTR_REF (®istered_bridges, i)), NULL);
+ dfs1 (get_hash_entry (DYN_ARRAY_PTR_REF (®istered_bridges, i), NULL), NULL);
SGEN_TV_GETTIME (atv);
step_2 = SGEN_TV_ELAPSED (btv, atv);
return cards [(addr - cards_start) >> CARD_BITS];
}
+static void
+update_mod_union (guint8 *dest, gboolean init, guint8 *start_card, guint8 *end_card)
+{
+ size_t num_cards = end_card - start_card;
+ if (init) {
+ memcpy (dest, start_card, num_cards);
+ } else {
+ int i;
+ for (i = 0; i < num_cards; ++i)
+ dest [i] |= start_card [i];
+ }
+}
+
+static guint8*
+alloc_mod_union (size_t num_cards)
+{
+ return sgen_alloc_internal_dynamic (num_cards, INTERNAL_MEM_CARDTABLE_MOD_UNION, TRUE);
+}
+
+guint8*
+sgen_card_table_update_mod_union (guint8 *dest, char *obj, mword obj_size, size_t *out_num_cards)
+{
+ guint8 *result = dest;
+ guint8 *start_card = sgen_card_table_get_card_address ((mword)obj);
+ guint8 *end_card = sgen_card_table_get_card_address ((mword)obj + obj_size - 1) + 1;
+ gboolean init = dest == NULL;
+ size_t num_cards;
+
+#ifdef SGEN_HAVE_OVERLAPPING_CARDS
+ if (end_card < start_card) {
+ guint8 *edge_card = sgen_cardtable + CARD_COUNT_IN_BYTES;
+ size_t num_cards_to_edge = edge_card - start_card;
+
+ num_cards = (end_card + CARD_COUNT_IN_BYTES) - start_card;
+ if (init) {
+ result = dest = alloc_mod_union (num_cards);
+ //g_print ("%d cards for %d bytes: %p\n", num_cards, num_bytes, dest);
+ }
+
+ update_mod_union (dest, init, start_card, edge_card);
+
+ SGEN_ASSERT (0, num_cards == (edge_card - start_card) + (end_card - sgen_cardtable), "wrong number of cards");
+
+ dest += num_cards_to_edge;
+ start_card = sgen_cardtable;
+ } else
+#endif
+ {
+ num_cards = end_card - start_card;
+ if (init)
+ result = dest = alloc_mod_union (num_cards);
+ }
+
+ update_mod_union (dest, init, start_card, end_card);
+
+ if (out_num_cards)
+ *out_num_cards = num_cards;
+
+ return result;
+}
+
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
static void
need_mod_union = sgen_get_major_collector ()->is_concurrent;
}
-#else
-
-void
-sgen_card_table_mark_address (mword address)
-{
- g_assert_not_reached ();
-}
-
-void
-sgen_card_table_mark_range (mword address, mword size)
-{
- g_assert_not_reached ();
-}
-
-guint8*
-mono_gc_get_card_table (int *shift_bits, gpointer *mask)
-{
- return NULL;
-}
-
#endif /*HAVE_SGEN_GC*/
gboolean sgen_card_table_get_card_data (guint8 *dest, mword address, mword cards) MONO_INTERNAL;
+guint8* sgen_card_table_update_mod_union (guint8 *dest, char *obj, mword obj_size, size_t *out_num_cards) MONO_INTERNAL;
+
void sgen_card_table_init (SgenRemeberedSet *remset) MONO_INTERNAL;
/*How many bytes a single card covers*/
suspended right in between setting the content to null and staging the unregister.
The rest of this code cannot handle null links as DISLINK_OBJECT (NULL) produces an invalid address.
+
+ We should simply skip the entry as the staged removal will take place during the next GC.
*/
- if (!*link)
+ if (!*link) {
+ SGEN_LOG (5, "Dislink %p was externally nullified", link);
continue;
+ }
track = DISLINK_TRACK (link);
/*
*/
if (track != before_finalization) {
object = DISLINK_OBJECT (link);
+ /*
+ We should guard against a null object been hidden. This can sometimes happen.
+ */
+ if (!object) {
+ SGEN_LOG (5, "Dislink %p with a hidden null object", link);
+ continue;
+ }
if (!major_collector.is_object_live (object)) {
if (sgen_gc_is_object_ready_for_finalization (object)) {
#include <mono/utils/dtrace.h>
#include <mono/utils/mono-logger-internal.h>
#include <mono/utils/atomic.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/sgen-conf.h>
#define LOCK_DECLARE(name) mono_mutex_t name
/* if changing LOCK_INIT to something that isn't idempotent, look at
its use in mono_gc_base_init in sgen-gc.c */
-#define LOCK_INIT(name) mono_mutex_init (&(name), NULL)
+#define LOCK_INIT(name) mono_mutex_init (&(name))
#define LOCK_GC do { \
mono_mutex_lock (&gc_mutex); \
MONO_GC_LOCKED (); \
queue->locked = locked;
if (locked) {
-#ifdef HOST_WIN32
- /*
- * mono_mutex_t is a critical section on Win32, which
- * is recursive by default. mono_mutexattr_t is not
- * defined there.
- */
- mono_mutex_init (&queue->lock, NULL);
-#else
- mono_mutexattr_t attr;
- mono_mutexattr_init (&attr);
- mono_mutexattr_settype (&attr, MONO_MUTEX_RECURSIVE);
- mono_mutex_init (&queue->lock, &attr);
-#endif
+ mono_mutex_init_recursive (&queue->lock);
}
#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
LOSObject *obj;
for (obj = los_object_list; obj; obj = obj->next) {
- guint8 *start_card = sgen_card_table_get_card_address ((mword)obj->data);
- guint8 *end_card = sgen_card_table_get_card_address ((mword)obj->data + obj->size - 1) + 1;
- size_t num_cards = end_card - start_card;
-
- if (!obj->cardtable_mod_union) {
- obj->cardtable_mod_union = sgen_alloc_internal_dynamic (num_cards,
- INTERNAL_MEM_CARDTABLE_MOD_UNION, TRUE);
- memcpy (obj->cardtable_mod_union, start_card, num_cards);
- } else {
- int i;
- for (i = 0; i < num_cards; ++i)
- obj->cardtable_mod_union [i] |= start_card [i];
- }
+ obj->cardtable_mod_union = sgen_card_table_update_mod_union (obj->cardtable_mod_union,
+ obj->data, obj->size, NULL);
}
}
MSBlockInfo *block;
FOREACH_BLOCK (block) {
- guint8 *cards;
- gboolean init = FALSE;
+ size_t num_cards;
- if (!block->cardtable_mod_union) {
- block->cardtable_mod_union = sgen_alloc_internal_dynamic (CARDS_PER_BLOCK,
- INTERNAL_MEM_CARDTABLE_MOD_UNION, TRUE);
- init = TRUE;
- }
+ block->cardtable_mod_union = sgen_card_table_update_mod_union (block->cardtable_mod_union,
+ block->block, MS_BLOCK_SIZE, &num_cards);
- cards = sgen_card_table_get_card_address ((mword)block->block);
- if (init) {
- memcpy (block->cardtable_mod_union, cards, CARDS_PER_BLOCK);
- } else {
- int i;
- for (i = 0; i < CARDS_PER_BLOCK; ++i)
- block->cardtable_mod_union [i] |= cards [i];
- }
+ SGEN_ASSERT (0, num_cards == CARDS_PER_BLOCK, "Number of cards calculation is wrong");
} END_FOREACH_BLOCK;
}
for (i = 0; i < workers_num; ++i) {
/* private gray queue is inited by the thread itself */
- mono_mutex_init (&workers_data [i].stealable_stack_mutex, NULL);
+ mono_mutex_init (&workers_data [i].stealable_stack_mutex);
workers_data [i].stealable_stack_fill = 0;
if (sgen_get_major_collector ()->alloc_worker_data)
/* if the thread is not in the hash it has been removed already */
if (!handle_remove (thread)) {
+ if (thread == mono_thread_internal_current ()) {
+ mono_domain_unset ();
+ mono_memory_barrier ();
+ }
/* This needs to be called even if handle_remove () fails */
if (mono_thread_cleanup_fn)
mono_thread_cleanup_fn (thread);
mono_profiler_thread_end (thread->tid);
+ if (thread == mono_thread_internal_current ()) {
+ /*
+ * This will signal async signal handlers that the thread has exited.
+ * The profiler callback needs this to be set, so it cannot be done earlier.
+ */
+ mono_domain_unset ();
+ mono_memory_barrier ();
+ }
+
if (thread == mono_thread_internal_current ())
mono_thread_pop_appdomain_ref ();
THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper terminating", __func__, GetCurrentThreadId ()));
- thread_cleanup (internal);
-
/* Do any cleanup needed for apartment state. This
* cannot be done in thread_cleanup since thread_cleanup could be
* called for a thread other than the current thread.
* for the current thead */
mono_thread_cleanup_apartment_state ();
+ thread_cleanup (internal);
+
/* Remove the reference to the thread object in the TLS data,
* so the thread object can be finalized. This won't be
* reached if the thread threw an uncaught exception, so those
* to TLS data.)
*/
SET_CURRENT_OBJECT (NULL);
- mono_domain_unset ();
return(0);
}
mono_thread_create_internal (domain, func, arg, FALSE, FALSE, 0);
}
+#if defined(HOST_WIN32) && defined(__GNUC__)
+static __inline__ __attribute__((always_inline))
+/* This is not defined by gcc */
+unsigned long long
+__readfsdword (unsigned long long offset)
+{
+ unsigned long long value;
+ __asm__("movl %%fs:%a[offset], %k[value]" : [value] "=q" (value) : [offset] "irm" (offset));
+ return value;
+}
+#endif
+
/*
* mono_thread_get_stack_bounds:
*
*staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
return;
/* FIXME: simplify the mess below */
-#elif !defined(HOST_WIN32)
+#elif defined(HOST_WIN32)
+ /* http://en.wikipedia.org/wiki/Win32_Thread_Information_Block */
+ void* tib = (void*)__readfsdword(0x18);
+ guint8 *stackTop = (guint8*)*(int*)((char*)tib + 4);
+ guint8 *stackBottom = (guint8*)*(int*)((char*)tib + 8);
+
+ *staddr = stackBottom;
+ *stsize = stackTop - stackBottom;
+ return;
+#else
pthread_attr_t attr;
guint8 *current = (guint8*)&attr;
+ *staddr = NULL;
+ *stsize = (size_t)-1;
+
pthread_attr_init (&attr);
# ifdef HAVE_PTHREAD_GETATTR_NP
pthread_getattr_np (pthread_self(), &attr);
# endif
pthread_attr_destroy (&attr);
-#else
- *staddr = NULL;
- *stsize = (size_t)-1;
#endif
/* When running under emacs, sometimes staddr is not aligned to a page size */
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 ();
mono_verifier_is_class_full_trust (MonoClass *klass)
{
/* under CoreCLR code is trusted if it is part of the "platform" otherwise all code inside the GAC is trusted */
- gboolean trusted_location = (mono_security_get_mode () != MONO_SECURITY_MODE_CORE_CLR) ?
+ gboolean trusted_location = !mono_security_core_clr_enabled () ?
(klass->image->assembly && klass->image->assembly->in_gac) : mono_security_core_clr_is_platform_image (klass->image);
if (verify_all && verifier_mode == MONO_VERIFIER_MODE_OFF)
exceptions-sparc.c \
tramp-sparc.c
-s390_sources = \
- mini-s390.c \
- mini-s390.h \
- exceptions-s390.c \
- tramp-s390.c
-
s390x_sources = \
mini-s390x.c \
mini-s390x.h \
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
arch_define=__sparc__
endif
-if S390
-arch_sources = $(s390_sources)
-arch_built=cpu-s390.h
-arch_define=__s390__
-endif
-
if S390x
arch_sources = $(s390x_sources)
arch_built=cpu-s390x.h
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)
cpu-sparc.h: cpu-sparc.md genmdesc$(EXEEXT)
$(GENMDESC_PRG) cpu-sparc.h sparc_desc $(srcdir)/cpu-sparc.md
-cpu-s390.h: cpu-s390.md genmdesc$(EXEEXT)
- $(GENMDESC_PRG) cpu-s390.h s390_cpu_desc $(srcdir)/cpu-s390.md
-
cpu-s390x.h: cpu-s390x.md genmdesc$(EXEEXT)
$(GENMDESC_PRG) cpu-s390x.h s390x_cpu_desc $(srcdir)/cpu-s390x.md
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
$(arm_sources) cpu-arm.md \
$(mips_sources) cpu-mips.md \
$(sparc_sources) cpu-sparc.md \
- $(s390_sources) cpu-s390.md \
$(s390x_sources) cpu-s390x.md \
$(ia64_sources) cpu-ia64.md \
$(windows_sources) \
fprintf (acfg->fp, "add r0, r0, #%d\n", (int)sizeof (MonoObject));
fprintf (acfg->fp, "b %s\n", call_target);
fprintf (acfg->fp, ".arm\n");
+ fprintf (acfg->fp, ".align 2\n");
return;
}
if (assembly->image->dynamic || assembly->ref_only)
return;
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS)
+ if (mono_security_cas_enabled ())
return;
mono_aot_lock ();
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
+}
+++ /dev/null
-# S/390 64-bit cpu description file
-# this file is read by genmdesc to pruduce a table with all the relevant information
-# about the cpu instructions that may be used by the regsiter allocator, the scheduler
-# and other parts of the arch-dependent part of mini.
-#
-# An opcode name is followed by a colon and optional specifiers.
-# A specifier has a name, a colon and a value. Specifiers are separated by white space.
-# Here is a description of the specifiers valid for this file and their possible values.
-#
-# dest:register describes the destination register of an instruction
-# src1:register describes the first source register of an instruction
-# src2:register describes the second source register of an instruction
-#
-# register may have the following values:
-# i integer register
-# a r3 register (output from calls)
-# b base register (used in address references)
-# f floating point register
-#
-# len:number describe the maximun length in bytes of the instruction
-# number is a positive integer
-#
-# cost:number describe how many cycles are needed to complete the instruction (unused)
-#
-# clob:spec describe if the instruction clobbers registers or has special needs
-#
-# spec can be one of the following characters:
-# c clobbers caller-save registers
-# r 'reserves' the destination register until a later instruction unreserves it
-# used mostly to set output registers in function calls
-#
-# flags:spec describe if the instruction uses or sets the flags (unused)
-#
-# spec can be one of the following chars:
-# s sets the flags
-# u uses the flags
-# m uses and modifies the flags
-#
-# res:spec describe what units are used in the processor (unused)
-#
-# delay: describe delay slots (unused)
-#
-# the required specifiers are: len, clob (if registers are clobbered), the registers
-# specifiers if the registers are actually used, flags (when scheduling is implemented).
-#
-# See the code in mini-x86.c for more details on how the specifiers are used.
-#
-
-nop: len:4
-relaxed_nop: len:4
-
-adc: dest:i src1:i src2:i len:6
-add_ovf_carry: dest:i src1:1 src2:i len:28
-add_ovf_un_carry: dest:i src1:1 src2:i len:28
-addcc: dest:i src1:i src2:i len:6
-aot_const: dest:i len:8
-atomic_add_i4: src1:b src2:i dest:i len:20
-atomic_exchange_i4: src1:b src2:i dest:i len:20
-atomic_add_new_i4: src1:b src2:i dest:i len:24
-br: len:6
-br_reg: src1:i len:8
-break: len:6
-call: dest:o len:6 clob:c
-call_handler: len:12 clob:c
-call_membase: dest:o src1:b len:12 clob:c
-call_reg: dest:o src1:i len:8 clob:c
-ceq: dest:i len:12
-cgt.un: dest:i len:12
-cgt: dest:i len:12
-checkthis: src1:b len:4
-ckfinite: dest:f src1:f len:22
-clt.un: dest:i len:12
-clt: dest:i len:12
-compare: src1:i src2:i len:4
-compare_imm: src1:i len:14
-cond_exc_c: len:8
-cond_exc_eq: len:8
-cond_exc_ge: len:8
-cond_exc_ge_un: len:8
-cond_exc_gt: len:8
-cond_exc_gt_un: len:8
-cond_exc_le: len:8
-cond_exc_le_un: len:8
-cond_exc_lt: len:8
-cond_exc_lt_un: len:8
-cond_exc_nc: len:8
-cond_exc_ne_un: len:8
-cond_exc_no: len:8
-cond_exc_ov: len:8
-endfinally: len: 20
-fcall: dest:g len:10 clob:c
-fcall_membase: dest:g src1:b len:14 clob:c
-fcall_reg: dest:g src1:i len:10 clob:c
-fcompare: src1:f src2:f len:14
-float_add: dest:f src1:f src2:f len:6
-float_beq: len:10
-float_bge: len:10
-float_bge_un: len:8
-float_bgt: len:10
-float_ble: len:10
-float_ble_un: len:8
-float_blt: len:10
-float_blt_un: len:8
-float_bne_un: len:8
-float_bgt_un: len:8
-float_ceq: dest:i src1:f src2:f len:16
-float_cgt: dest:i src1:f src2:f len:16
-float_cgt_un: dest:i src1:f src2:f len:16
-float_clt: dest:i src1:f src2:f len:16
-float_clt_un: dest:i src1:f src2:f len:16
-float_conv_to_i1: dest:i src1:f len:50
-float_conv_to_i2: dest:i src1:f len:50
-float_conv_to_i4: dest:i src1:f len:50
-float_conv_to_i8: dest:l src1:f len:50
-float_conv_to_i: dest:i src1:f len:52
-float_conv_to_r4: dest:f src1:f len:4
-float_conv_to_u1: dest:i src1:f len:62
-float_conv_to_u2: dest:i src1:f len:62
-float_conv_to_u4: dest:i src1:f len:62
-float_conv_to_u8: dest:l src1:f len:62
-float_conv_to_u: dest:i src1:f len:36
-float_div: dest:f src1:f src2:f len:6
-float_div_un: dest:f src1:f src2:f len:6
-float_mul: dest:f src1:f src2:f len:6
-float_neg: dest:f src1:f len:6
-float_not: dest:f src1:f len:6
-float_rem: dest:f src1:f src2:f len:16
-float_rem_un: dest:f src1:f src2:f len:16
-float_sub: dest:f src1:f src2:f len:6
-fmove: dest:f src1:f len:4
-iconst: dest:i len:16
-jmp: len:56
-label: len:0
-lcall: dest:L len:8 clob:c
-lcall_membase: dest:L src1:b len:12 clob:c
-lcall_reg: dest:L src1:i len:8 clob:c
-load_membase: dest:i src1:b len:18
-loadi1_membase: dest:i src1:b len:40
-loadi2_membase: dest:i src1:b len:24
-loadi4_membase: dest:i src1:b len:18
-loadi8_membase: dest:i src1:b
-loadr4_membase: dest:f src1:b len:20
-loadr8_membase: dest:f src1:b len:18
-loadu1_membase: dest:i src1:b len:26
-loadu2_membase: dest:i src1:b len:26
-loadu4_mem: dest:i len:8
-loadu4_membase: dest:i src1:b len:18
-localloc: dest:i src1:i len:72
-long_add: len: 18 dest:l src1:l src2:i clob:1
-long_add_ovf_un: len:22 dest:l src1:l src2:i clob:1
-long_add_ovf: len:28 dest:l src1:l src2:i clob:1
-long_conv_to_ovf_i: dest:i src1:i src2:i len:44
-long_conv_to_r_un: dest:f src1:i src2:i len:37
-long_conv_to_r4: dest:f src1:i len:4
-long_conv_to_r8: dest:f src1:i len:4
-long_mul_ovf: len: 18
-long_mul_ovf_un: len: 18
-long_sub: len: 18 dest:l src1:l src2:i clob:1
-long_sub_ovf_un: len:22 dest:l src1:l src2:i clob:1
-long_sub_ovf: len:36 dest:l src1:l src2:i clob:1
-memory_barrier: len: 10
-move: dest:i src1:i len:4
-bigmul: len:2 dest:l src1:a src2:i
-bigmul_un: len:2 dest:l src1:a src2:i
-endfilter: src1:i len:12
-rethrow: src1:i len:8
-oparglist: src1:i len:20
-r4const: dest:f len:22
-r8const: dest:f len:18
-s390_bkchain: len:16 dest:i src1:i
-s390_move: len:48 dest:b src1:b
-s390_setf4ret: dest:f src1:f len:4
-tls_get: dest:i len:44
-sbb: dest:i src1:i src2:i len:8
-setlret: src1:i src2:i len:12
-sqrt: dest:f src1:f len:4
-start_handler: len:18
-store_membase_imm: dest:b len:32
-store_membase_reg: dest:b src1:i len:18
-storei1_membase_imm: dest:b len:32
-storei1_membase_reg: dest:b src1:i len:18
-storei2_membase_imm: dest:b len:32
-storei2_membase_reg: dest:b src1:i len:18
-storei4_membase_imm: dest:b len:32
-storei4_membase_reg: dest:b src1:i len:18
-storei8_membase_imm: dest:b
-storei8_membase_reg: dest:b src1:i
-storer4_membase_reg: dest:b src1:f len:22
-storer8_membase_reg: dest:b src1:f len:22
-sub_ovf_carry: dest:i src1:1 src2:i len:28
-sub_ovf_un_carry: dest:i src1:1 src2:i len:28
-subcc: dest:i src1:i src2:i len:6
-throw: src1:i len:8
-vcall: len:8 clob:c
-vcall_membase: src1:b len:12 clob:c
-vcall_reg: src1:i len:8 clob:c
-voidcall: len:8 clob:c
-voidcall_membase: src1:b len:12 clob:c
-voidcall_reg: src1:i len:8 clob:c
-
-# 32 bit opcodes
-int_add: dest:i src1:i src2:i len:6
-int_sub: dest:i src1:i src2:i len:6
-int_mul: dest:i src1:i src2:i len:6
-int_div: dest:a src1:i src2:i len:10
-int_div_un: dest:a src1:i src2:i len:12
-int_and: dest:i src1:i src2:i len:6
-int_or: dest:i src1:i src2:i len:4
-int_xor: dest:i src1:i src2:i len:4
-int_rem: dest:d src1:i src2:i len:10
-int_rem_un: dest:d src1:i src2:i len:12
-int_shl: dest:i src1:i src2:i clob:s len:8
-int_shr: dest:i src1:i src2:i clob:s len:8
-int_shr_un: dest:i src1:i src2:i clob:s len:8
-int_add_ovf: len: 24 dest:i src1:i src2:i
-int_add_ovf_un: len: 10 dest:i src1:i src2:i
-int_sub_ovf: len:24 dest:i src1:i src2:i
-int_sub_ovf_un: len:10 dest:i src1:i src2:i
-int_mul_ovf: dest:i src1:i src2:i len:42
-int_mul_ovf_un: dest:i src1:i src2:i len:20
-
-int_neg: dest:i src1:i len:4
-int_not: dest:i src1:i len:8
-int_conv_to_i1: dest:i src1:i len:16
-int_conv_to_i2: dest:i src1:i len:16
-int_conv_to_i4: dest:i src1:i len:2
-int_conv_to_r4: dest:f src1:i len:4
-int_conv_to_r8: dest:f src1:i len:4
-int_conv_to_u1: dest:i src1:i len:8
-int_conv_to_u2: dest:i src1:i len:16
-int_conv_to_u4: dest:i src1:i
-
-int_conv_to_r_un: dest:f src1:i len:30
-
-int_beq: len:8
-int_bge_un: len:8
-int_bge: len:8
-int_bgt_un: len:8
-int_bgt: len:8
-int_ble_un: len:8
-int_ble: len:8
-int_blt_un: len:8
-int_blt: len:8
-int_bne_un: len:8
-
-mul_imm: dest:i src1:i len:20
-adc_imm: dest:i src1:i len:18
-add_imm: dest:i src1:i len:18
-addcc_imm: dest:i src1:i len:18
-and_imm: dest:i src1:i len:16
-div_imm: dest:i src1:i len:24
-div_un_imm: dest:i src1:i len:24
-or_imm: dest:i src1:i len:16
-rem_imm: dest:i src1:i len:24
-rem_un_imm: dest:i src1:i len:24
-sbb_imm: dest:i src1:i len:18
-shl_imm: dest:i src1:i len:8
-shr_imm: dest:i src1:i len:8
-shr_un_imm: dest:i src1:i len:8
-sub_imm: dest:i src1:i len:18
-subcc_imm: dest:i src1:i len:18
-xor_imm: dest:i src1:i len:16
-
-# Linear IR opcodes
-dummy_use: src1:i len:0
-dummy_store: len:0
-not_reached: len:0
-not_null: src1:i len:0
-
-jump_table: dest:i len:16
-
-icompare: src1:i src2:i len:4
-icompare_imm: src1:i len:14
-
-int_ceq: dest:i len:12
-int_cgt_un: dest:i len:12
-int_cgt: dest:i len:12
-int_clt_un: dest:i len:12
-int_clt: dest:i len:12
-
-cond_exc_ic: len:8
-cond_exc_ieq: len:8
-cond_exc_ige: len:8
-cond_exc_ige_un: len:8
-cond_exc_igt: len:8
-cond_exc_igt_un: len:8
-cond_exc_ile: len:8
-cond_exc_ile_un: len:8
-cond_exc_ilt: len:8
-cond_exc_ilt_un: len:8
-cond_exc_inc: len:8
-cond_exc_ine_un: len:8
-cond_exc_ino: len:8
-cond_exc_iov: len:8
-
-int_add_imm: dest:i src1:i len:18
-int_sub_imm: dest:i src1:i len:18
-int_mul_imm: dest:i src1:i len:20
-int_div_imm: dest:i src1:i len:24
-int_div_un_imm: dest:i src1:i len:24
-int_rem_imm: dest:i src1:i len:24
-int_rem_un_imm: dest:i src1:i len:24
-int_and_imm: dest:i src1:i len:16
-int_or_imm: dest:i src1:i len:16
-int_xor_imm: dest:i src1:i len:16
-int_adc_imm: dest:i src1:i len:18
-int_sbb_imm: dest:i src1:i len:18
-int_shl_imm: dest:i src1:i len:8
-int_shr_imm: dest:i src1:i len:8
-int_shr_un_imm: dest:i src1:i len:8
-
-int_adc: dest:i src1:i src2:i len:6
-int_sbb: dest:i src1:i src2:i len:8
-int_addcc: dest:i src1:i src2:i len:6
-int_subcc: dest:i src1:i src2:i len:6
-
-long_conv_to_ovf_i4_2: dest:i src1:i src2:i len:44
-
-vcall2: len:8 clob:c
-vcall2_membase: src1:b len:12 clob:c
-vcall2_reg: src1:i len:8 clob:c
-
-s390_long_add: dest:l src1:i src2:i len:18
-s390_long_add_ovf: dest:l src1:i src2:i len:32
-s390_long_add_ovf_un: dest:l src1:i src2:i len:32
-s390_long_sub: dest:l src1:i src2:i len:18
-s390_long_sub_ovf: dest:l src1:i src2:i len:32
-s390_long_sub_ovf_un: dest:l src1:i src2:i len:32
-s390_long_neg: dest:l src1:i src2:i len:18
-
-s390_int_add_ovf: len:24 dest:i src1:i src2:i
-s390_int_add_ovf_un: len:10 dest:i src1:i src2:i
-s390_int_sub_ovf: len:24 dest:i src1:i src2:i
-s390_int_sub_ovf_un: len:10 dest:i src1:i src2:i
#ifndef DISABLE_DEBUGGER_AGENT
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
/* Definitions to make backporting to 2.6 easier */
//#define MonoInternalThread MonoThread
event_requests = g_ptr_array_new ();
- mono_mutex_init (&debugger_thread_exited_mutex, NULL);
+ mono_mutex_init (&debugger_thread_exited_mutex);
mono_cond_init (&debugger_thread_exited_cond, NULL);
mono_profiler_install ((MonoProfiler*)&debugger_profiler, runtime_shutdown);
static void
suspend_init (void)
{
- mono_mutex_init (&suspend_mutex, NULL);
+ mono_mutex_init (&suspend_mutex);
mono_cond_init (&suspend_cond, NULL);
MONO_SEM_INIT (&suspend_sem, 0);
}
if (error) {
mono_error_set_error (error, MONO_ERROR_GENERIC, "%s", s);
+ g_warning ("%s", s);
g_free (s);
return;
} else {
- g_error ("%s", s);
+ g_warning ("%s", s);
g_free (s);
+ return;
}
}
case CMD_VM_EXIT: {
MonoInternalThread *thread;
DebuggerTlsData *tls;
+#ifdef TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT
MonoClass *env_class;
+#endif
MonoMethod *exit_method = NULL;
gpointer *args;
int exit_code;
#include "declsec.h"
#include "mini.h"
-#ifndef DISABLE_VERIFIER
+#ifndef DISABLE_SECURITY
+
/*
* Does the methods (or it's class) as any declarative security attribute ?
* Is so are they applicable ? (e.g. static class constructor)
return violation;
}
-#else /* DISABLE_JIT */
+#else /* DISABLE_SECURITY */
void
mono_declsec_cache_stack_modifiers (MonoJitInfo *jinfo)
guint32 mono_declsec_linkdemand (MonoDomain *domain, MonoMethod *caller, MonoMethod *callee) MONO_INTERNAL;
+#ifndef DISABLE_SECURITY
+#define mono_security_method_has_declsec(method) (mono_method_has_declsec(method))
+#else
+#define mono_security_method_has_declsec(method) (FALSE)
+#endif
+
#endif /* _MONO_MINI_DECLSEC_H_ */
" --runtime=VERSION Use the VERSION runtime, instead of autodetecting\n"
" --optimize=OPT Turns on or off a specific optimization\n"
" Use --list-opt to get a list of optimizations\n"
+#ifndef DISABLE_SECURITY
" --security[=mode] Turns on the unsupported security manager (off by default)\n"
" mode is one of cas, core-clr, verifiable or validil\n"
+#endif
" --attach=OPTIONS Pass OPTIONS to the attach agent in the runtime.\n"
" Currently the only supported option is 'disable'.\n"
" --llvm, --nollvm Controls whenever the runtime uses LLVM to compile code.\n"
#ifdef HOST_WIN32
int mixed_mode = FALSE;
#endif
+#ifdef __native_client__
+ gboolean nacl_null_checks_off = FALSE;
+#endif
#ifdef MOONLIGHT
#ifndef HOST_WIN32
opt->mdb_optimizations = TRUE;
enable_debugging = TRUE;
} else if (strcmp (argv [i], "--security") == 0) {
+#ifndef DISABLE_SECURITY
mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
mono_security_set_mode (MONO_SECURITY_MODE_CAS);
mono_activate_security_manager ();
+#else
+ fprintf (stderr, "error: --security: not compiled with security manager support");
+ return 1;
+#endif
} else if (strncmp (argv [i], "--security=", 11) == 0) {
+ /* Note: temporary-smcs-hack, validil, and verifiable need to be
+ accepted even if DISABLE_SECURITY is defined. */
+
if (strcmp (argv [i] + 11, "temporary-smcs-hack") == 0) {
mono_security_set_mode (MONO_SECURITY_MODE_SMCS_HACK);
} else if (strcmp (argv [i] + 11, "core-clr") == 0) {
+#ifndef DISABLE_SECURITY
mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR);
+#else
+ fprintf (stderr, "error: --security: not compiled with CoreCLR support");
+ return 1;
+#endif
} else if (strcmp (argv [i] + 11, "core-clr-test") == 0) {
+#ifndef DISABLE_SECURITY
/* fixme should we enable verifiable code here?*/
mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR);
mono_security_core_clr_test = TRUE;
- } else if (strcmp (argv [i] + 11, "cas") == 0){
+#else
+ fprintf (stderr, "error: --security: not compiled with CoreCLR support");
+ return 1;
+#endif
+ } else if (strcmp (argv [i] + 11, "cas") == 0) {
+#ifndef DISABLE_SECURITY
mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
mono_security_set_mode (MONO_SECURITY_MODE_CAS);
mono_activate_security_manager ();
- } else if (strcmp (argv [i] + 11, "validil") == 0) {
+#else
+ fprintf (stderr, "error: --security: not compiled with CAS support");
+ return 1;
+#endif
+ } else if (strcmp (argv [i] + 11, "validil") == 0) {
mono_verifier_set_mode (MONO_VERIFIER_MODE_VALID);
- } else if (strcmp (argv [i] + 11, "verifiable") == 0) {
+ } else if (strcmp (argv [i] + 11, "verifiable") == 0) {
mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE);
- } else {
+ } else {
fprintf (stderr, "error: --security= option has invalid argument (cas, core-clr, verifiable or validil)\n");
return 1;
}
#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
return FALSE;
}
+#if MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
void
mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
{
{
mono_monoctx_to_sigctx (mctx, ctx);
}
+#endif /* MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX */
/*
* handle_exception:
gboolean
mono_arch_handle_exception (void *ctx, gpointer obj)
{
-#if defined(MONO_CROSS_COMPILE)
+#if defined(MONO_CROSS_COMPILE) || !defined(MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX)
g_assert_not_reached ();
#elif defined(MONO_ARCH_USE_SIGACTION)
arm_ucontext *sigctx = ctx;
{
#ifdef MONO_CROSS_COMPILE
g_assert_not_reached ();
+#elif defined(__native_client__)
+ g_assert_not_reached ();
#else
arm_ucontext *my_uc = sigctx;
return (void*) UCONTEXT_REG_PC (my_uc);
+++ /dev/null
-/*------------------------------------------------------------------*/
-/* */
-/* Name - exceptions-s390.c */
-/* */
-/* Function - Exception support for S/390. */
-/* */
-/* Name - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */
-/* */
-/* Date - January, 2004 */
-/* */
-/* Derivation - From exceptions-x86 & exceptions-ppc */
-/* Paolo Molaro (lupus@ximian.com) */
-/* Dietmar Maurer (dietmar@ximian.com) */
-/* */
-/* Copyright - 2001 Ximian, Inc. */
-/* */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* D e f i n e s */
-/*------------------------------------------------------------------*/
-
-#define S390_CALLFILTER_INTREGS S390_MINIMAL_STACK_SIZE
-#define S390_CALLFILTER_FLTREGS S390_CALLFILTER_INTREGS+(16*sizeof(gulong))
-#define S390_CALLFILTER_ACCREGS S390_CALLFILTER_FLTREGS+(16*sizeof(gdouble))
-#define S390_CALLFILTER_SIZE (S390_CALLFILTER_ACCREGS+(16*sizeof(gulong)))
-
-#define S390_THROWSTACK_ACCPRM S390_MINIMAL_STACK_SIZE
-#define S390_THROWSTACK_FPCPRM S390_THROWSTACK_ACCPRM+sizeof(gpointer)
-#define S390_THROWSTACK_RETHROW S390_THROWSTACK_FPCPRM+sizeof(gulong)
-#define S390_THROWSTACK_INTREGS S390_THROWSTACK_RETHROW+sizeof(gboolean)
-#define S390_THROWSTACK_FLTREGS S390_THROWSTACK_INTREGS+(16*sizeof(gulong))
-#define S390_THROWSTACK_ACCREGS S390_THROWSTACK_FLTREGS+(16*sizeof(gdouble))
-#define S390_THROWSTACK_SIZE (S390_THROWSTACK_ACCREGS+(16*sizeof(gulong)))
-
-#define SZ_THROW 384
-
-/*========================= End of Defines =========================*/
-
-/*------------------------------------------------------------------*/
-/* I n c l u d e s */
-/*------------------------------------------------------------------*/
-
-#include <config.h>
-#include <glib.h>
-#include <signal.h>
-#include <string.h>
-#include <ucontext.h>
-
-#include <mono/arch/s390/s390-codegen.h>
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/tabledefs.h>
-#include <mono/metadata/threads.h>
-#include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/exception.h>
-#include <mono/metadata/mono-debug.h>
-
-#include "mini.h"
-#include "mini-s390.h"
-
-/*========================= End of Includes ========================*/
-
-/*------------------------------------------------------------------*/
-/* P r o t o t y p e s */
-/*------------------------------------------------------------------*/
-
-gboolean mono_arch_handle_exception (void *ctx,
- gpointer obj);
-
-/*========================= End of Prototypes ======================*/
-
-/*------------------------------------------------------------------*/
-/* G l o b a l V a r i a b l e s */
-/*------------------------------------------------------------------*/
-
-/*====================== End of Global Variables ===================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_call_filter */
-/* */
-/* Function - Return a pointer to a method which calls an */
-/* exception filter. We also use this function to */
-/* call finally handlers (we pass NULL as @exc */
-/* object in this case). */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
-{
- static guint8 *start;
- static int inited = 0;
- guint8 *code;
- int alloc_size, pos, i;
-
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- if (inited)
- return start;
-
- inited = 1;
- /* call_filter (MonoContext *ctx, unsigned long eip, gpointer exc) */
- code = start = mono_global_codeman_reserve (512);
-
- s390_stm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_lr (code, s390_r14, STK_BASE);
- alloc_size = S390_ALIGN(S390_CALLFILTER_SIZE, S390_STACK_ALIGNMENT);
- s390_ahi (code, STK_BASE, -alloc_size);
- s390_st (code, s390_r14, 0, STK_BASE, 0);
-
- /*------------------------------------------------------*/
- /* save general registers on stack */
- /*------------------------------------------------------*/
- s390_stm (code, s390_r0, s390_r13, STK_BASE, S390_CALLFILTER_INTREGS);
-
- /*------------------------------------------------------*/
- /* save floating point registers on stack */
- /*------------------------------------------------------*/
-// pos = S390_CALLFILTER_FLTREGS;
-// for (i = 0; i < 16; ++i) {
-// s390_std (code, i, 0, STK_BASE, pos);
-// pos += sizeof (gdouble);
-// }
-
- /*------------------------------------------------------*/
- /* save access registers on stack */
- /*------------------------------------------------------*/
-// s390_stam (code, s390_a0, s390_a15, STK_BASE, S390_CALLFILTER_ACCREGS);
-
- /*------------------------------------------------------*/
- /* Get A(Context) */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r13, s390_r2);
-
- /*------------------------------------------------------*/
- /* Get A(Handler Entry Point) */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r0, s390_r3);
-
- /*------------------------------------------------------*/
- /* Set parameter register with Exception */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r2, s390_r4);
-
- /*------------------------------------------------------*/
- /* Load all registers with values from the context */
- /*------------------------------------------------------*/
- s390_lm (code, s390_r3, s390_r12, s390_r13,
- G_STRUCT_OFFSET(MonoContext, uc_mcontext.gregs[3]));
- pos = G_STRUCT_OFFSET(MonoContext, uc_mcontext.fpregs.fprs[0]);
- for (i = 0; i < 16; ++i) {
- s390_ld (code, i, 0, s390_r13, pos);
- pos += sizeof(gdouble);
- }
-
- /*------------------------------------------------------*/
- /* Point at the copied stack frame and call the filter */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r1, s390_r0);
- s390_basr (code, s390_r14, s390_r1);
-
- /*------------------------------------------------------*/
- /* Save return value */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r14, s390_r2);
-
- /*------------------------------------------------------*/
- /* Restore all the regs from the stack */
- /*------------------------------------------------------*/
- s390_lm (code, s390_r0, s390_r13, STK_BASE, S390_CALLFILTER_INTREGS);
-// pos = S390_CALLFILTER_FLTREGS;
-// for (i = 0; i < 16; ++i) {
-// s390_ld (code, i, 0, STK_BASE, pos);
-// pos += sizeof (gdouble);
-// }
-
- s390_lr (code, s390_r2, s390_r14);
-// s390_lam (code, s390_a0, s390_a15, STK_BASE, S390_CALLFILTER_ACCREGS);
- s390_ahi (code, s390_r15, alloc_size);
- s390_lm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_br (code, s390_r14);
-
- g_assert ((code - start) < SZ_THROW);
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - throw_exception. */
-/* */
-/* Function - Raise an exception based on the parameters passed.*/
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp,
- gulong *int_regs, gdouble *fp_regs, gulong *acc_regs,
- guint fpc, gboolean rethrow)
-{
- MonoContext ctx;
- int iReg;
-
- memset(&ctx, 0, sizeof(ctx));
-
- getcontext(&ctx);
-
- /* adjust eip so that it point into the call instruction */
- ip -= 6;
-
- for (iReg = 0; iReg < 16; iReg++) {
- ctx.uc_mcontext.gregs[iReg] = int_regs[iReg];
- ctx.uc_mcontext.fpregs.fprs[iReg].d = fp_regs[iReg];
- ctx.uc_mcontext.aregs[iReg] = acc_regs[iReg];
- }
-
- ctx.uc_mcontext.fpregs.fpc = fpc;
-
- MONO_CONTEXT_SET_BP (&ctx, sp);
- MONO_CONTEXT_SET_IP (&ctx, ip);
-
- if (mono_object_isinst (exc, mono_defaults.exception_class)) {
- MonoException *mono_ex = (MonoException*)exc;
- if (!rethrow)
- mono_ex->stack_trace = NULL;
- }
- mono_arch_handle_exception (&ctx, exc);
- setcontext(&ctx);
-
- g_assert_not_reached ();
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - get_throw_exception_generic */
-/* */
-/* Function - Return a function pointer which can be used to */
-/* raise exceptions. The returned function has the */
-/* following signature: */
-/* void (*func) (MonoException *exc); or, */
-/* void (*func) (char *exc_name); */
-/* */
-/*------------------------------------------------------------------*/
-
-static gpointer
-get_throw_exception_generic (guint8 *start, int size,
- int by_name, gboolean rethrow)
-{
- guint8 *code;
- int alloc_size, pos, i, offset;
-
- code = start;
-
- s390_stm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- alloc_size = S390_ALIGN(S390_THROWSTACK_SIZE, S390_STACK_ALIGNMENT);
- s390_lr (code, s390_r14, STK_BASE);
- s390_ahi (code, STK_BASE, -alloc_size);
- s390_st (code, s390_r14, 0, STK_BASE, 0);
- if (by_name) {
- s390_lr (code, s390_r4, s390_r2);
- s390_bras (code, s390_r13, 6);
- s390_word (code, mono_defaults.corlib);
- s390_word (code, "System");
- s390_l (code, s390_r2, 0, s390_r13, 0);
- s390_l (code, s390_r3, 0, s390_r13, 4);
- offset = (guint32) S390_RELATIVE(mono_exception_from_name, code);
- s390_brasl(code, s390_r14, offset);
- }
- /*------------------------------------------------------*/
- /* save the general registers on the stack */
- /*------------------------------------------------------*/
- s390_stm (code, s390_r0, s390_r13, STK_BASE, S390_THROWSTACK_INTREGS);
-
- s390_lr (code, s390_r1, STK_BASE);
- s390_ahi (code, s390_r1, alloc_size);
- /*------------------------------------------------------*/
- /* save the return address in the parameter register */
- /*------------------------------------------------------*/
- s390_l (code, s390_r3, 0, s390_r1, S390_RET_ADDR_OFFSET);
-
- /*------------------------------------------------------*/
- /* save the floating point registers */
- /*------------------------------------------------------*/
- pos = S390_THROWSTACK_FLTREGS;
- for (i = 0; i < 16; ++i) {
- s390_std (code, i, 0,STK_BASE, pos);
- pos += sizeof (gdouble);
- }
- /*------------------------------------------------------*/
- /* save the access registers */
- /*------------------------------------------------------*/
- s390_stam (code, s390_r0, s390_r15, STK_BASE, S390_THROWSTACK_ACCREGS);
-
- /*------------------------------------------------------*/
- /* call throw_exception (exc, ip, sp, gr, fr, ar) */
- /* exc is already in place in r2 */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r4, s390_r1); /* caller sp */
- /*------------------------------------------------------*/
- /* pointer to the saved int regs */
- /*------------------------------------------------------*/
- s390_la (code, s390_r5, 0, STK_BASE, S390_THROWSTACK_INTREGS);
- s390_la (code, s390_r6, 0, STK_BASE, S390_THROWSTACK_FLTREGS);
- s390_la (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_ACCREGS);
- s390_st (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_ACCPRM);
- s390_stfpc(code, STK_BASE, S390_THROWSTACK_FPCPRM);
- s390_lhi (code, s390_r7, rethrow);
- s390_st (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_RETHROW);
- offset = (guint32) S390_RELATIVE(throw_exception, code);
- s390_brasl(code, s390_r14, offset);
- /* we should never reach this breakpoint */
- s390_break (code);
- g_assert ((code - start) < size);
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - arch_get_throw_exception */
-/* */
-/* Function - Return a function pointer which can be used to */
-/* raise exceptions. The returned function has the */
-/* following signature: */
-/* void (*func) (MonoException *exc); */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
-{
- static guint8 *start;
- static int inited = 0;
-
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- if (inited)
- return start;
- start = mono_global_codeman_reserve (SZ_THROW);
- get_throw_exception_generic (start, SZ_THROW, FALSE, FALSE);
- inited = 1;
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - arch_get_rethrow_exception */
-/* */
-/* Function - Return a function pointer which can be used to */
-/* raise exceptions. The returned function has the */
-/* following signature: */
-/* void (*func) (MonoException *exc); */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
-{
- static guint8 *start;
- static int inited = 0;
-
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- if (inited)
- return start;
- start = mono_global_codeman_reserve (SZ_THROW);
- get_throw_exception_generic (start, SZ_THROW, FALSE, TRUE);
- inited = 1;
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - arch_get_throw_exception_by_name */
-/* */
-/* Function - Return a function pointer which can be used to */
-/* raise corlib exceptions. The return function has */
-/* the following signature: */
-/* void (*func) (char *exc_name); */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_throw_exception_by_name (void)
-{
- static guint8 *start;
- static int inited = 0;
-
- if (inited)
- return start;
- start = mono_global_codeman_reserve (SZ_THROW);
- get_throw_exception_generic (start, SZ_THROW, TRUE, FALSE);
- inited = 1;
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_find_jit_info */
-/* */
-/* Function - See exceptions-amd64.c for docs. */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
- MonoJitInfo *ji, MonoContext *ctx,
- MonoContext *new_ctx, MonoLMF **lmf,
- mgreg_t **save_locations,
- StackFrameInfo *frame)
-{
- gpointer ip = MONO_CONTEXT_GET_IP (ctx);
- MonoS390StackFrame *sframe;
-
- memset (frame, 0, sizeof (StackFrameInfo));
- frame->ji = ji;
-
- *new_ctx = *ctx;
-
- if (ji != NULL) {
- gint32 address;
-
- frame->type = FRAME_TYPE_MANAGED;
-
- if (*lmf && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->ebp)) {
- /* remove any unused lmf */
- *lmf = (*lmf)->previous_lmf;
- }
-
- address = (char *)ip - (char *)ji->code_start;
-
- sframe = (MonoS390StackFrame *) MONO_CONTEXT_GET_SP (ctx);
- MONO_CONTEXT_SET_BP (new_ctx, sframe->prev);
- sframe = (MonoS390StackFrame *) sframe->prev;
- MONO_CONTEXT_SET_IP (new_ctx, (guint8*)sframe->return_address - 2);
- memcpy (&new_ctx->uc_mcontext.gregs[6], sframe->regs, (8*sizeof(gint32)));
- return TRUE;
- } else if (*lmf) {
- if (!(*lmf)->method)
- return FALSE;
-
- ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->eip, NULL);
- if (!ji) {
- // FIXME: This can happen with multiple appdomains (bug #444383)
- return FALSE;
- }
-
- frame->ji = ji;
- frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;
-
- memcpy(new_ctx->uc_mcontext.gregs, (*lmf)->gregs, sizeof((*lmf)->gregs));
- memcpy(new_ctx->uc_mcontext.fpregs.fprs, (*lmf)->fregs, sizeof((*lmf)->fregs));
-
- MONO_CONTEXT_SET_BP (new_ctx, (*lmf)->ebp);
- MONO_CONTEXT_SET_IP (new_ctx, (*lmf)->eip - 2);
- *lmf = (*lmf)->previous_lmf;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_handle_exception */
-/* */
-/* Function - Handle an exception raised by the JIT code. */
-/* */
-/* Parameters - ctx - Saved processor state */
-/* obj - The exception object */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_handle_exception (void *uc, gpointer obj)
-{
- return mono_handle_exception (uc, obj);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_ip_from_context */
-/* */
-/* Function - Return the instruction pointer from the context. */
-/* */
-/* Parameters - sigctx - Saved processor state */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_ip_from_context (void *sigctx)
-{
- return context_get_ip (sigctx);
-}
-
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_restore_context */
-/* */
-/* Function - Return the address of the routine that will rest- */
-/* ore the context. */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
-{
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- return setcontext;
-}
-
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_is_int_overflow */
-/* */
-/* Function - Inspect the code that raised the SIGFPE signal */
-/* to see if the DivideByZero or Arithmetic exception*/
-/* should be raised. */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_is_int_overflow (void *uc, void *info)
-{
- MonoContext *ctx;
- guint8 *code;
- guint32 *operand;
- gboolean arithExc = TRUE;
- gint regNo,
- offset;
-
- ctx = (MonoContext *) uc;
- code = (guint8 *) ((siginfo_t *)info)->si_addr;
- /*----------------------------------------------------------*/
- /* Divide operations are the only ones that will give the */
- /* divide by zero exception so just check for these ops. */
- /*----------------------------------------------------------*/
- switch (code[0]) {
- case 0x1d : /* Divide Register */
- regNo = code[1] & 0x0f;
- if (ctx->uc_mcontext.gregs[regNo] == 0)
- arithExc = FALSE;
- break;
- case 0x5d : /* Divide */
- regNo = (code[2] & 0xf0 >> 8);
- offset = *((guint16 *) code+2) & 0x0fff;
- operand = (guint32*)(ctx->uc_mcontext.gregs[regNo] + offset);
- if (*operand == 0)
- arithExc = FALSE;
- break;
- case 0xb9 : /* Divide logical Register? */
- if (code[1] == 0x97) {
- regNo = (code[2] & 0xf0 >> 8);
- if (ctx->uc_mcontext.gregs[regNo] == 0)
- arithExc = FALSE;
- }
- break;
- case 0xe3 : /* Divide logical? */
- if (code[1] == 0x97) {
- regNo = (code[2] & 0xf0 >> 8);
- offset = *((guint32 *) code+1) & 0x000fffff;
- operand = (guint32*)(ctx->uc_mcontext.gregs[regNo] + offset);
- if (*operand == 0)
- arithExc = FALSE;
- }
- break;
- default:
- arithExc = TRUE;
- }
- ctx->uc_mcontext.psw.addr = (guint32)code;
- return (arithExc);
-}
-
-/*========================= End of Function ========================*/
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 */
return 0;
}
+ public class TAbstractTableItem<TC> {
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void SetProperty<TV> () { }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void Test () {
+ SetProperty<bool> ();
+ }
+ }
+
+ public static int test_0_gsharedvt_method_on_shared_class () {
+ TAbstractTableItem<object>.Test ();
+ return 0;
+ }
}
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:
*;
};
* CAS - do not inline methods with declarative security
* Note: this has to be before any possible return TRUE;
*/
- if (mono_method_has_declsec (method))
+ if (mono_security_method_has_declsec (method))
return FALSE;
#ifdef MONO_ARCH_SOFT_FLOAT
{
guint32 result;
- if ((cfg->method != caller) && mono_method_has_declsec (callee)) {
+ if ((cfg->method != caller) && mono_security_method_has_declsec (callee)) {
return TRUE;
}
dont_verify |= method->wrapper_type == MONO_WRAPPER_COMINTEROP;
dont_verify |= method->wrapper_type == MONO_WRAPPER_COMINTEROP_INVOKE;
- dont_verify |= mono_security_get_mode () == MONO_SECURITY_MODE_SMCS_HACK;
+ dont_verify |= mono_security_smcs_hack_enabled ();
/* still some type unsafety issues in marshal wrappers... (unknown is PtrToStructure) */
dont_verify_stloc = method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE;
}
}
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS)
+ if (mono_security_cas_enabled ())
secman = mono_security_manager_get_methods ();
- security = (secman && mono_method_has_declsec (method));
+ security = (secman && mono_security_method_has_declsec (method));
/* at this point having security doesn't mean we have any code to generate */
if (security && (cfg->method == method)) {
/* Only Demand, NonCasDemand and DemandChoice requires code generation.
mono_emit_method_call (cfg, secman->demandunmanaged, NULL, NULL);
}
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+ if (mono_security_core_clr_enabled ()) {
/* check if this is native code, e.g. an icall or a p/invoke */
if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
MonoMethod *wrapped = mono_marshal_method_from_wrapper (method);
if (cfg->generic_sharing_context && mono_method_check_context_used (cmethod))
GENERIC_SHARING_FAILURE (CEE_JMP);
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS)
+ if (mono_security_cas_enabled ())
CHECK_CFG_EXCEPTION;
#ifdef MONO_ARCH_USE_OP_TAIL_CALL
METHOD_ACCESS_FAILURE;
}
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
ensure_method_is_allowed_to_call_method (cfg, method, cil_method, bblock, ip);
if (!virtual && (cmethod->flags & METHOD_ATTRIBUTE_ABSTRACT))
}
*/
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS) {
+ if (mono_security_cas_enabled ()) {
if (check_linkdemand (cfg, method, cmethod))
INLINE_FAILURE ("linkdemand");
CHECK_CFG_EXCEPTION;
context_used = mini_method_check_context_used (cfg, cmethod);
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS) {
+ if (mono_security_cas_enabled ()) {
if (check_linkdemand (cfg, method, cmethod))
INLINE_FAILURE ("linkdemand");
CHECK_CFG_EXCEPTION;
- } else if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+ } else if (mono_security_core_clr_enabled ()) {
ensure_method_is_allowed_to_call_method (cfg, method, cmethod, bblock, ip);
}
UNVERIFIED;
/* if the class is Critical then transparent code cannot access it's fields */
- if (!is_instance && mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (!is_instance && mono_security_core_clr_enabled ())
ensure_method_is_allowed_to_access_field (cfg, method, field, bblock, ip);
/* XXX this is technically required but, so far (SL2), no [SecurityCritical] types (not many exists) have
any visible *instance* field (in fact there's a single case for a static field in Marshal) XXX
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
ensure_method_is_allowed_to_access_field (cfg, method, field, bblock, ip);
*/
if (!dont_verify && !cfg->skip_visibility && !mono_method_can_access_method (method, cmethod))
METHOD_ACCESS_FAILURE;
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS) {
+ if (mono_security_cas_enabled ()) {
if (check_linkdemand (cfg, method, cmethod))
INLINE_FAILURE ("linkdemand");
CHECK_CFG_EXCEPTION;
- } else if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+ } else if (mono_security_core_clr_enabled ()) {
ensure_method_is_allowed_to_call_method (cfg, method, cmethod, bblock, ip);
- }
+ }
/*
* Optimize the common case of ldftn+delegate creation
target_ins = sp [-1];
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+ if (mono_security_core_clr_enabled ())
ensure_method_is_allowed_to_call_method (cfg, method, ctor_method, bblock, ip);
if (!(cmethod->flags & METHOD_ATTRIBUTE_STATIC)) {
context_used = mini_method_check_context_used (cfg, cmethod);
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS) {
+ if (mono_security_cas_enabled ()) {
if (check_linkdemand (cfg, method, cmethod))
INLINE_FAILURE ("linkdemand");
CHECK_CFG_EXCEPTION;
- } else if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+ } else if (mono_security_core_clr_enabled ()) {
ensure_method_is_allowed_to_call_method (cfg, method, cmethod, bblock, ip);
}
/* 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
# if defined(__s390x__)
# include "mini-s390x.h"
# else
-# include "mini-s390.h"
+#error "s390 is no longer supported."
# endif
#elif defined(__ia64__)
#include "mini-ia64.h"
#include "mono/arch/arm/arm-fpa-codegen.h"
#include "mono/arch/arm/arm-vfp-codegen.h"
-#if defined(__ARM_EABI__) && defined(__linux__) && !defined(PLATFORM_ANDROID)
+#if defined(__ARM_EABI__) && defined(__linux__) && !defined(PLATFORM_ANDROID) && !defined(__native_client__)
#define HAVE_AEABI_READ_TP 1
#endif
#define IS_SOFT_FLOAT 0
#endif
+#ifdef __native_client_codegen__
+const guint kNaClAlignment = kNaClAlignmentARM;
+const guint kNaClAlignmentMask = kNaClAlignmentMaskARM;
+gint8 nacl_align_byte = -1; /* 0xff */
+
+guint8 *
+mono_arch_nacl_pad (guint8 *code, int pad)
+{
+ /* Not yet properly implemented. */
+ g_assert_not_reached ();
+ return code;
+}
+
+guint8 *
+mono_arch_nacl_skip_nops (guint8 *code)
+{
+ /* Not yet properly implemented. */
+ g_assert_not_reached ();
+ return code;
+}
+
+#endif /* __native_client_codegen__ */
+
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
#if __APPLE__
return "unknown";
}
-#ifndef DISABLE_JIT
+#ifndef DISABLE_JIT
static guint8*
emit_big_add (guint8 *code, int dreg, int sreg, int imm)
{
mono_arch_init (void)
{
InitializeCriticalSection (&mini_arch_mutex);
-
+#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
if (mini_get_debug_options ()->soft_breakpoints) {
single_step_func_wrapper = create_function_wrapper (debugger_agent_single_step_from_context);
breakpoint_func_wrapper = create_function_wrapper (debugger_agent_breakpoint_from_context);
} else {
+#else
+ {
+#endif
ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
mono_mprotect (bp_trigger_page, mono_pagesize (), 0);
void
mono_arch_flush_icache (guint8 *code, gint size)
{
+#if defined(__native_client__)
+ // For Native Client we don't have to flush i-cache here,
+ // as it's being done by dyncode interface.
+#else
+
#ifdef MONO_CROSS_COMPILE
#elif __APPLE__
sys_icache_invalidate (code, size);
: "r" (code), "r" (code + size), "r" (0)
: "r0", "r1", "r3" );
#endif
+#endif /* !__native_client__ */
}
typedef enum {
return mono_arm_get_exception_trampolines (aot);
}
+
+#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
/*
* mono_arch_set_breakpoint:
*
MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + 4);
}
+#endif /* MONO_ARCH_SOFT_DEBUG_SUPPORTED */
+
/*
* mono_arch_get_seq_point_info:
*
#include <mono/utils/mono-context.h>
#include <glib.h>
+#ifdef __native_client_codegen__
+#define kNaClAlignmentARM 16
+#define kNaClAlignmentMaskARM (kNaClAlignmentARM - 1)
+#define kNaClLengthOfCallImm 4
+#endif
+
#if defined(ARM_FPU_NONE) || (defined(__ARM_EABI__) && !defined(ARM_FPU_VFP) && !defined(ARM_FPU_VFP_HARD))
#define MONO_ARCH_SOFT_FLOAT 1
#endif
#define ARM_LAST_ARG_REG 3
#define MONO_ARCH_USE_SIGACTION 1
+
+#if defined(__native_client__)
+#undef MONO_ARCH_USE_SIGACTION
+#endif
+
#define MONO_ARCH_NEED_DIV_CHECK 1
#define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
#define MONO_ARCH_GSHAREDVT_SUPPORTED 1
#define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1
+#if defined(__native_client__)
+#undef MONO_ARCH_SOFT_DEBUG_SUPPORTED
+#undef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
+#undef MONO_ARCH_HAVE_CONTEXT_SET_INT_REG
+#endif
+
/* Matches the HAVE_AEABI_READ_TP define in mini-arm.c */
-#if defined(__ARM_EABI__) && defined(__linux__) && !defined(TARGET_ANDROID)
+#if defined(__ARM_EABI__) && defined(__linux__) && !defined(TARGET_ANDROID) && !defined(__native_client__)
#define MONO_ARCH_HAVE_TLS_GET 1
#endif
#endif
#endif /* __MONO_MINI_ARM_H__ */
-
sa.ss_sp = tls->signal_stack;
sa.ss_size = MONO_ARCH_SIGNAL_STACK_SIZE;
-#if __APPLE__
sa.ss_flags = 0;
-#else
- sa.ss_flags = SS_ONSTACK;
-#endif
g_assert (sigaltstack (&sa, NULL) == 0);
mono_gc_register_altstack ((char*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size, (char*)staddr + stsize - ((char*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size), tls->signal_stack, tls->signal_stack_size);
} 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;
#endif /* DISABLE_JIT */
-void
-mini_gc_enable_gc_maps_for_aot (void)
-{
-}
-
#endif
#ifndef DISABLE_JIT
#endif
if (binl != -1) {
char *base;
- char *name;
+ char *resolvedname, *name;
buf [binl] = 0;
- base = g_path_get_dirname (buf);
+ resolvedname = mono_path_resolve_symlinks (buf);
+ base = g_path_get_dirname (resolvedname);
name = g_strdup_printf ("%s/.libs", base);
err = NULL;
llvm_lib = try_llvm_load (name, &err);
g_free (name);
}
g_free (base);
+ g_free (resolvedname);
}
if (!llvm_lib) {
llvm_lib = try_llvm_load (NULL, &err);
/* #if defined(__native_client_codegen__) || defined(__native_client__) */
/* We have to define these in terms of the TARGET defines, not NaCl defines */
/* because genmdesc.pl doesn't have multiple defines per platform. */
-#if defined(TARGET_AMD64) || defined(TARGET_X86)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM)
MINI_OP(OP_NACL_GC_SAFE_POINT, "nacl_gc_safe_point", IREG, NONE, NONE)
#endif
{
}
+pid_t
+mono_runtime_syscall_fork (void)
+{
+ g_assert_not_reached();
+ return 0;
+}
+void
+mono_gdb_render_native_backtraces (pid_t crashed_pid)
+{
+}
#else
+++ /dev/null
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mini-s390.c */
-/* */
-/* Function - S/390 backend for the Mono code generator. */
-/* */
-/* Name - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */
-/* */
-/* Date - January, 2004 */
-/* */
-/* Derivation - From mini-x86 & mini-ppc by - */
-/* Paolo Molaro (lupus@ximian.com) */
-/* Dietmar Maurer (dietmar@ximian.com) */
-/* */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* D e f i n e s */
-/*------------------------------------------------------------------*/
-
-#define EMIT_COND_BRANCH(ins,cond) \
-{ \
-if (ins->inst_true_bb->native_offset) { \
- int displace; \
- displace = ((cfg->native_code + \
- ins->inst_true_bb->native_offset) - code) / 2; \
- if (s390_is_imm16(displace)) { \
- s390_brc (code, cond, displace); \
- } else { \
- s390_jcl (code, cond, displace); \
- } \
-} else { \
- mono_add_patch_info (cfg, code - cfg->native_code, \
- MONO_PATCH_INFO_BB, ins->inst_true_bb); \
- s390_jcl (code, cond, 0); \
-} \
-}
-
-#define EMIT_UNCOND_BRANCH(ins) \
-{ \
-if (ins->inst_target_bb->native_offset) { \
- int displace; \
- displace = ((cfg->native_code + \
- ins->inst_target_bb->native_offset) - code) / 2; \
- if (s390_is_imm16(displace)) { \
- s390_brc (code, S390_CC_UN, displace); \
- } else { \
- s390_jcl (code, S390_CC_UN, displace); \
- } \
-} else { \
- mono_add_patch_info (cfg, code - cfg->native_code, \
- MONO_PATCH_INFO_BB, ins->inst_target_bb); \
- s390_jcl (code, S390_CC_UN, 0); \
-} \
-}
-
-#define EMIT_COND_SYSTEM_EXCEPTION(cond,exc_name) \
- do { \
- mono_add_patch_info (cfg, code - cfg->native_code, \
- MONO_PATCH_INFO_EXC, exc_name); \
- s390_jcl (code, cond, 0); \
- } while (0);
-
-#define CHECK_SRCDST_COM \
- if (ins->dreg == ins->sreg2) { \
- src2 = ins->sreg1; \
- } else { \
- src2 = ins->sreg2; \
- if (ins->dreg != ins->sreg1) { \
- s390_lr (code, ins->dreg, ins->sreg1); \
- } \
- }
-
-#define CHECK_SRCDST_NCOM \
- if (ins->dreg == ins->sreg2) { \
- src2 = s390_r13; \
- s390_lr (code, s390_r13, ins->sreg2); \
- } else { \
- src2 = ins->sreg2; \
- } \
- if (ins->dreg != ins->sreg1) { \
- s390_lr (code, ins->dreg, ins->sreg1); \
- }
-
-#define CHECK_SRCDST_COM_F \
- if (ins->dreg == ins->sreg2) { \
- src2 = ins->sreg1; \
- } else { \
- src2 = ins->sreg2; \
- if (ins->dreg != ins->sreg1) { \
- s390_ldr (code, ins->dreg, ins->sreg1); \
- } \
- }
-
-#define CHECK_SRCDST_NCOM_F \
- if (ins->dreg == ins->sreg2) { \
- src2 = s390_f15; \
- s390_ldr (code, s390_r13, ins->sreg2); \
- } else { \
- src2 = ins->sreg2; \
- } \
- if (ins->dreg != ins->sreg1) { \
- s390_ldr (code, ins->dreg, ins->sreg1); \
- }
-
-#define MONO_EMIT_NEW_MOVE(cfg,dest,offset,src,imm,size) do { \
- MonoInst *inst; \
- int tmpr = 0; \
- int sReg, dReg; \
- MONO_INST_NEW (cfg, inst, OP_NOP); \
- if (size > 256) { \
- inst->dreg = dest; \
- inst->inst_offset = offset; \
- inst->sreg1 = src; \
- inst->inst_imm = imm; \
- } else { \
- if (s390_is_uimm12(offset)) { \
- inst->dreg = dest; \
- inst->inst_offset = offset; \
- } else { \
- dReg = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_BIALU_IMM(cfg, OP_ADD_IMM, \
- dReg, dest, offset); \
- inst->dreg = dReg; \
- inst->inst_offset = 0; \
- } \
- if (s390_is_uimm12(imm)) { \
- inst->sreg1 = src; \
- inst->inst_imm = imm; \
- } else { \
- sReg = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_BIALU_IMM(cfg, OP_ADD_IMM, \
- sReg, src, imm); \
- inst->sreg1 = sReg; \
- inst->inst_imm = 0; \
- } \
- } \
- inst->opcode = OP_S390_MOVE; \
- inst->backend.size = size; \
- MONO_ADD_INS (cfg->cbb, inst); \
- } while (0)
-
-#define MONO_OUTPUT_VTR(cfg, size, dr, sr, so) do { \
- int reg = mono_alloc_preg (cfg); \
- switch (size) { \
- case 0: \
- MONO_EMIT_NEW_ICONST(cfg, reg, 0); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- break; \
- case 1: \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE, \
- reg, sr, so); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- break; \
- case 2: \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE, \
- reg, sr, so); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- break; \
- case 4: \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
- reg, sr, so); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- break; \
- case 8: \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
- reg, sr, so); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- reg = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
- reg, sr, so + sizeof (guint32)); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr + 1, FALSE); \
- break; \
- } \
-} while (0)
-
-#define MONO_OUTPUT_VTS(cfg, size, dr, dx, sr, so) do { \
- int tmpr; \
- switch (size) { \
- case 0: \
- tmpr = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_ICONST(cfg, tmpr, 0); \
- MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
- dr, dx, tmpr); \
- break; \
- case 1: \
- tmpr = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE, \
- tmpr, sr, so); \
- MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
- dr, dx, tmpr); \
- break; \
- case 2: \
- tmpr = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE, \
- tmpr, sr, so); \
- MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
- dr, dx, tmpr); \
- break; \
- case 4: \
- case 8: \
- MONO_EMIT_NEW_MOVE (cfg, dr, dx, sr, so, size); \
- break; \
- } \
-} while (0)
-
-#undef DEBUG
-#define DEBUG(a) if (cfg->verbose_level > 1) a
-
-#define MAX_EXC 16
-
-#define S390_TRACE_STACK_SIZE (5*sizeof(gint32)+3*sizeof(gdouble))
-
-#define MAX (a, b) ((a) > (b) ? (a) : (b))
-
-/*========================= End of Defines =========================*/
-
-/*------------------------------------------------------------------*/
-/* I n c l u d e s */
-/*------------------------------------------------------------------*/
-
-#include "mini.h"
-#include <string.h>
-
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/profiler-private.h>
-#include <mono/utils/mono-math.h>
-
-#include "mini-s390.h"
-#include "cpu-s390.h"
-#include "jit-icalls.h"
-#include "ir-emit.h"
-
-/*========================= End of Includes ========================*/
-
-/*------------------------------------------------------------------*/
-/* T y p e d e f s */
-/*------------------------------------------------------------------*/
-
-typedef struct {
- guint stack_size,
- local_size,
- code_size,
- parm_size,
- offset,
- offStruct,
- retStruct;
-} size_data;
-
-/*------------------------------------------------------------------*/
-/* Used by the instrument_emit_epilog */
-/*------------------------------------------------------------------*/
-
-enum {
- SAVE_NONE,
- SAVE_STRUCT,
- SAVE_ONE,
- SAVE_TWO,
- SAVE_R4,
- SAVE_R8
-};
-
-typedef struct InstList InstList;
-
-struct InstList {
- InstList *prev;
- InstList *next;
- MonoInst *data;
-};
-
-typedef enum {
- RegTypeGeneral,
- RegTypeBase,
- RegTypeFP,
- RegTypeFPR4,
- RegTypeStructByVal,
- RegTypeStructByValInFP,
- RegTypeStructByAddr
-} ArgStorage;
-
-typedef struct {
- gint32 offset; /* offset from caller's stack */
- gint32 offparm; /* offset from callee's stack */
- guint16 vtsize; /* in param area */
- guint8 reg;
- ArgStorage regtype; /* See RegType* */
- guint32 size; /* Size of structure used by RegTypeStructByVal */
-} ArgInfo;
-
-typedef struct {
- int nargs;
- int lastgr;
- guint32 stack_usage;
- guint32 struct_ret;
- ArgInfo ret;
- ArgInfo sigCookie;
- size_data sz;
- ArgInfo args [1];
-} CallInfo;
-
-typedef struct {
- gint32 gr[5]; /* R2-R6 */
- gdouble fp[3]; /* F0-F2 */
-} __attribute__ ((packed)) RegParm;
-
-/*========================= End of Typedefs ========================*/
-
-/*------------------------------------------------------------------*/
-/* P r o t o t y p e s */
-/*------------------------------------------------------------------*/
-
-static void indent (int);
-static guint8 * backUpStackPtr(MonoCompile *, guint8 *, gint);
-static void decodeParm (MonoType *, void *, int);
-static void enter_method (MonoMethod *, RegParm *, char *);
-static void leave_method (MonoMethod *, ...);
-static gboolean is_regsize_var (MonoType *);
-static inline void add_general (guint *, size_data *, ArgInfo *, gboolean);
-static inline void add_stackParm (guint *, size_data *, ArgInfo *, gint);
-static inline void add_float (guint *, size_data *, ArgInfo *);
-static CallInfo * get_call_info (MonoCompile *, MonoMemPool *, MonoMethodSignature *, gboolean);
-static guchar * emit_float_to_int (MonoCompile *, guchar *, int, int, int, gboolean);
-gpointer mono_arch_get_lmf_addr (void);
-static guint8 * emit_load_volatile_registers(guint8 *, MonoCompile *);
-static void emit_sig_cookie (MonoCompile *, MonoCallInst *, CallInfo *);
-
-/*========================= End of Prototypes ======================*/
-
-/*------------------------------------------------------------------*/
-/* G l o b a l V a r i a b l e s */
-/*------------------------------------------------------------------*/
-
-int mono_exc_esp_offset = 0;
-
-static int indent_level = 0;
-
-static int appdomain_tls_offset = -1,
- thread_tls_offset = -1;
-
-pthread_key_t lmf_addr_key;
-
-gboolean lmf_addr_key_inited = FALSE;
-
-#if 0
-
-extern __thread MonoDomain *tls_appdomain;
-extern __thread MonoThread *tls_current_object;
-extern __thread gpointer mono_lmf_addr;
-
-#endif
-
-/*====================== End of Global Variables ===================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_regname */
-/* */
-/* Function - Returns the name of the register specified by */
-/* the input parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-const char*
-mono_arch_regname (int reg) {
- static const char * rnames[] = {
- "s390_r0", "s390_sp", "s390_r2", "s390_r3", "s390_r4",
- "s390_r5", "s390_r6", "s390_r7", "s390_r8", "s390_r9",
- "s390_r10", "s390_r11", "s390_r12", "s390_r13", "s390_r14",
- "s390_r15"
- };
-
- if (reg >= 0 && reg < 16)
- return rnames [reg];
- else
- return "unknown";
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_fregname */
-/* */
-/* Function - Returns the name of the register specified by */
-/* the input parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-const char*
-mono_arch_fregname (int reg) {
- static const char * rnames[] = {
- "s390_f0", "s390_f1", "s390_f2", "s390_f3", "s390_f4",
- "s390_f5", "s390_f6", "s390_f7", "s390_f8", "s390_f9",
- "s390_f10", "s390_f11", "s390_f12", "s390_f13", "s390_f14",
- "s390_f15"
- };
-
- if (reg >= 0 && reg < 16)
- return rnames [reg];
- else
- return "unknown";
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - arch_get_argument_info */
-/* */
-/* Function - Gathers information on parameters such as size, */
-/* alignment, and padding. arg_info should be large */
-/* enough to hold param_count + 1 entries. */
-/* */
-/* Parameters - @csig - Method signature */
-/* @param_count - No. of parameters to consider */
-/* @arg_info - An array to store the result info */
-/* */
-/* Returns - Size of the activation frame */
-/* */
-/*------------------------------------------------------------------*/
-
-int
-mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig,
- int param_count,
- MonoJitArgumentInfo *arg_info)
-{
- int k, frame_size = 0;
- int size, align, pad;
- int offset = 8;
-
- if (MONO_TYPE_ISSTRUCT (csig->ret)) {
- frame_size += sizeof (gpointer);
- offset += 4;
- }
-
- arg_info [0].offset = offset;
-
- if (csig->hasthis) {
- frame_size += sizeof (gpointer);
- offset += 4;
- }
-
- arg_info [0].size = frame_size;
-
- for (k = 0; k < param_count; k++) {
-
- if (csig->pinvoke)
- size = mono_type_native_stack_size (csig->params [k], &align);
- else
- size = mini_type_stack_size (NULL, csig->params [k], &align);
-
- frame_size += pad = (align - (frame_size & (align - 1))) & (align - 1);
- arg_info [k].pad = pad;
- frame_size += size;
- arg_info [k + 1].pad = 0;
- arg_info [k + 1].size = size;
- offset += pad;
- arg_info [k + 1].offset = offset;
- offset += size;
- }
-
- align = MONO_ARCH_FRAME_ALIGNMENT;
- frame_size += pad = (align - (frame_size & (align - 1))) & (align - 1);
- arg_info [k].pad = pad;
-
- return frame_size;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - retFitsInReg. */
-/* */
-/* Function - Determines if a value can be returned in one or */
-/* two registers. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline gboolean
-retFitsInReg(guint32 size)
-{
- switch (size) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 8:
- return (TRUE);
- break;
- default:
- return (FALSE);
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - backStackPtr. */
-/* */
-/* Function - Restore Stack Pointer to previous frame. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-backUpStackPtr(MonoCompile *cfg, guint8 *code, gint framePtr)
-{
- int stackSize = cfg->stack_usage;
-
- if (s390_is_uimm16 (cfg->stack_usage)) {
- s390_ahi (code, framePtr, cfg->stack_usage);
- } else {
- while (stackSize > 32767) {
- s390_ahi (code, framePtr, 32767);
- stackSize -= 32767;
- }
- s390_ahi (code, framePtr, stackSize);
- }
- return (code);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - indent */
-/* */
-/* Function - Perform nice indenting to current level */
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-indent (int diff) {
- int v;
- if (diff < 0)
- indent_level += diff;
- v = indent_level;
- printf("[%3d] ",v);
- while (v-- > 0) {
- printf (". ");
- }
- if (diff > 0)
- indent_level += diff;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - decodeParm */
-/* */
-/* Function - Decode a parameter for the trace. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-decodeParm(MonoType *type, void *curParm, int size)
-{
- guint32 simpleType;
-
- if (type->byref) {
- printf("[BYREF:%p], ", *((char **) curParm));
- } else {
- simpleType = mono_type_get_underlying_type(type)->type;
-enum_parmtype:
- switch (simpleType) {
- case MONO_TYPE_I :
- printf ("[INTPTR:%p], ", *((int **) curParm));
- break;
- case MONO_TYPE_U :
- printf ("[UINTPTR:%p], ", *((int **) curParm));
- break;
- case MONO_TYPE_BOOLEAN :
- printf ("[BOOL:%d], ", *((int *) curParm));
- break;
- case MONO_TYPE_CHAR :
- printf ("[CHAR:%c], ", *((int *) curParm));
- break;
- case MONO_TYPE_I1 :
- printf ("[INT1:%d], ", *((int *) curParm));
- break;
- case MONO_TYPE_I2 :
- printf ("[INT2:%d], ", *((int *) curParm));
- break;
- case MONO_TYPE_I4 :
- printf ("[INT4:%d], ", *((int *) curParm));
- break;
- case MONO_TYPE_U1 :
- printf ("[UINT1:%u], ", *((unsigned int *) curParm));
- break;
- case MONO_TYPE_U2 :
- printf ("[UINT2:%u], ", *((guint16 *) curParm));
- break;
- case MONO_TYPE_U4 :
- printf ("[UINT4:%u], ", *((guint32 *) curParm));
- break;
- case MONO_TYPE_U8 :
- printf ("[UINT8:%llu], ", *((guint64 *) curParm));
- break;
- case MONO_TYPE_STRING : {
- MonoString *s = *((MonoString **) curParm);
- if (s) {
- g_assert (((MonoObject *) s)->vtable->klass == mono_defaults.string_class);
- printf("[STRING:%p:%s], ", s, mono_string_to_utf8(s));
- } else {
- printf("[STRING:null], ");
- }
- break;
- }
- case MONO_TYPE_CLASS :
- case MONO_TYPE_OBJECT : {
- MonoObject *obj = *((MonoObject **) curParm);
- MonoClass *class;
- if ((obj) && (obj->vtable)) {
- printf("[CLASS/OBJ:");
- class = obj->vtable->klass;
- printf("%p [%p] ",obj,curParm);
-// if (class == mono_defaults.string_class) {
-// printf("[STRING:%p:%s]",
-// *obj, mono_string_to_utf8 (obj));
-// } else if (class == mono_defaults.int32_class) {
-// printf("[INT32:%p:%d]",
-// obj, *(gint32 *)((char *)obj + sizeof (MonoObject)));
-// } else
-// printf("[%s.%s:%p]",
-// class->name_space, class->name, obj);
- printf("], ");
- } else {
- printf("[OBJECT:null], ");
- }
- break;
- }
- case MONO_TYPE_PTR :
- printf("[PTR:%p], ", *((gpointer **) (curParm)));
- break;
- case MONO_TYPE_FNPTR :
- printf("[FNPTR:%p], ", *((gpointer **) (curParm)));
- break;
- case MONO_TYPE_ARRAY :
- printf("[ARRAY:%p], ", *((gpointer **) (curParm)));
- break;
- case MONO_TYPE_SZARRAY :
- printf("[SZARRAY:%p], ", *((gpointer **) (curParm)));
- break;
- case MONO_TYPE_I8 :
- printf("[INT8:%lld], ", *((gint64 *) (curParm)));
- break;
- case MONO_TYPE_R4 :
- printf("[FLOAT4:%g], ", *((double *) (curParm)));
- break;
- case MONO_TYPE_R8 :
- printf("[FLOAT8:%g], ", *((double *) (curParm)));
- break;
- case MONO_TYPE_VALUETYPE : {
- int i;
- MonoMarshalType *info;
-
- if (type->data.klass->enumtype) {
- simpleType = mono_class_enum_basetype (type->data.klass)->type;
- printf("{VALUETYPE} - ");
- goto enum_parmtype;
- }
-
- info = mono_marshal_load_type_info (type->data.klass);
-
- if ((info->native_size == sizeof(float)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R4)) {
- printf("[FLOAT4:%f], ", *((float *) (curParm)));
- break;
- }
-
- if ((info->native_size == sizeof(double)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R8)) {
- printf("[FLOAT8:%g], ", *((double *) (curParm)));
- break;
- }
-
- printf("[VALUETYPE:");
- for (i = 0; i < size; i++)
- printf("%02x,", *((guint8 *)curParm+i));
- printf("]");
- break;
- }
- case MONO_TYPE_TYPEDBYREF: {
- int i;
- printf("[TYPEDBYREF:");
- for (i = 0; i < size; i++)
- printf("%02x,", *((guint8 *)curParm+i));
- printf("]");
- break;
- }
- default :
- printf("[?? - %d], ",simpleType);
- }
- }
-}
-
-/*========================= End of Function ========================*/
-
-//static int lc = 0;
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - enter_method */
-/* */
-/* Function - Perform tracing of the entry to the current */
-/* method. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-enter_method (MonoMethod *method, RegParm *rParm, char *sp)
-{
- int i, oParm = 0, iParm = 0;
- MonoObject *obj;
- MonoMethodSignature *sig;
- char *fname;
- guint32 ip;
- CallInfo *cinfo;
- ArgInfo *ainfo;
- void *curParm;
-
- fname = mono_method_full_name (method, TRUE);
- indent (1);
- printf ("ENTER: %s(", fname);
- g_free (fname);
-
- ip = (*(guint32 *) (sp+S390_RET_ADDR_OFFSET)) & 0x7fffffff;
- printf (") ip: %p sp: %p - ", (gpointer) ip, sp);
-
- if (rParm == NULL)
- return;
-
- sig = mono_method_signature (method);
-
- cinfo = get_call_info (NULL, NULL, sig, sig->pinvoke);
-
- if (cinfo->struct_ret) {
- printf ("[STRUCTRET:%p], ", (gpointer) rParm->gr[0]);
- iParm = 1;
- }
-
- if (sig->hasthis) {
- gpointer *this = (gpointer *) rParm->gr[iParm];
- obj = (MonoObject *) this;
- if (method->klass->valuetype) {
- if (obj) {
- printf("this:[value:%p:%08x], ",
- this, *((guint32 *)(this+sizeof(MonoObject))));
- } else
- printf ("this:[NULL], ");
- } else {
- if (obj) {
-// class = obj->vtable->klass;
-// if (class == mono_defaults.string_class) {
-// printf ("this:[STRING:%p:%s], ",
-// obj, mono_string_to_utf8 ((MonoString *)obj));
-// } else {
-// printf ("this:%p[%s.%s], ",
-// obj, class->name_space, class->name);
-// }
-printf("this:%p, ",obj);
- } else
- printf ("this:NULL, ");
- }
- oParm++;
- }
-
- for (i = 0; i < sig->param_count; ++i) {
- ainfo = &cinfo->args[i + oParm];
- switch (ainfo->regtype) {
- case RegTypeGeneral :
- decodeParm(sig->params[i], &(rParm->gr[ainfo->reg-2]), ainfo->size);
- break;
- case RegTypeFP :
- decodeParm(sig->params[i], &(rParm->fp[ainfo->reg]), ainfo->size);
- break;
- case RegTypeBase :
- decodeParm(sig->params[i], sp+ainfo->offset, ainfo->size);
- break;
- case RegTypeStructByVal :
- if (ainfo->reg != STK_BASE)
- curParm = &(rParm->gr[ainfo->reg-2]);
- else
- curParm = sp+ainfo->offset;
-
- if (retFitsInReg (ainfo->vtsize))
- decodeParm(sig->params[i],
- curParm,
- ainfo->size);
- else
- decodeParm(sig->params[i],
- *((char **) curParm),
- ainfo->vtsize);
- break;
- case RegTypeStructByAddr :
- if (ainfo->reg != STK_BASE)
- curParm = &(rParm->gr[ainfo->reg-2]);
- else
- curParm = sp+ainfo->offset;
-
- decodeParm(sig->params[i],
- *((char **) curParm),
- ainfo->vtsize);
- break;
-
- default :
- printf("???, ");
- }
- }
- printf("\n");
- g_free(cinfo);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - leave_method */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-leave_method (MonoMethod *method, ...)
-{
- MonoType *type;
- char *fname;
- guint32 ip;
- va_list ap;
-
- va_start(ap, method);
-
- fname = mono_method_full_name (method, TRUE);
- indent (-1);
- printf ("LEAVE: %s", fname);
- g_free (fname);
-
- type = mono_method_signature (method)->ret;
-
-handle_enum:
- switch (type->type) {
- case MONO_TYPE_VOID:
- break;
- case MONO_TYPE_BOOLEAN: {
- int val = va_arg (ap, int);
- if (val)
- printf ("[TRUE:%d]", val);
- else
- printf ("[FALSE]");
-
- break;
- }
- case MONO_TYPE_CHAR: {
- int val = va_arg (ap, int);
- printf ("[CHAR:%d]", val);
- break;
- }
- case MONO_TYPE_I1: {
- int val = va_arg (ap, int);
- printf ("[INT1:%d]", val);
- break;
- }
- case MONO_TYPE_U1: {
- int val = va_arg (ap, int);
- printf ("[UINT1:%d]", val);
- break;
- }
- case MONO_TYPE_I2: {
- int val = va_arg (ap, int);
- printf ("[INT2:%d]", val);
- break;
- }
- case MONO_TYPE_U2: {
- int val = va_arg (ap, int);
- printf ("[UINT2:%d]", val);
- break;
- }
- case MONO_TYPE_I4: {
- int val = va_arg (ap, int);
- printf ("[INT4:%d]", val);
- break;
- }
- case MONO_TYPE_U4: {
- int val = va_arg (ap, int);
- printf ("[UINT4:%d]", val);
- break;
- }
- case MONO_TYPE_I: {
- int val = va_arg (ap, int);
- printf ("[INT:%d]", val);
- printf("]");
- break;
- }
- case MONO_TYPE_U: {
- int val = va_arg (ap, int);
- printf ("[UINT:%d]", val);
- printf("]");
- break;
- }
- case MONO_TYPE_STRING: {
- MonoString *s = va_arg (ap, MonoString *);
-;
- if (s) {
- g_assert (((MonoObject *)s)->vtable->klass == mono_defaults.string_class);
- printf ("[STRING:%p:%s]", s, mono_string_to_utf8 (s));
- } else
- printf ("[STRING:null], ");
- break;
- }
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT: {
- MonoObject *o = va_arg (ap, MonoObject *);
-
-// if ((o) && (o->vtable)) {
-// if (o->vtable->klass == mono_defaults.boolean_class) {
-// printf ("[BOOLEAN:%p:%d]", o, *((guint8 *)o + sizeof (MonoObject)));
-// } else if (o->vtable->klass == mono_defaults.int32_class) {
-// printf ("[INT32:%p:%d]", o, *((gint32 *)((char *)o + sizeof (MonoObject))));
-// } else if (o->vtable->klass == mono_defaults.int64_class) {
-// printf ("[INT64:%p:%lld]", o, *((gint64 *)((char *)o + sizeof (MonoObject))));
-// } else
-// printf ("[%s.%s:%p]", o->vtable->klass->name_space, o->vtable->klass->name, o);
-// } else
- printf ("[OBJECT:%p]", o);
-
- break;
- }
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY: {
- gpointer p = va_arg (ap, gpointer);
- printf ("[result=%p]", p);
- break;
- }
- case MONO_TYPE_I8: {
- gint64 l = va_arg (ap, gint64);
- printf ("[LONG:%lld]", l);
- break;
- }
- case MONO_TYPE_U8: {
- guint64 l = va_arg (ap, guint64);
- printf ("[ULONG:%llu]", l);
- break;
- }
- case MONO_TYPE_R4: {
- double f;
- f = va_arg (ap, double);
- printf ("[FLOAT4:%g]\n", f);
- break;
- }
- case MONO_TYPE_R8: {
- double f = va_arg (ap, double);
- printf ("[FLOAT8:%g]\n", f);
- break;
- }
- case MONO_TYPE_VALUETYPE: {
- MonoMarshalType *info;
- if (type->data.klass->enumtype) {
- type = mono_class_enum_basetype (type->data.klass);
- goto handle_enum;
- } else {
- guint8 *p = va_arg (ap, gpointer);
- int j, size, align;
-
- info = mono_marshal_load_type_info (type->data.klass);
-
- if ((info->native_size == sizeof(float)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R4)) {
- double f = va_arg (ap, double);
- printf("[FLOAT4:%g]\n", (double) f);
- break;
- }
-
- if ((info->native_size == sizeof(double)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R8)) {
- double f = va_arg (ap, double);
- printf("[FLOAT8:%g]\n", f);
- break;
- }
-
- size = mono_type_size (type, &align);
- switch (size) {
- case 1:
- case 2:
- case 4:
- case 8:
- printf ("[");
- for (j = 0; p && j < size; j++)
- printf ("%02x,", p [j]);
- printf ("]\n");
- break;
- default:
- printf ("[VALUERET]\n");
- }
- }
- break;
- }
- case MONO_TYPE_TYPEDBYREF: {
- guint8 *p = va_arg (ap, gpointer);
- int j, size, align;
- size = mono_type_size (type, &align);
- switch (size) {
- case 1:
- case 2:
- case 4:
- case 8:
- printf ("[");
- for (j = 0; p && j < size; j++)
- printf ("%02x,", p [j]);
- printf ("]\n");
- break;
- default:
- printf ("[TYPEDBYREF]\n");
- }
- }
- break;
- default:
- printf ("(unknown return type %x)",
- mono_method_signature (method)->ret->type);
- }
-
- ip = ((gint32) __builtin_return_address (0)) & 0x7fffffff;
- printf (" ip: %p\n", (gpointer) ip);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_cpu_init */
-/* */
-/* Function - Perform CPU specific initialization to execute */
-/* managed code. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_cpu_init (void)
-{
- guint mode = 1;
-
- /*--------------------------------------*/
- /* Set default rounding mode for FP */
- /*--------------------------------------*/
- __asm__ ("SRNM\t%0\n\t"
- : : "m" (mode));
-}
-
-/*========================= End of Function ========================*/
-
-
-/*
- * Initialize architecture specific code.
- */
-void
-mono_arch_init (void)
-{
-}
-
-/*
- * Cleanup architecture specific code.
- */
-void
-mono_arch_cleanup (void)
-{
-}
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_cpu_optimizations */
-/* */
-/* Function - Returns the optimizations supported on this CPU */
-/* */
-/*------------------------------------------------------------------*/
-
-guint32
-mono_arch_cpu_optimizations (guint32 *exclude_mask)
-{
- guint32 opts = 0;
-
- /*----------------------------------------------------------*/
- /* no s390-specific optimizations yet */
- /*----------------------------------------------------------*/
- *exclude_mask = MONO_OPT_INLINE|MONO_OPT_LINEARS;
-// *exclude_mask = MONO_OPT_INLINE;
- return opts;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_cpu_enumerate_simd_versions */
-/* */
-/* Function - Returns the SIMD instruction sets on this CPU */
-/* */
-/*------------------------------------------------------------------*/
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
- /* SIMD is currently unimplemented */
- return 0;
-}
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-static gboolean
-is_regsize_var (MonoType *t) {
- if (t->byref)
- return TRUE;
- switch (mono_type_get_underlying_type (t)->type) {
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- return TRUE;
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- return FALSE;
- case MONO_TYPE_VALUETYPE:
- if (t->data.klass->enumtype)
- return is_regsize_var (mono_class_enum_basetype (t->data.klass));
- return FALSE;
- }
- return FALSE;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_allocatable_int_vars */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-GList *
-mono_arch_get_allocatable_int_vars (MonoCompile *cfg)
-{
- GList *vars = NULL;
- int i;
-
- for (i = 0; i < cfg->num_varinfo; i++) {
- MonoInst *ins = cfg->varinfo [i];
- MonoMethodVar *vmv = MONO_VARINFO (cfg, i);
-
- /* unused vars */
- if (vmv->range.first_use.abs_pos >= vmv->range.last_use.abs_pos)
- continue;
-
- if (ins->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) ||
- (ins->opcode != OP_LOCAL && ins->opcode != OP_ARG))
- continue;
-
- /* we can only allocate 32 bit values */
- if (is_regsize_var (ins->inst_vtype)) {
- g_assert (MONO_VARINFO (cfg, i)->reg == -1);
- g_assert (i == vmv->idx);
- vars = mono_varlist_insert_sorted (cfg, vars, vmv, FALSE);
- }
- }
-
- return vars;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_global_int_regs */
-/* */
-/* Function - Return a list of usable integer registers. */
-/* */
-/*------------------------------------------------------------------*/
-
-GList *
-mono_arch_get_global_int_regs (MonoCompile *cfg)
-{
- GList *regs = NULL;
- MonoMethodHeader *header;
- int i, top = 13;
-
- header = cfg->header;
- if ((cfg->flags & MONO_CFG_HAS_ALLOCA) || header->num_clauses)
- cfg->frame_reg = s390_r11;
-
- /* FIXME: s390_r12 is reserved for bkchain_reg. Only reserve it if needed */
- top = 12;
- for (i = 8; i < top; ++i) {
- if (cfg->frame_reg != i)
- regs = g_list_prepend (regs, GUINT_TO_POINTER (i));
- }
-
- return regs;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_flush_icache */
-/* */
-/* Function - Flush the CPU icache. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_flush_icache (guint8 *code, gint size)
-{
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_is_inst_imm */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_is_inst_imm (gint64 imm)
-{
- /* The lowering pass will take care of it */
- return TRUE;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - add_general */
-/* */
-/* Function - Determine code and stack size incremements for a */
-/* parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-add_general (guint *gr, size_data *sz, ArgInfo *ainfo, gboolean simple)
-{
- int disp;
-
- if (simple) {
- if (*gr > S390_LAST_ARG_REG) {
- sz->stack_size = S390_ALIGN(sz->stack_size, sizeof(long));
- ainfo->offset = sz->stack_size;
- ainfo->reg = STK_BASE;
- ainfo->regtype = RegTypeBase;
- sz->stack_size += sizeof(int);
- sz->local_size += sizeof(int);
- sz->offStruct += sizeof(int);
- sz->code_size += 12;
- } else {
- ainfo->reg = *gr;
- sz->code_size += 8;
- }
- } else {
- if (*gr > S390_LAST_ARG_REG - 1) {
- disp = sz->stack_size;
- sz->stack_size = S390_ALIGN(sz->stack_size, S390_STACK_ALIGNMENT);
- disp = sz->stack_size - disp;
- ainfo->offset = sz->stack_size;
- ainfo->reg = STK_BASE;
- ainfo->regtype = RegTypeBase;
- sz->stack_size += sizeof(long long);
- sz->local_size += (sizeof(long long) + disp);
- sz->offStruct += (sizeof(long long) + disp);
- sz->code_size += 10;
- } else {
- ainfo->reg = *gr;
- sz->code_size += 8;
- }
- (*gr) ++;
- }
- (*gr) ++;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - add_stackParm */
-/* */
-/* Function - Determine code and stack size incremements for a */
-/* parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-add_stackParm (guint *gr, size_data *sz, ArgInfo *ainfo, gint size)
-{
- if (*gr > S390_LAST_ARG_REG) {
- sz->stack_size = S390_ALIGN(sz->stack_size, sizeof(long));
- ainfo->reg = STK_BASE;
- ainfo->offset = sz->stack_size;
- sz->stack_size += sizeof (gpointer);
- sz->parm_size += sizeof(gpointer);
- sz->offStruct += sizeof(gpointer);
- } else {
- ainfo->reg = *gr;
- ainfo->offset = sz->stack_size;
- }
- (*gr) ++;
- ainfo->offparm = sz->offset;
- sz->offset = S390_ALIGN(sz->offset+size, sizeof(long));
- ainfo->size = size;
- ainfo->regtype = RegTypeStructByAddr;
- ainfo->vtsize = size;
- sz->parm_size += size;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - add_float */
-/* */
-/* Function - Determine code and stack size incremements for a */
-/* float parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-add_float (guint *fr, size_data *sz, ArgInfo *ainfo)
-{
- if ((*fr) <= S390_LAST_FPARG_REG) {
- ainfo->regtype = RegTypeFP;
- ainfo->reg = *fr;
- sz->code_size += 4;
- (*fr) += 2;
- }
- else {
- ainfo->offset = sz->stack_size;
- ainfo->reg = STK_BASE;
- ainfo->regtype = RegTypeBase;
- sz->code_size += 4;
- sz->stack_size += ainfo->size;
- sz->local_size += ainfo->size;
- sz->offStruct += ainfo->size;
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - get_call_info */
-/* */
-/* Function - Determine the amount of space required for code */
-/* and stack. In addition determine starting points */
-/* for stack-based parameters, and area for struct- */
-/* ures being returned on the stack. */
-/* */
-/*------------------------------------------------------------------*/
-
-static CallInfo *
-get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
-{
- guint i, fr, gr, size;
- int nParm = sig->hasthis + sig->param_count;
- MonoType *ret_type;
- guint32 simpletype, align;
- CallInfo *cinfo;
- size_data *sz;
- MonoGenericSharingContext *gsctx = cfg ? cfg->generic_sharing_context : NULL;
-
- if (mp)
- cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + sizeof (ArgInfo) * nParm);
- else
- cinfo = g_malloc0 (sizeof (CallInfo) + sizeof (ArgInfo) * nParm);
-
- fr = 0;
- gr = s390_r2;
- nParm = 0;
- cinfo->struct_ret = 0;
- sz = &cinfo->sz;
- sz->offset = 0;
- sz->offStruct = S390_MINIMAL_STACK_SIZE;
- sz->retStruct = 0;
- sz->stack_size = S390_MINIMAL_STACK_SIZE;
- sz->code_size = 0;
- sz->parm_size = 0;
- sz->local_size = 0;
-
- /*----------------------------------------------------------*/
- /* We determine the size of the return code/stack in case we*/
- /* need to reserve a register to be used to address a stack */
- /* area that the callee will use. */
- /*----------------------------------------------------------*/
-
- ret_type = mono_type_get_underlying_type (sig->ret);
- ret_type = mini_get_basic_type_from_generic (gsctx, ret_type);
- simpletype = ret_type->type;
-enum_retvalue:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- case MONO_TYPE_STRING:
- cinfo->ret.reg = s390_r2;
- sz->code_size += 4;
- break;
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- cinfo->ret.reg = s390_f0;
- sz->code_size += 4;
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- cinfo->ret.reg = s390_r2;
- sz->code_size += 4;
- break;
- case MONO_TYPE_GENERICINST:
- if (!mono_type_generic_inst_is_valuetype (ret_type)) {
- cinfo->ret.reg = s390_r2;
- sz->code_size += 4;
- break;
- }
- /* Fall through */
- case MONO_TYPE_VALUETYPE: {
- MonoClass *klass = mono_class_from_mono_type (sig->ret);
- if (klass->enumtype) {
- simpletype = mono_class_enum_basetype (klass)->type;
- goto enum_retvalue;
- }
- if (sig->pinvoke)
- size = mono_class_native_size (klass, &align);
- else
- size = mono_class_value_size (klass, &align);
-
- cinfo->ret.reg = s390_r2;
- cinfo->struct_ret = 1;
- cinfo->ret.size = size;
- cinfo->ret.vtsize = size;
- gr++;
- break;
- }
- case MONO_TYPE_TYPEDBYREF:
- size = sizeof (MonoTypedRef);
- cinfo->ret.reg = s390_r2;
- cinfo->struct_ret = 1;
- cinfo->ret.size = size;
- cinfo->ret.vtsize = size;
- gr++;
- break;
- case MONO_TYPE_VOID:
- break;
- default:
- g_error ("mini-s390: cannot handle as return value 0x%x (0x%x)", sig->ret->type,simpletype);
- }
-
- if (sig->hasthis) {
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- cinfo->args[nParm].size = sizeof(gpointer);
- nParm++;
- }
-
- /*----------------------------------------------------------*/
- /* We determine the size of the parameter code and stack */
- /* requirements by checking the types and sizes of the */
- /* parameters. */
- /*----------------------------------------------------------*/
-
- for (i = 0; i < sig->param_count; ++i) {
- MonoType *ptype;
-
- /*--------------------------------------------------*/
- /* Handle vararg type calls. All args are put on */
- /* the stack. */
- /*--------------------------------------------------*/
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (i == sig->sentinelpos)) {
- gr = S390_LAST_ARG_REG + 1;
- add_general (&gr, sz, &cinfo->sigCookie, TRUE);
- }
-
- if (sig->params [i]->byref) {
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- cinfo->args[nParm].size = sizeof(gpointer);
- nParm++;
- continue;
- }
-
- ptype = mono_type_get_underlying_type (sig->params [i]);
- ptype = mini_get_basic_type_from_generic (gsctx, ptype);
- simpletype = ptype->type;
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- cinfo->args[nParm].size = sizeof(char);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- cinfo->args[nParm].size = sizeof(short);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- cinfo->args[nParm].size = sizeof(int);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- cinfo->args[nParm].size = sizeof(gpointer);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- cinfo->args[nParm].size = sizeof(long long);
- add_general (&gr, sz, cinfo->args+nParm, FALSE);
- nParm++;
- break;
- case MONO_TYPE_R4:
- cinfo->args[nParm].size = sizeof(float);
- add_float (&fr, sz, cinfo->args+nParm);
- nParm++;
- break;
- case MONO_TYPE_R8:
- cinfo->args[nParm].size = sizeof(double);
- add_float (&fr, sz, cinfo->args+nParm);
- nParm++;
- break;
- case MONO_TYPE_GENERICINST:
- if (!mono_type_generic_inst_is_valuetype (ptype)) {
- cinfo->args[nParm].size = sizeof(gpointer);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- }
- /* Fall through */
- case MONO_TYPE_VALUETYPE: {
- MonoMarshalType *info;
- MonoClass *klass = mono_class_from_mono_type (sig->params [i]);
- if (sig->pinvoke)
- size = mono_class_native_size (klass, &align);
- else
- size = mono_class_value_size (klass, &align);
-
- info = mono_marshal_load_type_info (klass);
-
- if ((info->native_size == sizeof(float)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R4)) {
- cinfo->args[nParm].size = sizeof(float);
- add_float(&fr, sz, cinfo->args+nParm);
- nParm ++;
- break;
- }
-
- if ((info->native_size == sizeof(double)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R8)) {
- cinfo->args[nParm].size = sizeof(double);
- add_float(&fr, sz, cinfo->args+nParm);
- nParm ++;
- break;
- }
-
- cinfo->args[nParm].vtsize = 0;
- cinfo->args[nParm].size = 0;
-
- switch (size) {
- /*----------------------------------*/
- /* On S/390, structures of size 1, */
- /* 2, 4, and 8 bytes are passed in */
- /* (a) register(s). */
- /*----------------------------------*/
- case 0:
- case 1:
- case 2:
- case 4:
- add_general(&gr, sz, cinfo->args+nParm, TRUE);
- cinfo->args[nParm].size = size;
- cinfo->args[nParm].regtype = RegTypeStructByVal;
- nParm++;
- sz->local_size += sizeof(long);
- break;
- case 8:
- add_general(&gr, sz, cinfo->args+nParm, FALSE);
- cinfo->args[nParm].size = sizeof(long long);
- cinfo->args[nParm].regtype = RegTypeStructByVal;
- nParm++;
- sz->local_size += sizeof(long long);
- break;
- default:
- add_stackParm(&gr, sz, cinfo->args+nParm, size);
- nParm++;
- }
- }
- break;
- case MONO_TYPE_TYPEDBYREF: {
- int size = sizeof (MonoTypedRef);
-
- cinfo->args[nParm].vtsize = 0;
- cinfo->args[nParm].size = 0;
-
- switch (size) {
- /*----------------------------------*/
- /* On S/390, structures of size 1, */
- /* 2, 4, and 8 bytes are passed in */
- /* (a) register(s). */
- /*----------------------------------*/
- case 0:
- case 1:
- case 2:
- case 4:
- add_general(&gr, sz, cinfo->args+nParm, TRUE);
- cinfo->args[nParm].size = size;
- cinfo->args[nParm].regtype = RegTypeStructByVal;
- nParm++;
- sz->local_size += sizeof(long);
- break;
- case 8:
- add_general(&gr, sz, cinfo->args+nParm, FALSE);
- cinfo->args[nParm].size = sizeof(long long);
- cinfo->args[nParm].regtype = RegTypeStructByVal;
- nParm++;
- sz->local_size += sizeof(long long);
- break;
- default:
- add_stackParm(&gr, sz, cinfo->args+nParm, size);
- nParm++;
- }
- }
- break;
- default:
- g_error ("Can't trampoline 0x%x", sig->params [i]->type);
- }
- }
-
- /*----------------------------------------------------------*/
- /* If we are passing a structure back then if it won't be */
- /* in a register(s) then we make room at the end of the */
- /* parameters that may have been placed on the stack */
- /*----------------------------------------------------------*/
- if (cinfo->struct_ret) {
- cinfo->ret.offset = sz->stack_size;
- switch (cinfo->ret.size) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 8:
- break;
- default:
- sz->stack_size += S390_ALIGN(cinfo->ret.size, align);
- }
- }
-
- /*----------------------------------------------------------*/
- /* Handle the case where there are no implicit arguments */
- /*----------------------------------------------------------*/
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (sig->param_count == sig->sentinelpos)) {
- gr = S390_LAST_ARG_REG + 1;
- add_general (&gr, sz, &cinfo->sigCookie, TRUE);
- }
-
- cinfo->lastgr = gr;
- sz->stack_size = sz->stack_size + sz->local_size + sz->parm_size +
- sz->offset;
- sz->stack_size = S390_ALIGN(sz->stack_size, sizeof(long));
-
- return (cinfo);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_allocate_vars */
-/* */
-/* Function - Set var information according to the calling */
-/* convention for S/390. The local var stuff should */
-/* most likely be split in another method. */
-/* */
-/* Parameter - @m - Compile unit. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_allocate_vars (MonoCompile *cfg)
-{
- MonoMethodSignature *sig;
- MonoMethodHeader *header;
- MonoInst *inst;
- CallInfo *cinfo;
- int iParm, iVar, offset, size, align, curinst;
- int frame_reg = STK_BASE;
- int sArg, eArg;
-
- header = cfg->header;
-
- cfg->flags |= MONO_CFG_HAS_SPILLUP;
-
- sig = mono_method_signature (cfg->method);
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- /*---------------------------------------------------------*/
- /* We use the frame register also for any method that has */
- /* filter clauses. This way, when the handlers are called, */
- /* the code will reference local variables using the frame */
- /* reg instead of the stack pointer: if we had to restore */
- /* the stack pointer, we'd corrupt the method frames that */
- /* are already on the stack (since filters get called */
- /* before stack unwinding happens) when the filter code */
- /* would call any method. */
- /*---------------------------------------------------------*/
- if ((cfg->flags & MONO_CFG_HAS_ALLOCA) || header->num_clauses)
- frame_reg = s390_r11;
-
- cfg->frame_reg = frame_reg;
-
- cfg->arch.bkchain_reg = -1;
-
- if (frame_reg != STK_BASE)
- cfg->used_int_regs |= 1 << frame_reg;
-
- sig = mono_method_signature (cfg->method);
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- if (!cinfo->struct_ret) {
- switch (mono_type_get_underlying_type (sig->ret)->type) {
- case MONO_TYPE_VOID:
- break;
- default:
- cfg->ret->opcode = OP_REGVAR;
- cfg->ret->dreg = s390_r2;
- break;
- }
- }
-
- /*--------------------------------------------------------------*/
- /* local vars are at a positive offset from the stack pointer */
- /* also note that if the function uses alloca, we use s390_r11 */
- /* to point at the local variables. */
- /* add parameter area size for called functions */
- /*--------------------------------------------------------------*/
- offset = (cfg->param_area + S390_MINIMAL_STACK_SIZE);
- cfg->sig_cookie = 0;
-
- if (cinfo->struct_ret) {
- inst = cfg->vret_addr;
- offset = S390_ALIGN(offset, sizeof(gpointer));
- inst->inst_offset = offset;
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- offset += sizeof(gpointer);
- if (G_UNLIKELY (cfg->verbose_level > 1)) {
- printf ("vret_addr =");
- mono_print_ins (cfg->vret_addr);
- }
- }
-
- if (sig->hasthis) {
- inst = cfg->args [0];
- if (inst->opcode != OP_REGVAR) {
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- offset = S390_ALIGN(offset, sizeof(gpointer));
- inst->inst_offset = offset;
- offset += sizeof (gpointer);
- }
- curinst = sArg = 1;
- } else {
- curinst = sArg = 0;
- }
-
- eArg = sig->param_count + sArg;
-
- if (sig->call_convention == MONO_CALL_VARARG)
- cfg->sig_cookie += S390_MINIMAL_STACK_SIZE;
-
- for (iParm = sArg; iParm < eArg; ++iParm) {
- inst = cfg->args [curinst];
- if (inst->opcode != OP_REGVAR) {
- switch (cinfo->args[iParm].regtype) {
- case RegTypeStructByAddr : {
- MonoInst *indir;
-
- size = sizeof (gpointer);
-
- if (cinfo->args [iParm].reg == STK_BASE) {
- cfg->arch.bkchain_reg = s390_r12;
- cfg->used_int_regs |= 1 << cfg->arch.bkchain_reg;
-
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = cfg->arch.bkchain_reg;
- inst->inst_offset = cinfo->args [iParm].offset;
- } else {
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- inst->inst_offset = S390_ALIGN(offset, sizeof (gpointer));
- }
-
- /* Add a level of indirection */
- MONO_INST_NEW (cfg, indir, 0);
- *indir = *inst;
- inst->opcode = OP_VTARG_ADDR;
- inst->inst_left = indir;
- }
- break;
- case RegTypeStructByVal :
- size = cinfo->args[iParm].size;
- offset = S390_ALIGN(offset, size);
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- inst->inst_offset = S390_ALIGN (offset, size);
- break;
- default :
- if (cinfo->args [iParm].reg == STK_BASE) {
- /*
- * These arguments are in the previous frame, so we can't
- * compute their offset from the current frame pointer right
- * now, since cfg->stack_offset is not yet known, so dedicate a
- * register holding the previous frame pointer.
- */
- cfg->arch.bkchain_reg = s390_r12;
- cfg->used_int_regs |= 1 << cfg->arch.bkchain_reg;
-
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = cfg->arch.bkchain_reg;
- size = (cinfo->args[iParm].size < 4
- ? 4 - cinfo->args[iParm].size
- : 0);
- inst->inst_offset = cinfo->args [iParm].offset + size;
- size = sizeof (long);
- } else {
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- size = (cinfo->args[iParm].size < 8
- ? sizeof(long)
- : sizeof(long long));
- offset = S390_ALIGN(offset, size);
- inst->inst_offset = offset;
- }
- }
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (cinfo->args[iParm].regtype != RegTypeGeneral) &&
- (iParm < sig->sentinelpos))
- cfg->sig_cookie += size;
-
- offset += size;
- }
- curinst++;
- }
-
- curinst = cfg->locals_start;
- for (iVar = curinst; iVar < cfg->num_varinfo; ++iVar) {
- inst = cfg->varinfo [iVar];
- if ((inst->flags & MONO_INST_IS_DEAD) ||
- (inst->opcode == OP_REGVAR))
- continue;
-
- /*--------------------------------------------------*/
- /* inst->backend.is_pinvoke indicates native sized value types, */
- /* this is used by the pinvoke wrappers when they */
- /* call functions returning structure */
- /*--------------------------------------------------*/
- if (inst->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (inst->inst_vtype))
- size = mono_class_native_size (mono_class_from_mono_type(inst->inst_vtype), &align);
- else
- size = mono_type_size (inst->inst_vtype, &align);
-
- offset = S390_ALIGN(offset, align);
- inst->inst_offset = offset;
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- offset += size;
- DEBUG (g_print("allocating local %d to %ld\n", iVar, inst->inst_offset));
- }
-
- /*------------------------------------------------------*/
- /* Allow space for the trace method stack area if needed*/
- /*------------------------------------------------------*/
- if (mono_jit_trace_calls != NULL && mono_trace_eval (cfg->method)) {
- offset += S390_TRACE_STACK_SIZE;
- }
-
- /*------------------------------------------------------*/
- /* Reserve space to save LMF and caller saved registers */
- /*------------------------------------------------------*/
- if (cfg->method->save_lmf)
- offset += sizeof (MonoLMF);
-
- /*------------------------------------------------------*/
- /* align the offset */
- /*------------------------------------------------------*/
- cfg->stack_offset = S390_ALIGN(offset, S390_STACK_ALIGNMENT);
-
- /* Fix up offsets for arguments whose value is in the parent frame */
- for (iParm = sArg; iParm < eArg; ++iParm) {
- inst = cfg->args [iParm];
-
- if (inst->opcode == OP_S390_STKARG) {
- inst->opcode = OP_REGOFFSET;
- inst->inst_offset += cfg->stack_offset;
- }
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_vars */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_create_vars (MonoCompile *cfg)
-{
- MonoMethodSignature *sig;
- CallInfo *cinfo;
-
- sig = mono_method_signature (cfg->method);
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- if (cinfo->struct_ret) {
- cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
- if (G_UNLIKELY (cfg->verbose_level > 1)) {
- printf ("vret_addr = ");
- mono_print_ins (cfg->vret_addr);
- }
- }
-}
-
-/*========================= End of Function ========================*/
-
-static void
-add_outarg_reg2 (MonoCompile *cfg, MonoCallInst *call, ArgStorage storage, int reg, MonoInst *tree)
-{
- MonoInst *ins;
-
- switch (storage) {
- case RegTypeGeneral:
- MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->dreg = mono_alloc_ireg (cfg);
- ins->sreg1 = tree->dreg;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, FALSE);
- break;
- case RegTypeFP:
- MONO_INST_NEW (cfg, ins, OP_FMOVE);
- ins->dreg = mono_alloc_freg (cfg);
- ins->sreg1 = tree->dreg;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, TRUE);
- break;
- case RegTypeFPR4:
- MONO_INST_NEW (cfg, ins, OP_S390_SETF4RET);
- ins->dreg = mono_alloc_freg (cfg);
- ins->sreg1 = tree->dreg;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, TRUE);
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo)
-{
- MonoMethodSignature *tmpSig;
- MonoInst *sig_arg;
-
- cfg->disable_aot = TRUE;
-
- /*----------------------------------------------------------*/
- /* mono_ArgIterator_Setup assumes the signature cookie is */
- /* passed first and all the arguments which were before it */
- /* passed on the stack after the signature. So compensate */
- /* by passing a different signature. */
- /*----------------------------------------------------------*/
- tmpSig = mono_metadata_signature_dup (call->signature);
- tmpSig->param_count -= call->signature->sentinelpos;
- tmpSig->sentinelpos = 0;
- if (tmpSig->param_count > 0)
- memcpy (tmpSig->params,
- call->signature->params + call->signature->sentinelpos,
- tmpSig->param_count * sizeof(MonoType *));
-
- MONO_INST_NEW (cfg, sig_arg, OP_ICONST);
- sig_arg->dreg = mono_alloc_ireg (cfg);
- sig_arg->inst_p0 = tmpSig;
- MONO_ADD_INS (cfg->cbb, sig_arg);
-
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, STK_BASE,
- cinfo->sigCookie.offset, sig_arg->dreg);
-}
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_call */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
-{
- MonoInst *in;
- MonoMethodSignature *sig;
- MonoInst *ins;
- int i, n, lParamArea;
- CallInfo *cinfo;
- ArgInfo *ainfo = NULL;
- int stackSize;
-
- sig = call->signature;
- n = sig->param_count + sig->hasthis;
- DEBUG (g_print ("Call requires: %d parameters\n",n));
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- stackSize = cinfo->sz.stack_size + cinfo->sz.local_size + cinfo->sz.parm_size + cinfo->sz.offset;
- call->stack_usage = MAX(stackSize, call->stack_usage);
- lParamArea = MAX((call->stack_usage-S390_MINIMAL_STACK_SIZE-cinfo->sz.parm_size), 0);
- cfg->param_area = MAX(((signed) cfg->param_area), lParamArea);
- cfg->flags |= MONO_CFG_HAS_CALLS;
-
- if (cinfo->struct_ret) {
- MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->sreg1 = call->vret_var->dreg;
- ins->dreg = mono_alloc_preg (cfg);
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, cinfo->ret.reg, FALSE);
- }
-
- for (i = 0; i < n; ++i) {
- ainfo = cinfo->args + i;
- MonoType *t;
-
- if (i >= sig->hasthis)
- t = sig->params [i - sig->hasthis];
- else
- t = &mono_defaults.int_class->byval_arg;
- t = mono_type_get_underlying_type (t);
-
- in = call->args [i];
-
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (i == sig->sentinelpos)) {
- emit_sig_cookie (cfg, call, cinfo);
- }
-
- switch (ainfo->regtype) {
- case RegTypeGeneral:
- if (!t->byref && (t->type == MONO_TYPE_I8 || t->type == MONO_TYPE_U8)) {
- MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->dreg = mono_alloc_ireg (cfg);
- ins->sreg1 = in->dreg + 2;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, FALSE);
- MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->dreg = mono_alloc_ireg (cfg);
- ins->sreg1 = in->dreg + 1;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg + 1, FALSE);
- } else {
- add_outarg_reg2 (cfg, call, ainfo->regtype, ainfo->reg, in);
- }
- break;
- case RegTypeFP:
- if (MONO_TYPE_ISSTRUCT (t)) {
- /* Valuetype passed in one fp register */
- ainfo->regtype = RegTypeStructByValInFP;
- /* Fall through */
- } else {
- if (ainfo->size == 4)
- ainfo->regtype = RegTypeFPR4;
- add_outarg_reg2 (cfg, call, ainfo->regtype, ainfo->reg, in);
- break;
- }
- case RegTypeStructByVal:
- case RegTypeStructByAddr: {
- guint32 align;
- guint32 size;
-
- if (sig->params [i - sig->hasthis]->type == MONO_TYPE_TYPEDBYREF) {
- size = sizeof (MonoTypedRef);
- align = sizeof (gpointer);
- }
- else
- if (sig->pinvoke)
- size = mono_type_native_stack_size (&in->klass->byval_arg, &align);
- else {
- /*
- * Other backends use mono_type_stack_size (), but that
- * aligns the size to 8, which is larger than the size of
- * the source, leading to reads of invalid memory if the
- * source is at the end of address space.
- */
- size = mono_class_value_size (in->klass, &align);
- }
-
- g_assert (in->klass);
-
- ainfo->offparm += cinfo->sz.offStruct;
-
- MONO_INST_NEW (cfg, ins, OP_OUTARG_VT);
- ins->sreg1 = in->dreg;
- ins->klass = in->klass;
- ins->backend.size = ainfo->size;
- ins->inst_p0 = call;
- ins->inst_p1 = mono_mempool_alloc (cfg->mempool, sizeof (ArgInfo));
- memcpy (ins->inst_p1, ainfo, sizeof (ArgInfo));
-
- MONO_ADD_INS (cfg->cbb, ins);
-
- if (ainfo->regtype == RegTypeStructByAddr) {
- /*
- * We use OP_OUTARG_VT to copy the valuetype to a stack location, then
- * use the normal OUTARG opcodes to pass the address of the location to
- * the callee.
- */
- int treg = mono_alloc_preg (cfg);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADD_IMM, treg,
- STK_BASE, ainfo->offparm);
- if (ainfo->reg == STK_BASE) {
- /* The address is passed on the stack */
- MONO_INST_NEW (cfg, ins, OP_STORE_MEMBASE_REG);
- ins->inst_destbasereg = STK_BASE;
- ins->inst_offset = ainfo->offset;
- ins->sreg1 = treg;
- MONO_ADD_INS (cfg->cbb, ins);
- } else {
- mono_call_inst_add_outarg_reg (cfg, call, treg, ainfo->reg, FALSE);
- }
- }
- break;
- }
- case RegTypeBase:
- if (!t->byref && t->type == MONO_TYPE_R4) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG,
- STK_BASE, ainfo->offset,
- in->dreg);
- } else if (!t->byref && (t->type == MONO_TYPE_R8)) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG,
- STK_BASE, ainfo->offset,
- in->dreg);
- } else if (!t->byref && (t->type == MONO_TYPE_I8 || t->type == MONO_TYPE_U8)) {
- MONO_INST_NEW (cfg, ins, OP_STORE_MEMBASE_REG);
- ins->inst_destbasereg = STK_BASE;
- ins->inst_offset = ainfo->offset + MINI_LS_WORD_OFFSET;
- ins->sreg1 = in->dreg + 1;
- MONO_ADD_INS (cfg->cbb, ins);
-
- MONO_INST_NEW (cfg, ins, OP_STORE_MEMBASE_REG);
- ins->inst_destbasereg = STK_BASE;
- ins->inst_offset = ainfo->offset + MINI_MS_WORD_OFFSET;
- ins->sreg1 = in->dreg + 2;
- MONO_ADD_INS (cfg->cbb, ins);
- } else {
- MONO_INST_NEW (cfg, ins, OP_STORE_MEMBASE_REG);
- ins->inst_destbasereg = STK_BASE;
- ins->inst_offset = ainfo->offset;
- ins->sreg1 = in->dreg;
- MONO_ADD_INS (cfg->cbb, ins);
- }
- break;
- default:
- g_assert_not_reached ();
- break;
- }
- }
-
- /*
- * Handle the case where there are no implicit arguments
- */
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (i == sig->sentinelpos)) {
- emit_sig_cookie (cfg, call, cinfo);
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_outarg_vt */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
-{
- MonoCallInst *call = (MonoCallInst*)ins->inst_p0;
- ArgInfo *ainfo = (ArgInfo*)ins->inst_p1;
- int size = ins->backend.size;
-
- if (ainfo->regtype == RegTypeStructByVal) {
- /*
- arg->ins.sreg1 = ainfo->reg;
- arg->ins.opcode = OP_OUTARG_VT;
- arg->size = ainfo->size;
- arg->offset = ainfo->offset;
- arg->offPrm = ainfo->offparm + cinfo->sz.offStruct;
- */
- if (ainfo->reg != STK_BASE) {
- MONO_OUTPUT_VTR (cfg, size, ainfo->reg, src->dreg, 0);
- } else {
- MONO_OUTPUT_VTS (cfg, size, ainfo->reg, ainfo->offset,
- src->dreg, 0);
- }
- } else if (ainfo->regtype == RegTypeStructByValInFP) {
- int dreg = mono_alloc_freg (cfg);
-
- if (ainfo->size == 4) {
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR4_MEMBASE, dreg, src->dreg, 0);
- MONO_EMIT_NEW_UNALU (cfg, OP_S390_SETF4RET, dreg, dreg);
- } else {
- g_assert (ainfo->size == 8);
-
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, dreg, src->dreg, 0);
- }
-
- mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg, TRUE);
- } else {
- MONO_EMIT_NEW_MOVE (cfg, STK_BASE, ainfo->offparm,
- src->dreg, 0, size);
- }
-}
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_setret */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
-{
- MonoType *ret = mono_type_get_underlying_type (mono_method_signature (method)->ret);
-
- if (!ret->byref) {
- if (ret->type == MONO_TYPE_R4) {
- MONO_EMIT_NEW_UNALU (cfg, OP_S390_SETF4RET, s390_f0, val->dreg);
- return;
- } else if (ret->type == MONO_TYPE_R8) {
- MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, s390_f0, val->dreg);
- return;
- } else if (ret->type == MONO_TYPE_I8 || ret->type == MONO_TYPE_U8) {
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, s390_r3, val->dreg + 1);
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, s390_r2, val->dreg + 2);
- return;
- }
- }
-
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, cfg->ret->dreg, val->dreg);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_instrument_mem_needs */
-/* */
-/* Function - Allow tracing to work with this interface (with */
-/* an optional argument). */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_instrument_mem_needs (MonoMethod *method, int *stack, int *code)
-{
- /* no stack room needed now (may be needed for FASTCALL-trace support) */
- *stack = 0;
- /* split prolog-epilog requirements? */
- *code = 50; /* max bytes needed: check this number */
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_instrument_prolog */
-/* */
-/* Function - Create an "instrumented" prolog. */
-/* */
-/*------------------------------------------------------------------*/
-
-void*
-mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p,
- gboolean enable_arguments)
-{
- guchar *code = p;
- int parmOffset,
- fpOffset,
- baseReg;
-
- parmOffset = cfg->stack_usage - S390_TRACE_STACK_SIZE;
- if (cfg->method->save_lmf)
- parmOffset -= sizeof(MonoLMF);
- fpOffset = parmOffset + (5*sizeof(gint32));
- if (fpOffset > 4096) {
- s390_lr (code, s390_r12, STK_BASE);
- baseReg = s390_r12;
- while (fpOffset > 4096) {
- s390_ahi (code, baseReg, 4096);
- fpOffset -= 4096;
- parmOffset -= 4096;
- }
- } else {
- baseReg = STK_BASE;
- }
-
- s390_stm (code, s390_r2, s390_r6, baseReg, parmOffset);
- s390_std (code, s390_f0, 0, baseReg, fpOffset);
- s390_std (code, s390_f1, 0, baseReg, fpOffset+sizeof(gdouble));
- s390_std (code, s390_f2, 0, baseReg, fpOffset+2*sizeof(gdouble));
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, cfg->method);
- s390_word (code, func);
- s390_l (code, s390_r2, 0, s390_r13, 4);
- s390_la (code, s390_r3, 0, baseReg, parmOffset);
- s390_lr (code, s390_r4, STK_BASE);
- s390_ahi (code, s390_r4, cfg->stack_usage);
- s390_l (code, s390_r1, 0, s390_r13, 8);
- s390_basr (code, s390_r14, s390_r1);
- s390_ld (code, s390_f2, 0, baseReg, fpOffset+2*sizeof(gdouble));
- s390_ld (code, s390_f1, 0, baseReg, fpOffset+sizeof(gdouble));
- s390_ld (code, s390_f0, 0, baseReg, fpOffset);
- s390_lm (code, s390_r2, s390_r6, baseReg, parmOffset);
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_instrument_epilog */
-/* */
-/* Function - Create an epilog that will handle the returned */
-/* values used in instrumentation. */
-/* */
-/*------------------------------------------------------------------*/
-
-void*
-mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments, gboolean preserve_argument_registers)
-{
- guchar *code = p;
- int save_mode = SAVE_NONE,
- saveOffset;
- MonoMethod *method = cfg->method;
- int rtype = mono_type_get_underlying_type (mono_method_signature (method)->ret)->type;
-
- saveOffset = cfg->stack_usage - S390_TRACE_STACK_SIZE;
- if (method->save_lmf)
- saveOffset -= sizeof(MonoLMF);
-
-handle_enum:
- switch (rtype) {
- case MONO_TYPE_VOID:
- /* special case string .ctor icall */
- if (strcmp (".ctor", method->name) && method->klass == mono_defaults.string_class)
- save_mode = SAVE_ONE;
- else
- save_mode = SAVE_NONE;
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- save_mode = SAVE_TWO;
- break;
- case MONO_TYPE_R4:
- save_mode = SAVE_R4;
- break;
- case MONO_TYPE_R8:
- save_mode = SAVE_R8;
- break;
- case MONO_TYPE_VALUETYPE:
- if (mono_method_signature (method)->ret->data.klass->enumtype) {
- rtype = mono_class_enum_basetype (mono_method_signature (method)->ret->data.klass)->type;
- goto handle_enum;
- }
- save_mode = SAVE_STRUCT;
- break;
- default:
- save_mode = SAVE_ONE;
- break;
- }
-
- switch (save_mode) {
- case SAVE_TWO:
- s390_stm (code, s390_r2, s390_r3, cfg->frame_reg, saveOffset);
- if (enable_arguments) {
- s390_lr (code, s390_r4, s390_r3);
- s390_lr (code, s390_r3, s390_r2);
- }
- break;
- case SAVE_ONE:
- s390_st (code, s390_r2, 0, cfg->frame_reg, saveOffset);
- if (enable_arguments) {
- s390_lr (code, s390_r3, s390_r2);
- }
- break;
- case SAVE_R4:
- s390_std (code, s390_f0, 0, cfg->frame_reg, saveOffset);
- if (enable_arguments) {
- s390_ldebr (code, s390_f0, s390_f0);
- }
- break;
- case SAVE_R8:
- s390_std (code, s390_f0, 0, cfg->frame_reg, saveOffset);
- break;
- case SAVE_STRUCT:
- s390_st (code, s390_r2, 0, cfg->frame_reg, saveOffset);
- if (enable_arguments) {
- s390_l (code, s390_r3, 0, cfg->frame_reg,
- S390_MINIMAL_STACK_SIZE+cfg->param_area);
- }
- break;
- case SAVE_NONE:
- default:
- break;
- }
-
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, cfg->method);
- s390_word (code, func);
- s390_l (code, s390_r2, 0, s390_r13, 4);
- s390_l (code, s390_r1, 0, s390_r13, 8);
- s390_basr (code, s390_r14, s390_r1);
-
- switch (save_mode) {
- case SAVE_TWO:
- s390_lm (code, s390_r2, s390_r3, cfg->frame_reg, saveOffset);
- break;
- case SAVE_ONE:
- s390_l (code, s390_r2, 0, cfg->frame_reg, saveOffset);
- break;
- case SAVE_R4:
- case SAVE_R8:
- s390_ld (code, s390_f0, 0, cfg->frame_reg, saveOffset);
- break;
- case SAVE_STRUCT:
- s390_l (code, s390_r2, 0, cfg->frame_reg, saveOffset);
- break;
- case SAVE_NONE:
- default:
- break;
- }
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-void
-mono_arch_peephole_pass_1 (MonoCompile *cfg, MonoBasicBlock *bb)
-{
-}
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_peephole_pass */
-/* */
-/* Function - Form a peephole pass at the code looking for */
-/* simple optimizations. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb)
-{
- MonoInst *ins, *n;
-
- MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
- mono_peephole_ins (bb, ins);
- }
-}
-
-/*========================= End of Function ========================*/
-
-void
-mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
-{
- MonoInst *ins, *next;
-
- MONO_BB_FOR_EACH_INS_SAFE (bb, next, ins) {
- switch (ins->opcode) {
- case OP_DIV_IMM:
- case OP_REM_IMM:
- case OP_IDIV_IMM:
- case OP_IREM_IMM:
- case OP_IDIV_UN_IMM:
- case OP_IREM_UN_IMM:
- case OP_LOCALLOC_IMM:
- mono_decompose_op_imm (cfg, bb, ins);
- break;
- default:
- break;
- }
- }
-
- bb->max_vreg = cfg->next_vreg;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_float_to_int */
-/* */
-/* Function - Create instructions which will convert a floating */
-/* point value to integer. */
-/* */
-/*------------------------------------------------------------------*/
-
-static guchar*
-emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, gboolean is_signed)
-{
- /* sreg is a float, dreg is an integer reg. */
- if (is_signed) {
- s390_cfdbr (code, dreg, 5, sreg);
- switch (size) {
- case 1:
- s390_lhi (code, s390_r0, 0);
- s390_lhi (code, s390_r13, 0xff);
- s390_ltr (code, dreg, dreg);
- s390_jnl (code, 4);
- s390_lhi (code, s390_r0, 0x80);
- s390_nr (code, dreg, s390_r13);
- s390_or (code, dreg, s390_r0);
- break;
- }
- } else {
- short *o[1];
- s390_basr (code, s390_r13, 0);
- s390_j (code, 10);
- s390_llong (code, 0x41e0000000000000LL);
- s390_llong (code, 0x41f0000000000000LL);
- s390_ldr (code, s390_f15, sreg);
- s390_cdb (code, s390_f15, 0, s390_r13, 4);
- s390_jl (code, 0); CODEPTR(code, o[0]);
- s390_sdb (code, s390_f15, 0, s390_r13, 12);
- s390_cfdbr (code, dreg, 7, s390_f15);
- s390_j (code, 4);
- PTRSLOT(code, o[0]);
- s390_cfdbr (code, dreg, 5, sreg);
- switch (size) {
- case 1:
- s390_lhi (code, s390_r0, 0xff);
- s390_nr (code, dreg, s390_r0);
- break;
- case 2:
- s390_lhi (code, s390_r0, -1);
- s390_srl (code, s390_r0, 0, 16);
- s390_nr (code, dreg, s390_r0);
- break;
- }
- }
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_output_basic_block */
-/* */
-/* Function - Perform the "real" work of emitting instructions */
-/* that will do the work of in the basic block. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
-{
- MonoInst *ins;
- MonoCallInst *call;
- guint offset;
- guint8 *code = cfg->native_code + cfg->code_len;
- MonoInst *last_ins = NULL;
- guint last_offset = 0;
- int max_len, cpos, src2;
-
- /* we don't align basic blocks of loops on s390 */
-
- if (cfg->verbose_level > 2)
- g_print ("Basic block %d starting at offset 0x%x\n", bb->block_num, bb->native_offset);
-
- cpos = bb->max_offset;
-
- if (cfg->prof_options & MONO_PROFILE_COVERAGE) {
- //MonoCoverageInfo *cov = mono_get_coverage_info (cfg->method);
- //g_assert (!mono_compile_aot);
- //cpos += 6;
- //if (bb->cil_code)
- // cov->data [bb->dfn].iloffset = bb->cil_code - cfg->cil_code;
- /* this is not thread save, but good enough */
- /* fixme: howto handle overflows? */
- //x86_inc_mem (code, &cov->data [bb->dfn].count);
- }
-
- MONO_BB_FOR_EACH_INS (bb, ins) {
- offset = code - cfg->native_code;
-
- max_len = ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
-
- if (offset > (cfg->code_size - max_len - 16)) {
- cfg->code_size *= 2;
- cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- code = cfg->native_code + offset;
- }
-
- mono_debug_record_line_number (cfg, ins, offset);
-
- switch (ins->opcode) {
- case OP_STOREI1_MEMBASE_IMM: {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (s390_is_uimm12(ins->inst_offset))
- s390_stc (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_stc (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STOREI2_MEMBASE_IMM: {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_sth (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_sth (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STORE_MEMBASE_IMM:
- case OP_STOREI4_MEMBASE_IMM: {
- if (s390_is_imm16(ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_l (code, s390_r0, 0, s390_r13, 4);
- }
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_st (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_st (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STOREI1_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_stc (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_stc (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STOREI2_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_sth (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_sth (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STORE_MEMBASE_REG:
- case OP_STOREI4_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_st (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_st (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_LOADU4_MEM:
- g_assert_not_reached ();
- break;
- case OP_LOAD_MEMBASE:
- case OP_LOADI4_MEMBASE:
- case OP_LOADU4_MEMBASE: {
- if (s390_is_uimm12(ins->inst_offset))
- s390_l (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- if (s390_is_imm16(ins->inst_offset)) {
- s390_lhi (code, s390_r13, ins->inst_offset);
- s390_l (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_l (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
- }
- }
- break;
- case OP_LOADU1_MEMBASE: {
- s390_lhi (code, s390_r0, 0);
- if (s390_is_uimm12(ins->inst_offset))
- s390_ic (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ic (code, s390_r0, s390_r13, ins->inst_basereg, 0);
- }
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_LOADI1_MEMBASE: {
- s390_lhi (code, s390_r0, 0);
- if (s390_is_uimm12(ins->inst_offset))
- s390_ic (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ic (code, s390_r0, s390_r13, ins->inst_basereg, 0);
- }
- s390_lhi (code, s390_r13, 0x80);
- s390_nr (code, s390_r13, s390_r0);
- s390_jz (code, 5);
- s390_lhi (code, s390_r13, 0xff00);
- s390_or (code, s390_r0, s390_r13);
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_LOADU2_MEMBASE: {
- s390_lhi (code, s390_r0, 0);
- if (s390_is_uimm12(ins->inst_offset))
- s390_icm (code, s390_r0, 3, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ar (code, s390_r13, ins->inst_basereg);
- s390_icm (code, s390_r0, 3, s390_r13, 0);
- }
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_LOADI2_MEMBASE: {
- s390_lhi (code, s390_r0, 0);
- if (s390_is_uimm12(ins->inst_offset))
- s390_lh (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_lh (code, s390_r0, s390_r13, ins->inst_basereg, 0);
- }
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
-
- case OP_ICONV_TO_I1: {
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_sll (code, ins->dreg, 0, 24);
- s390_sra (code, ins->dreg, 0, 24);
- }
- break;
- case OP_ICONV_TO_I2: {
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_sll (code, ins->dreg, 0, 16);
- s390_sra (code, ins->dreg, 0, 16);
- }
- break;
- case OP_ICONV_TO_U1: {
- s390_lhi (code, s390_r0, 0xff);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_nr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_ICONV_TO_U2: {
- s390_lhi (code, s390_r0, -1);
- s390_sll (code, s390_r0, 0, 16);
- s390_srl (code, s390_r0, 0, 16);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_nr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_COMPARE:
- case OP_ICOMPARE: {
- gboolean un = FALSE;
- MonoInst *next = ins->next;
-
- if ((next) &&
- (((next->opcode >= OP_IBNE_UN) &&
- (next->opcode <= OP_IBLT_UN)) ||
- ((next->opcode >= OP_COND_EXC_NE_UN) &&
- (next->opcode <= OP_COND_EXC_LT_UN)) ||
- ((next->opcode >= OP_COND_EXC_INE_UN) &&
- (next->opcode <= OP_COND_EXC_ILT_UN)) ||
- ((next->opcode == OP_CLT_UN) ||
- (next->opcode == OP_CGT_UN)) ||
- ((next->opcode == OP_ICLT_UN) ||
- (next->opcode == OP_ICGT_UN))))
- un = TRUE;
-
- if (un)
- s390_clr (code, ins->sreg1, ins->sreg2);
- else
- s390_cr (code, ins->sreg1, ins->sreg2);
- }
- break;
- case OP_COMPARE_IMM:
- case OP_ICOMPARE_IMM: {
- gboolean un = FALSE;
- MonoInst *next = ins->next;
-
- if ((next) &&
- (((next->opcode >= OP_IBNE_UN) &&
- (next->opcode <= OP_IBLT_UN)) ||
- ((next->opcode >= OP_COND_EXC_NE_UN) &&
- (next->opcode <= OP_COND_EXC_LT_UN)) ||
- ((next->opcode >= OP_COND_EXC_INE_UN) &&
- (next->opcode <= OP_COND_EXC_ILT_UN)) ||
- ((next->opcode == OP_CLT_UN) ||
- (next->opcode == OP_CGT_UN)) ||
- ((next->opcode == OP_ICLT_UN) ||
- (next->opcode == OP_ICGT_UN))))
- un = TRUE;
-
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (un)
- s390_clr (code, ins->sreg1, s390_r0);
- else
- s390_cr (code, ins->sreg1, s390_r0);
- }
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (un)
- s390_cl (code, ins->sreg1, 0, s390_r13, 4);
- else
- s390_c (code, ins->sreg1, 0, s390_r13, 4);
- }
- }
- break;
- case OP_BREAK: {
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, mono_break);
- s390_brasl (code, s390_r14, 0);
- }
- break;
- case OP_ADDCC:
- case OP_IADDCC: {
- CHECK_SRCDST_COM;
- s390_alr (code, ins->dreg, src2);
- }
- break;
- case OP_IADD: {
- CHECK_SRCDST_COM;
- s390_ar (code, ins->dreg, src2);
- }
- break;
- case OP_ADC:
- case OP_IADC: {
- CHECK_SRCDST_COM;
- s390_alcr (code, ins->dreg, src2);
- }
- break;
- case OP_ADD_IMM:
- case OP_IADD_IMM: {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- if ((ins->next) &&
- (ins->next->opcode == OP_ADC_IMM)) {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_a (code, ins->dreg, 0, s390_r13, 4);
- } else {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_ahi (code, ins->dreg, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_a (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- }
- break;
- case OP_ADDCC_IMM: {
- if ((ins->next) &&
- (ins->next->opcode == OP_ADC_IMM)) {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_al (code, ins->dreg, 0, s390_r13, 4);
- } else {
- if (s390_is_imm16 (ins->inst_imm)) {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_lhi (code, s390_r0, ins->inst_imm);
- s390_alcr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_al (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- }
- break;
- case OP_ADC_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_lhi (code, s390_r0, ins->inst_imm);
- s390_alcr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_alcr (code, ins->dreg, s390_r13);
- }
- }
- break;
- case OP_IADD_OVF:
- case OP_S390_IADD_OVF: {
- CHECK_SRCDST_COM;
- s390_ar (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- }
- break;
- case OP_IADD_OVF_UN:
- case OP_S390_IADD_OVF_UN: {
- CHECK_SRCDST_COM;
- s390_alr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, "OverflowException");
- }
- break;
- case OP_LADD:
- case OP_S390_LADD: {
- s390_alr (code, s390_r0, ins->sreg1);
- s390_jnc (code, 4);
- s390_ahi (code, s390_r1, 1);
- s390_ar (code, s390_r1, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_LADD_OVF:
- case OP_S390_LADD_OVF: {
- short int *o[1];
- s390_alr (code, s390_r0, ins->sreg1);
- s390_jnc (code, 0); CODEPTR(code, o[0]);
- s390_ahi (code, s390_r1, 1);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- PTRSLOT (code, o[0]);
- s390_ar (code, s390_r1, ins->sreg2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_LADD_OVF_UN:
- case OP_S390_LADD_OVF_UN: {
- s390_alr (code, s390_r0, ins->sreg1);
- s390_alcr (code, s390_r1, ins->sreg2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, "OverflowException");
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_ADD_OVF_CARRY: {
- CHECK_SRCDST_COM;
- s390_lhi (code, s390_r0, 0);
- s390_lr (code, s390_r1, s390_r0);
- s390_alcr (code, s390_r0, s390_r1);
- s390_ar (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- s390_ar (code, ins->dreg, s390_r0);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- }
- break;
- case OP_ADD_OVF_UN_CARRY: {
- CHECK_SRCDST_COM;
- s390_alcr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, "OverflowException");
- }
- break;
- case OP_SUBCC:
- case OP_ISUBCC: {
- CHECK_SRCDST_NCOM;
- s390_slr (code, ins->dreg, src2);
- }
- break;
- case OP_ISUB: {
- CHECK_SRCDST_NCOM;
- s390_sr (code, ins->dreg, src2);
- }
- break;
- case OP_SBB:
- case OP_ISBB: {
- CHECK_SRCDST_NCOM;
- s390_slbr (code, ins->dreg, src2);
- }
- break;
- case OP_SUBCC_IMM: {
- if (s390_is_imm16 (-ins->inst_imm)) {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_lhi (code, s390_r0, ins->inst_imm);
- s390_slr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_sl (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_SUB_IMM:
- case OP_ISUB_IMM: {
- if (s390_is_imm16 (-ins->inst_imm)) {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_ahi (code, ins->dreg, -ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_s (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_SBB_IMM: {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- if (s390_is_imm16 (-ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- s390_slbr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_slb (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_ISUB_OVF:
- case OP_S390_ISUB_OVF: {
- CHECK_SRCDST_NCOM;
- s390_sr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- }
- break;
- case OP_ISUB_OVF_UN:
- case OP_S390_ISUB_OVF_UN: {
- CHECK_SRCDST_NCOM;
- s390_slr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NC, "OverflowException");
- }
- break;
- case OP_LSUB:
- case OP_S390_LSUB: {
- s390_lr (code, s390_r14, ins->sreg2);
- s390_slr (code, s390_r0, ins->sreg1);
- s390_jnl (code, 4);
- s390_ahi (code, s390_r14, 1);
- s390_sr (code, s390_r1, s390_r14);
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_LSUB_OVF:
- case OP_S390_LSUB_OVF: {
- short int *o[1];
- s390_lr (code, s390_r14, ins->sreg2);
- s390_slr (code, s390_r0, ins->sreg1);
- s390_jnl (code, 0); CODEPTR(code, o[0]);
- s390_ahi (code, s390_r14, 1);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- PTRSLOT (code, o[0]);
- s390_sr (code, s390_r1, s390_r14);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_LSUB_OVF_UN:
- case OP_S390_LSUB_OVF_UN: {
- s390_slr (code, s390_r0, ins->sreg1);
- s390_slbr (code, s390_r1, ins->sreg2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LT, "OverflowException");
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_SUB_OVF_CARRY: {
- CHECK_SRCDST_NCOM;
- s390_lhi (code, s390_r0, 0);
- s390_lr (code, s390_r1, s390_r0);
- s390_slbr (code, s390_r0, s390_r1);
- s390_sr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- s390_ar (code, ins->dreg, s390_r0);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- }
- break;
- case OP_SUB_OVF_UN_CARRY: {
- CHECK_SRCDST_NCOM;
- s390_slbr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NC, "OverflowException");
- }
- break;
- case OP_IAND: {
- if (ins->sreg1 == ins->dreg) {
- s390_nr (code, ins->dreg, ins->sreg2);
- }
- else {
- if (ins->sreg2 == ins->dreg) {
- s390_nr (code, ins->dreg, ins->sreg1);
- }
- else {
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_nr (code, ins->dreg, ins->sreg2);
- }
- }
- }
- break;
- case OP_AND_IMM:
- case OP_IAND_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_nr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_n (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_IDIV: {
- s390_lr (code, s390_r0, ins->sreg1);
- s390_srda (code, s390_r0, 0, 32);
- s390_dr (code, s390_r0, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_IDIV_UN: {
- s390_lr (code, s390_r0, ins->sreg1);
- s390_srdl (code, s390_r0, 0, 32);
- s390_dlr (code, s390_r0, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_IREM: {
- s390_lr (code, s390_r0, ins->sreg1);
- s390_srda (code, s390_r0, 0, 32);
- s390_dr (code, s390_r0, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r0);
- break;
- case OP_IREM_UN:
- s390_lr (code, s390_r0, ins->sreg1);
- s390_srdl (code, s390_r0, 0, 32);
- s390_dlr (code, s390_r0, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_IOR: {
- if (ins->sreg1 == ins->dreg) {
- s390_or (code, ins->dreg, ins->sreg2);
- }
- else {
- if (ins->sreg2 == ins->dreg) {
- s390_or (code, ins->dreg, ins->sreg1);
- }
- else {
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_or (code, ins->dreg, ins->sreg2);
- }
- }
- }
- break;
- case OP_OR_IMM:
- case OP_IOR_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_or (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_o (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_IXOR: {
- if (ins->sreg1 == ins->dreg) {
- s390_xr (code, ins->dreg, ins->sreg2);
- }
- else {
- if (ins->sreg2 == ins->dreg) {
- s390_xr (code, ins->dreg, ins->sreg1);
- }
- else {
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_xr (code, ins->dreg, ins->sreg2);
- }
- }
- }
- break;
- case OP_XOR_IMM:
- case OP_IXOR_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_xr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_x (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_ISHL: {
- CHECK_SRCDST_NCOM;
- s390_sll (code, ins->dreg, src2, 0);
- }
- break;
- case OP_SHL_IMM:
- case OP_ISHL_IMM: {
- if (ins->sreg1 != ins->dreg) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_sll (code, ins->dreg, 0, (ins->inst_imm & 0x1f));
- }
- break;
- case OP_ISHR: {
- CHECK_SRCDST_NCOM;
- s390_sra (code, ins->dreg, src2, 0);
- }
- break;
- case OP_SHR_IMM:
- case OP_ISHR_IMM: {
- if (ins->sreg1 != ins->dreg) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_sra (code, ins->dreg, 0, (ins->inst_imm & 0x1f));
- }
- break;
- case OP_SHR_UN_IMM:
- case OP_ISHR_UN_IMM: {
- if (ins->sreg1 != ins->dreg) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_srl (code, ins->dreg, 0, (ins->inst_imm & 0x1f));
- }
- break;
- case OP_ISHR_UN: {
- CHECK_SRCDST_NCOM;
- s390_srl (code, ins->dreg, src2, 0);
- }
- break;
- case OP_INOT: {
- if (ins->sreg1 != ins->dreg) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_lhi (code, s390_r0, -1);
- s390_xr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_INEG: {
- s390_lcr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_S390_LNEG: {
- /* From gcc code */
- g_assert (ins->dreg + 1 != ins->sreg1);
- s390_lcr (code, ins->dreg + 1, ins->sreg2);
- s390_lcr (code, ins->dreg, ins->sreg1);
- s390_je (code, 3);
- s390_bctr (code, ins->dreg + 1, 0);
- }
- break;
- case OP_IMUL: {
- if (ins->sreg1 == ins->dreg) {
- s390_msr (code, ins->dreg, ins->sreg2);
- }
- else {
- if (ins->sreg2 == ins->dreg) {
- s390_msr (code, ins->dreg, ins->sreg1);
- }
- else {
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_msr (code, ins->dreg, ins->sreg2);
- }
- }
- }
- break;
- case OP_MUL_IMM:
- case OP_IMUL_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r13, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
-// if (ins->dreg != ins->sreg1) {
-// s390_lr (code, ins->dreg, ins->sreg1);
-// }
- s390_l (code, s390_r13, 0, s390_r13, 4);
- }
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_msr (code, ins->dreg, s390_r13);
- }
- break;
- case OP_IMUL_OVF: {
- short int *o[2];
- s390_ltr (code, s390_r1, ins->sreg1);
- s390_jz (code, 0); CODEPTR(code, o[0]);
- s390_ltr (code, s390_r0, ins->sreg2);
- s390_jnz (code, 6);
- s390_lhi (code, s390_r1, 0);
- s390_j (code, 0); CODEPTR(code, o[1]);
- s390_xr (code, s390_r0, s390_r1);
- s390_msr (code, s390_r1, ins->sreg2);
- s390_xr (code, s390_r0, s390_r1);
- s390_srl (code, s390_r0, 0, 31);
- s390_ltr (code, s390_r0, s390_r0);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NZ, "OverflowException");
- PTRSLOT (code, o[0]);
- PTRSLOT (code, o[1]);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_IMUL_OVF_UN: {
- s390_lhi (code, s390_r0, 0);
- s390_lr (code, s390_r1, ins->sreg1);
- s390_mlr (code, s390_r0, ins->sreg2);
- s390_ltr (code, s390_r0, s390_r0);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NZ, "OverflowException");
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_LMUL: {
- s390_l (code, s390_r0, 0, ins->sreg1, 4);
- s390_srda (code, s390_r0, 0, 32);
- s390_m (code, s390_r0, 0, ins->sreg2, 4);
- s390_l (code, s390_r0, 0, ins->sreg1, 4);
- s390_srl (code, s390_r0, 0, 31);
- s390_a (code, s390_r0, 0, ins->sreg1, 0);
- s390_l (code, s390_r13, 0, ins->sreg2, 0);
- s390_srl (code, s390_r13, 0, 31);
- s390_ms (code, s390_r13, 0, ins->sreg1, 4);
- s390_ar (code, s390_r0, s390_r13);
- s390_st (code, s390_r0, 0, ins->dreg, 0);
- s390_st (code, s390_r1, 0, ins->dreg, 4);
- }
- break;
- case OP_ICONST: {
- if (s390_is_imm16(ins->inst_c0)) {
- s390_lhi (code, ins->dreg, ins->inst_c0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_c0);
- s390_l (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_AOTCONST: {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- mono_add_patch_info (cfg, code - cfg->native_code,
- (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
- s390_word (code, 0);
- s390_l (code,ins->dreg, 0, s390_r13, 4);
- }
- break;
- case OP_JUMP_TABLE: {
- mono_add_patch_info (cfg, code - cfg->native_code,
- (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, 0);
- s390_l (code, ins->dreg, 0, s390_r13, 4);
- }
- break;
- case OP_ICONV_TO_I4:
- case OP_ICONV_TO_U4:
- case OP_MOVE: {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- }
- break;
- case OP_SETLRET: {
- int saved = ins->sreg1;
- if (ins->sreg1 == s390_r2) {
- s390_lr (code, s390_r0, ins->sreg1);
- saved = s390_r0;
- }
- if (ins->sreg2 != s390_r2)
- s390_lr (code, s390_r2, ins->sreg2);
- if (saved != s390_r3)
- s390_lr (code, s390_r3, saved);
- break;
- }
- case OP_FMOVE: {
- if (ins->dreg != ins->sreg1) {
- s390_ldr (code, ins->dreg, ins->sreg1);
- }
- }
- break;
- case OP_S390_SETF4RET: {
- s390_ledbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_TLS_GET: {
- if (s390_is_imm16 (ins->inst_offset)) {
- s390_lhi (code, s390_r13, ins->inst_offset);
- } else {
- s390_bras (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- }
- s390_ear (code, s390_r1, 0);
- s390_l (code, ins->dreg, s390_r13, s390_r1, 0);
- }
- break;
- case OP_FCONV_TO_R4: {
- // FIXME:
- if (ins->dreg != ins->sreg1) {
- s390_ldr (code, ins->dreg, ins->sreg1);
- }
- /*
- NOT_IMPLEMENTED;
- if ((ins->next) &&
- (ins->next->opcode != OP_FMOVE) &&
- (ins->next->opcode != OP_STORER4_MEMBASE_REG))
- s390_ledbr (code, ins->dreg, ins->sreg1);
- */
- }
- break;
- case OP_JMP: {
- if (cfg->method->save_lmf)
- restoreLMF(code, cfg->frame_reg, cfg->stack_usage);
-
- if (cfg->flags & MONO_CFG_HAS_TAIL) {
- code = emit_load_volatile_registers(code, cfg);
- }
-
- code = backUpStackPtr(cfg, code, STK_BASE);
- s390_l (code, s390_r14, 0, STK_BASE, S390_RET_ADDR_OFFSET);
- mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_METHOD_JUMP,
- ins->inst_p0);
- s390_jcl (code, S390_CC_UN, 0);
- }
- break;
- case OP_CHECK_THIS: {
- /* ensure ins->sreg1 is not NULL */
- s390_icm (code, s390_r0, 15, ins->sreg1, 0);
- }
- break;
- case OP_ARGLIST: {
- int offset = cfg->sig_cookie + cfg->stack_usage;
-
- if (s390_is_imm16 (offset))
- s390_lhi (code, s390_r0, offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, offset);
- s390_l (code, s390_r0, 0, s390_r13, 0);
- }
- s390_ar (code, s390_r0, cfg->frame_reg);
- s390_st (code, s390_r0, 0, ins->sreg1, 0);
- }
- break;
- case OP_FCALL: {
- call = (MonoCallInst*)ins;
- if (ins->flags & MONO_INST_HAS_METHOD)
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD,
- call->method);
- else
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS,
- call->fptr);
- s390_brasl (code, s390_r14, 0);
- if (call->signature->ret->type == MONO_TYPE_R4)
- s390_ldebr (code, s390_f0, s390_f0);
- }
- break;
- case OP_LCALL:
- case OP_VCALL:
- case OP_VCALL2:
- case OP_VOIDCALL:
- case OP_CALL: {
- call = (MonoCallInst*)ins;
- if (ins->flags & MONO_INST_HAS_METHOD)
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD, call->method);
- else
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, call->fptr);
- s390_brasl (code, s390_r14, 0);
- }
- break;
- case OP_FCALL_REG: {
- call = (MonoCallInst*)ins;
- s390_lr (code, s390_r1, ins->sreg1);
- s390_basr (code, s390_r14, s390_r1);
- if (call->signature->ret->type == MONO_TYPE_R4)
- s390_ldebr (code, s390_f0, s390_f0);
- }
- break;
- case OP_LCALL_REG:
- case OP_VCALL_REG:
- case OP_VCALL2_REG:
- case OP_VOIDCALL_REG:
- case OP_CALL_REG: {
- s390_lr (code, s390_r1, ins->sreg1);
- s390_basr (code, s390_r14, s390_r1);
- }
- break;
- case OP_LCALL_MEMBASE:
- case OP_VCALL_MEMBASE:
- case OP_VCALL2_MEMBASE:
- case OP_VOIDCALL_MEMBASE:
- case OP_FCALL_MEMBASE:
- case OP_CALL_MEMBASE: {
- call = (MonoCallInst*)ins;
- if (s390_is_uimm12(ins->inst_offset))
- s390_l (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
- else {
- if (s390_is_imm16(ins->inst_offset)) {
- s390_lhi (code, s390_r13, ins->inst_offset);
- s390_l (code, s390_r1, s390_r13, ins->inst_basereg, 0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_l (code, s390_r1, s390_r13, ins->inst_basereg, 0);
- }
- }
- s390_basr (code, s390_r14, s390_r1);
- if (ins->opcode == OP_FCALL_MEMBASE && call->signature->ret->type == MONO_TYPE_R4)
- s390_ldebr (code, s390_f0, s390_f0);
- }
- break;
- case OP_LOCALLOC: {
- /*------------------------------------------*/
- /* To allocate space on the stack we have */
- /* to allow room for parameters passed in */
- /* calls, the backchain pointer and round */
- /* it to our stack alignment requirements */
- /*------------------------------------------*/
- int alloca_skip = S390_MINIMAL_STACK_SIZE + cfg->param_area;
- int area_offset = S390_ALIGN(alloca_skip, S390_STACK_ALIGNMENT);
- s390_lr (code, s390_r1, ins->sreg1);
- if (ins->flags & MONO_INST_INIT)
- s390_lr (code, s390_r0, ins->sreg1);
- s390_ahi (code, s390_r1, 14);
- s390_srl (code, s390_r1, 0, 3);
- s390_sll (code, s390_r1, 0, 3);
- if (cfg->method->save_lmf) {
- /*----------------------------------*/
- /* we have to adjust lmf ebp value */
- /*----------------------------------*/
- int lmfOffset = cfg->stack_usage - sizeof(MonoLMF);
-
- s390_lr (code, s390_r13, cfg->frame_reg);
- if (s390_is_uimm16(lmfOffset))
- s390_ahi (code, s390_r13, lmfOffset);
- else {
- s390_basr (code, s390_r14, 0);
- s390_j (code, 4);
- s390_word (code, lmfOffset);
- s390_a (code, s390_r13, 0, s390_r14, 4);
- }
- s390_lr (code, s390_r14, STK_BASE);
- s390_sr (code, s390_r14, s390_r1);
- s390_st (code, s390_r14, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, ebp));
- }
- s390_l (code, s390_r13, 0, STK_BASE, 0);
- s390_sr (code, STK_BASE, s390_r1);
- s390_st (code, s390_r13, 0, STK_BASE, 0);
- s390_la (code, ins->dreg, 0, STK_BASE, area_offset);
- s390_srl (code, ins->dreg, 0, 3);
- s390_sll (code, ins->dreg, 0, 3);
- if (ins->flags & MONO_INST_INIT) {
- s390_lr (code, s390_r1, s390_r0);
- s390_lr (code, s390_r0, ins->dreg);
- s390_lr (code, s390_r14, s390_r12);
- s390_lhi (code, s390_r13, 0);
- s390_mvcle(code, s390_r0, s390_r12, 0, 0);
- s390_jo (code, -2);
- s390_lr (code, s390_r12, s390_r14);
- }
- }
- break;
- case OP_THROW: {
- s390_lr (code, s390_r2, ins->sreg1);
- mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
- (gpointer)"mono_arch_throw_exception");
- s390_brasl (code, s390_r14, 0);
- }
- break;
- case OP_RETHROW: {
- s390_lr (code, s390_r2, ins->sreg1);
- mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
- (gpointer)"mono_arch_rethrow_exception");
- s390_brasl (code, s390_r14, 0);
- }
- break;
- case OP_START_HANDLER: {
- MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
- if (s390_is_uimm12 (spvar->inst_offset)) {
- s390_st (code, s390_r14, 0,
- spvar->inst_basereg,
- spvar->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, spvar->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_st (code, s390_r14, s390_r13,
- spvar->inst_basereg, 0);
- }
- }
- break;
- case OP_ENDFILTER: {
- MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
- if (ins->sreg1 != s390_r2)
- s390_lr (code, s390_r2, ins->sreg1);
- if (s390_is_uimm12 (spvar->inst_offset)) {
- s390_l (code, s390_r14, 0, spvar->inst_basereg,
- spvar->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, spvar->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_l (code, s390_r14, s390_r13,
- spvar->inst_basereg, 0);
- }
- s390_br (code, s390_r14);
- }
- break;
- case OP_ENDFINALLY: {
- MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
- if (s390_is_uimm12 (spvar->inst_offset)) {
- s390_l (code, s390_r14, 0, spvar->inst_basereg,
- spvar->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, spvar->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_l (code, s390_r14, s390_r13,
- spvar->inst_basereg, 0);
- }
- s390_br (code, s390_r14);
- }
- break;
- case OP_CALL_HANDLER: {
- mono_add_patch_info (cfg, code-cfg->native_code,
- MONO_PATCH_INFO_BB, ins->inst_target_bb);
- s390_brasl (code, s390_r14, 0);
- mono_cfg_add_try_hole (cfg, ins->inst_eh_block, code, bb);
- }
- break;
- case OP_LABEL: {
- ins->inst_c0 = code - cfg->native_code;
- }
- break;
- case OP_RELAXED_NOP:
- case OP_NOP:
- case OP_DUMMY_USE:
- case OP_DUMMY_STORE:
- case OP_NOT_REACHED:
- case OP_NOT_NULL: {
- }
- break;
- case OP_BR:
- EMIT_UNCOND_BRANCH(ins);
- break;
- case OP_BR_REG: {
- s390_br (code, ins->sreg1);
- }
- break;
- case OP_CEQ:
- case OP_ICEQ: {
- s390_lhi (code, ins->dreg, 1);
- s390_jz (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_CLT:
- case OP_ICLT: {
- s390_lhi (code, ins->dreg, 1);
- s390_jl (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_CLT_UN:
- case OP_ICLT_UN: {
- s390_lhi (code, ins->dreg, 1);
- s390_jlo (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_CGT:
- case OP_ICGT: {
- s390_lhi (code, ins->dreg, 1);
- s390_jh (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_CGT_UN:
- case OP_ICGT_UN: {
- s390_lhi (code, ins->dreg, 1);
- s390_jho (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_COND_EXC_EQ:
- case OP_COND_EXC_IEQ:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_EQ, ins->inst_p1);
- break;
- case OP_COND_EXC_NE_UN:
- case OP_COND_EXC_INE_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NE, ins->inst_p1);
- break;
- case OP_COND_EXC_LT:
- case OP_COND_EXC_ILT:
- case OP_COND_EXC_LT_UN:
- case OP_COND_EXC_ILT_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LT, ins->inst_p1);
- break;
- case OP_COND_EXC_GT:
- case OP_COND_EXC_IGT:
- case OP_COND_EXC_GT_UN:
- case OP_COND_EXC_IGT_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_GT, ins->inst_p1);
- break;
- case OP_COND_EXC_GE:
- case OP_COND_EXC_IGE:
- case OP_COND_EXC_GE_UN:
- case OP_COND_EXC_IGE_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_GE, ins->inst_p1);
- break;
- case OP_COND_EXC_LE:
- case OP_COND_EXC_ILE:
- case OP_COND_EXC_LE_UN:
- case OP_COND_EXC_ILE_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LE, ins->inst_p1);
- break;
- case OP_COND_EXC_OV:
- case OP_COND_EXC_IOV:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, ins->inst_p1);
- break;
- case OP_COND_EXC_NO:
- case OP_COND_EXC_INO:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NO, ins->inst_p1);
- break;
- case OP_COND_EXC_C:
- case OP_COND_EXC_IC:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, ins->inst_p1);
- break;
- case OP_COND_EXC_NC:
- case OP_COND_EXC_INC:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NC, ins->inst_p1);
- break;
- case OP_IBEQ:
- EMIT_COND_BRANCH (ins, S390_CC_EQ);
- break;
- case OP_IBNE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_NE);
- break;
- case OP_IBLT:
- case OP_IBLT_UN:
- EMIT_COND_BRANCH (ins, S390_CC_LT);
- break;
- case OP_IBGT:
- case OP_IBGT_UN:
- EMIT_COND_BRANCH (ins, S390_CC_GT);
- break;
- case OP_IBGE:
- case OP_IBGE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_GE);
- break;
- case OP_IBLE:
- case OP_IBLE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_LE);
- break;
-
- /* floating point opcodes */
- case OP_R8CONST: {
- if (*((float *) ins->inst_p0) == 0) {
- s390_lzdr (code, ins->dreg);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_p0);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ld (code, ins->dreg, 0, s390_r13, 0);
- }
- }
- break;
- case OP_R4CONST: {
- if (*((float *) ins->inst_p0) == 0) {
- s390_lzdr (code, ins->dreg);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_p0);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ldeb (code, ins->dreg, 0, s390_r13, 0);
- }
- }
- break;
- case OP_STORER8_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_std (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_std (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_LOADR8_MEMBASE: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_ld (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ld (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
- }
- break;
- case OP_STORER4_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_ledbr(code, s390_f15, ins->sreg1);
- s390_ste (code, s390_f15, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ledbr(code, s390_f15, ins->sreg1);
- s390_ste (code, s390_f15, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_LOADR4_MEMBASE: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_ldeb (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ldeb (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
- }
- break;
- case OP_ICONV_TO_R_UN: {
- s390_cdfbr (code, ins->dreg, ins->sreg1);
- s390_ltr (code, ins->sreg1, ins->sreg1);
- s390_jnl (code, 12);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, 0x41f00000);
- s390_word (code, 0);
- s390_adb (code, ins->dreg, 0, s390_r13, 4);
- }
- break;
- case OP_ICONV_TO_R4: {
- s390_cdfbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_ICONV_TO_R8: {
- s390_cdfbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_FCONV_TO_I1:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, TRUE);
- break;
- case OP_FCONV_TO_U1:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, FALSE);
- break;
- case OP_FCONV_TO_I2:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, TRUE);
- break;
- case OP_FCONV_TO_U2:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, FALSE);
- break;
- case OP_FCONV_TO_I4:
- case OP_FCONV_TO_I:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, TRUE);
- break;
- case OP_FCONV_TO_U4:
- case OP_FCONV_TO_U:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
- break;
- case OP_FCONV_TO_I8:
- case OP_FCONV_TO_U8:
- g_assert_not_reached ();
- /* Implemented as helper calls */
- break;
- case OP_LCONV_TO_R_UN:
- g_assert_not_reached ();
- /* Implemented as helper calls */
- break;
- case OP_LCONV_TO_OVF_I:
- case OP_LCONV_TO_OVF_I4_2: {
- /* Valid ints: 0xffffffff:8000000 to 00000000:0x7f000000 */
- short int *o[5];
- s390_ltr (code, ins->sreg1, ins->sreg1);
- s390_jnl (code, 0); CODEPTR(code, o[0]);
- s390_ltr (code, ins->sreg2, ins->sreg2);
- s390_jnl (code, 0); CODEPTR(code, o[1]);
- s390_lhi (code, s390_r13, -1);
- s390_cr (code, ins->sreg2, s390_r13);
- s390_jnz (code, 0); CODEPTR(code, o[2]);
- s390_j (code, 0); CODEPTR(code, o[3]);
- PTRSLOT(code, o[0]);
- s390_ltr (code, ins->sreg2, ins->sreg2);
- s390_jz (code, 0); CODEPTR(code, o[4]);
- PTRSLOT(code, o[1]);
- PTRSLOT(code, o[2]);
- mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_EXC, "OverflowException");
- s390_brasl (code, s390_r14, 0);
- PTRSLOT(code, o[3]);
- PTRSLOT(code, o[4]);
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_SQRT: {
- s390_sqdbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_FADD: {
- CHECK_SRCDST_COM_F;
- s390_adbr (code, ins->dreg, src2);
- }
- break;
- case OP_FSUB: {
- CHECK_SRCDST_NCOM_F;
- s390_sdbr (code, ins->dreg, src2);
- }
- break;
- case OP_FMUL: {
- CHECK_SRCDST_COM_F;
- s390_mdbr (code, ins->dreg, src2);
- }
- break;
- case OP_FDIV: {
- CHECK_SRCDST_NCOM_F;
- s390_ddbr (code, ins->dreg, src2);
- }
- break;
- case OP_FNEG: {
- s390_lcdbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_FREM: {
- CHECK_SRCDST_NCOM_F;
- s390_didbr (code, ins->dreg, src2, 5, s390_f15);
- }
- break;
- case OP_FCOMPARE: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- }
- break;
- case OP_FCEQ: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_je (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FCLT: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_jl (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FCLT_UN: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_jlo (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FCGT: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_jh (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FCGT_UN: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_jho (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FBEQ: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_EQ);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBNE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_NE|S390_CC_OV);
- break;
- case OP_FBLT: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_LT);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBLT_UN:
- EMIT_COND_BRANCH (ins, S390_CC_LT|S390_CC_OV);
- break;
- case OP_FBGT: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_GT);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBGT_UN:
- EMIT_COND_BRANCH (ins, S390_CC_GT|S390_CC_OV);
- break;
- case OP_FBGE: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_GE);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBGE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_GE|S390_CC_OV);
- break;
- case OP_FBLE: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_LE);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBLE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_LE|S390_CC_OV);
- break;
- case OP_CKFINITE: {
- short *o;
- s390_lhi (code, s390_r13, 0x7f);
- s390_tcdb (code, ins->sreg1, 0, s390_r13, 0);
- s390_jz (code, 0); CODEPTR(code, o);
- mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_EXC, "ArithmeticException");
- s390_brasl (code, s390_r14,0);
- PTRSLOT(code, o);
- }
- break;
- case OP_S390_MOVE: {
- if (ins->backend.size > 0) {
- if (ins->backend.size <= 256) {
- s390_mvc (code, ins->backend.size, ins->dreg,
- ins->inst_offset, ins->sreg1, ins->inst_imm);
- } else {
- s390_lr (code, s390_r0, ins->dreg);
- if (s390_is_imm16 (ins->inst_offset)) {
- s390_ahi (code, s390_r0, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_long (code, ins->inst_offset);
- s390_a (code, s390_r0, 0, s390_r13, 4);
- }
- s390_lr (code, s390_r12, ins->sreg1);
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_ahi (code, s390_r12, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_long (code, ins->inst_imm);
- s390_a (code, s390_r12, 0, s390_r13, 4);
- }
- if (s390_is_imm16 (ins->backend.size)) {
- s390x_lhi (code, s390_r1, ins->backend.size);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_long (code, ins->backend.size);
- s390_l (code, s390_r1, 0, s390_r13, 4);
- }
- s390_lr (code, s390_r1, ins->backend.size);
- s390_lr (code, s390_r13, s390_r1);
- s390_mvcle(code, s390_r0, s390_r12, 0, 0);
- s390_jo (code, -2);
- }
- }
- }
- case OP_ATOMIC_ADD_I4: {
- s390_lr (code, s390_r1, ins->sreg2);
- s390_l (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- s390_a (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
- s390_cs (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
- s390_jnz (code, -7);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_ATOMIC_ADD_NEW_I4: {
- s390_lr (code, s390_r1, ins->sreg2);
- s390_l (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- s390_a (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
- s390_cs (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
- s390_jnz (code, -7);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_ATOMIC_EXCHANGE_I4: {
- s390_l (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- s390_cs (code, s390_r0, ins->sreg2, ins->inst_basereg, ins->inst_offset);
- s390_jnz (code, -4);
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_S390_BKCHAIN: {
- s390_lr (code, ins->dreg, ins->sreg1);
- if (s390_is_imm16 (cfg->stack_offset)) {
- s390_ahi (code, ins->dreg, cfg->stack_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, cfg->stack_offset);
- s390_a (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- case OP_MEMORY_BARRIER: {
- }
- break;
- default:
- g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
- g_assert_not_reached ();
- }
-
- if ((cfg->opt & MONO_OPT_BRANCH) && ((code - cfg->native_code - offset) > max_len)) {
- g_warning ("wrong maximal instruction length of instruction %s (expected %d, got %d)",
- mono_inst_name (ins->opcode), max_len, code - cfg->native_code - offset);
- g_assert_not_reached ();
- }
-
- cpos += max_len;
-
- last_ins = ins;
- last_offset = offset;
- }
-
- cfg->code_len = code - cfg->native_code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_register_lowlevel_calls */
-/* */
-/* Function - Register routines to help with --trace operation. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_register_lowlevel_calls (void)
-{
- mono_register_jit_icall (mono_arch_get_lmf_addr, "mono_arch_get_lmf_addr", NULL, TRUE);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_patch_code */
-/* */
-/* Function - Process the patch data created during the */
-/* instruction build process. This resolves jumps, */
-/* calls, variables etc. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_patch_code (MonoMethod *method, MonoDomain *domain,
- guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors)
-{
- MonoJumpInfo *patch_info;
-
- for (patch_info = ji; patch_info; patch_info = patch_info->next) {
- unsigned char *ip = patch_info->ip.i + code;
- gconstpointer target = NULL;
-
- target = mono_resolve_patch_target (method, domain, code,
- patch_info, run_cctors);
-
- switch (patch_info->type) {
- case MONO_PATCH_INFO_IP:
- case MONO_PATCH_INFO_EXC_NAME:
- case MONO_PATCH_INFO_LDSTR:
- case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
- case MONO_PATCH_INFO_LDTOKEN:
- case MONO_PATCH_INFO_EXC:
- continue;
- case MONO_PATCH_INFO_SWITCH:
- /*----------------------------------*/
- /* ip points at the basr r13,0/j +4 */
- /* instruction the vtable value */
- /* follows this (i.e. ip+6) */
- /*----------------------------------*/
- *((gconstpointer *)(ip+6)) = target;
- target = NULL;
- continue;
- case MONO_PATCH_INFO_METHODCONST:
- case MONO_PATCH_INFO_CLASS:
- case MONO_PATCH_INFO_IMAGE:
- case MONO_PATCH_INFO_FIELD:
- case MONO_PATCH_INFO_IID:
- target = S390_RELATIVE(target, ip);
- continue;
- case MONO_PATCH_INFO_R4:
- case MONO_PATCH_INFO_R8:
- case MONO_PATCH_INFO_METHOD_REL:
- g_assert_not_reached ();
- continue;
- default:
- target = S390_RELATIVE(target, ip);
- ip += 2;
- }
- s390_patch (ip, (guint32) target);
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_load_volatile_registers */
-/* */
-/* Function - Create the instruction sequence for loading the */
-/* parameter registers for use with the 'tail' op. */
-/* */
-/* The register loading operations performed here */
-/* are the mirror of the store operations performed */
-/* in mono_arch_emit_prolog and need to be kept in */
-/* synchronization with it. */
-/* */
-/*------------------------------------------------------------------*/
-
-guint8 *
-emit_load_volatile_registers (guint8 * code, MonoCompile *cfg)
-{
- MonoMethod *method = cfg->method;
- MonoMethodSignature *sig;
- MonoInst *inst;
- int pos, i;
- CallInfo *cinfo;
-
- sig = mono_method_signature (method);
- pos = 0;
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- if (cinfo->struct_ret) {
- ArgInfo *ainfo = &cinfo->ret;
- inst = cfg->vret_addr;
- s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
-
- for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
- ArgInfo *ainfo = cinfo->args + i;
- inst = cfg->args [pos];
-
- if (inst->opcode == OP_REGVAR) {
- if (ainfo->regtype == RegTypeGeneral)
- s390_lr (code, ainfo->reg, inst->dreg);
- else if (ainfo->regtype == RegTypeFP) {
- if (inst->dreg != ainfo->reg) {
- if (ainfo->size == 4) {
- s390_ldebr (code, ainfo->reg, inst->dreg);
- } else {
- s390_ldr (code, ainfo->reg, inst->dreg);
- }
- }
- }
- else if (ainfo->regtype == RegTypeBase) {
- } else
- g_assert_not_reached ();
- } else {
- if (ainfo->regtype == RegTypeGeneral) {
- if (!((ainfo->reg >= 2) && (ainfo->reg <= 6)))
- g_assert_not_reached();
- switch (ainfo->size) {
- case 1:
- s390_ic (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 2:
- s390_lh (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 8:
- s390_lm (code, ainfo->reg, ainfo->reg + 1,
- inst->inst_basereg, inst->inst_offset);
- break;
- default:
- s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
- } else if (ainfo->regtype == RegTypeBase) {
- } else if (ainfo->regtype == RegTypeFP) {
- if (ainfo->size == 8)
- s390_ld (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- else if (ainfo->size == 4)
- s390_le (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- else
- g_assert_not_reached ();
- } else if (ainfo->regtype == RegTypeStructByVal) {
- if (ainfo->reg != STK_BASE) {
- switch (ainfo->size) {
- case 1:
- s390_ic (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 2:
- s390_lh (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 4:
- s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 8:
- s390_lm (code, ainfo->reg, ainfo->reg+1, inst->inst_basereg, inst->inst_offset);
- break;
- }
- }
- } else if (ainfo->regtype == RegTypeStructByAddr) {
- if (ainfo->reg != STK_BASE) {
- s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
- } else
- g_assert_not_reached ();
- }
- pos++;
- }
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_prolog */
-/* */
-/* Function - Create the instruction sequence for a function */
-/* prolog. */
-/* */
-/*------------------------------------------------------------------*/
-
-guint8 *
-mono_arch_emit_prolog (MonoCompile *cfg)
-{
- MonoMethod *method = cfg->method;
- MonoBasicBlock *bb;
- MonoMethodSignature *sig;
- MonoInst *inst;
- int alloc_size, pos, max_offset, i;
- guint8 *code;
- CallInfo *cinfo;
- int tracing = 0;
- int lmfOffset; \
-
- if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
- tracing = 1;
-
- cfg->code_size = 1024;
- cfg->native_code = code = g_malloc (cfg->code_size);
-
- s390_stm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
-
- if (cfg->arch.bkchain_reg != -1)
- s390_lr (code, cfg->arch.bkchain_reg, STK_BASE);
-
- if (cfg->flags & MONO_CFG_HAS_ALLOCA) {
- cfg->used_int_regs |= 1 << 11;
- }
-
- alloc_size = cfg->stack_offset;
-
- cfg->stack_usage = alloc_size;
- s390_lr (code, s390_r11, STK_BASE);
- if (s390_is_uimm16 (alloc_size)) {
- s390_ahi (code, STK_BASE, -alloc_size);
- } else {
- int stackSize = alloc_size;
- while (stackSize > 32767) {
- s390_ahi (code, STK_BASE, -32767);
- stackSize -= 32767;
- }
- s390_ahi (code, STK_BASE, -stackSize);
- }
- s390_st (code, s390_r11, 0, STK_BASE, 0);
-
- if (cfg->frame_reg != STK_BASE)
- s390_lr (code, s390_r11, STK_BASE);
-
- /* compute max_offset in order to use short forward jumps
- * we always do it on s390 because the immediate displacement
- * for jumps is too small
- */
- max_offset = 0;
- for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
- MonoInst *ins = bb->code;
- bb->max_offset = max_offset;
-
- if (cfg->prof_options & MONO_PROFILE_COVERAGE)
- max_offset += 6;
-
- MONO_BB_FOR_EACH_INS (bb, ins)
- max_offset += ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
- }
-
- /* load arguments allocated to register from the stack */
- sig = mono_method_signature (method);
- pos = 0;
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- if (cinfo->struct_ret) {
- ArgInfo *ainfo = &cinfo->ret;
- inst = cfg->vret_addr;
- inst->backend.size = ainfo->vtsize;
- s390_st (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
-
- for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
- ArgInfo *ainfo = cinfo->args + i;
- inst = cfg->args [pos];
-
- if (inst->opcode == OP_VTARG_ADDR)
- inst = inst->inst_left;
-
- if (inst->opcode == OP_REGVAR) {
- if (ainfo->regtype == RegTypeGeneral)
- s390_lr (code, inst->dreg, ainfo->reg);
- else if (ainfo->regtype == RegTypeFP) {
- if (inst->dreg != ainfo->reg) {
- if (ainfo->size == 4) {
- s390_ledbr (code, inst->dreg, ainfo->reg);
- } else {
- s390_ldr (code, inst->dreg, ainfo->reg);
- }
- }
- }
- else if (ainfo->regtype == RegTypeBase) {
- s390_lr (code, s390_r13, STK_BASE);
- s390_ahi (code, s390_r13, alloc_size);
- s390_l (code, inst->dreg, 0, s390_r13, ainfo->offset);
- } else
- g_assert_not_reached ();
-
- if (cfg->verbose_level > 2)
- g_print ("Argument %d assigned to register %s\n",
- pos, mono_arch_regname (inst->dreg));
- } else {
- if (ainfo->regtype == RegTypeGeneral) {
- if (!((ainfo->reg >= 2) && (ainfo->reg <= 6)))
- g_assert_not_reached();
- switch (ainfo->size) {
- case 1:
- s390_stc (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 2:
- s390_sth (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 8:
- s390_stm (code, ainfo->reg, ainfo->reg + 1,
- inst->inst_basereg, inst->inst_offset);
- break;
- default:
- s390_st (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
- } else if (ainfo->regtype == RegTypeBase) {
- } else if (ainfo->regtype == RegTypeFP) {
- if (ainfo->size == 8)
- s390_std (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- else if (ainfo->size == 4)
- s390_ste (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- else
- g_assert_not_reached ();
- } else if (ainfo->regtype == RegTypeStructByVal) {
- int doffset = inst->inst_offset;
- int reg;
- if (ainfo->reg != STK_BASE)
- reg = ainfo->reg;
- else {
- reg = s390_r0;
- s390_lr (code, s390_r13, STK_BASE);
- s390_ahi (code, s390_r13, alloc_size);
- }
- switch (ainfo->size) {
- case 1:
- if (ainfo->reg == STK_BASE)
- s390_ic (code, reg, 0, s390_r13, ainfo->offset+3);
- s390_stc (code, reg, 0, inst->inst_basereg, doffset);
- break;
- case 2:
- if (ainfo->reg == STK_BASE)
- s390_lh (code, reg, 0, s390_r13, ainfo->offset+2);
- s390_sth (code, reg, 0, inst->inst_basereg, doffset);
- break;
- case 4:
- if (ainfo->reg == STK_BASE)
- s390_l (code, reg, 0, s390_r13, ainfo->offset);
- s390_st (code, reg, 0, inst->inst_basereg, doffset);
- break;
- case 8:
- if (ainfo->reg == STK_BASE)
- s390_lm (code, s390_r0, s390_r1, s390_r13, ainfo->offset);
- s390_stm (code, reg, reg+1, inst->inst_basereg, doffset);
- break;
- }
- } else if (ainfo->regtype == RegTypeStructByAddr) {
- if (ainfo->reg != STK_BASE)
- s390_st (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- } else
- g_assert_not_reached ();
- }
- pos++;
- }
-
- if (method->save_lmf) {
- /*---------------------------------------------------------------*/
- /* we build the MonoLMF structure on the stack - see mini-s390.h */
- /*---------------------------------------------------------------*/
- lmfOffset = alloc_size - sizeof(MonoLMF);
-
- s390_lr (code, s390_r13, cfg->frame_reg);
- if (s390_is_uimm16(lmfOffset))
- s390_ahi (code, s390_r13, lmfOffset);
- else {
- s390_basr (code, s390_r14, 0);
- s390_j (code, 4);
- s390_word (code, lmfOffset);
- s390_a (code, s390_r13, 0, s390_r14, 4);
- }
-
- /*---------------------------------------------------------------*/
- /* Preserve the parameter registers while we fix up the lmf */
- /*---------------------------------------------------------------*/
- s390_stm (code, s390_r2, s390_r6, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, pregs[0]));
-
- /*---------------------------------------------------------------*/
- /* On return from this call r2 have the address of the &lmf */
- /*---------------------------------------------------------------*/
- mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_INTERNAL_METHOD,
- (gpointer)"mono_get_lmf_addr");
- s390_brasl (code, s390_r14, 0);
-
- /*---------------------------------------------------------------*/
- /* Set lmf.lmf_addr = jit_tls->lmf */
- /*---------------------------------------------------------------*/
- s390_st (code, s390_r2, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, lmf_addr));
-
- /*---------------------------------------------------------------*/
- /* Get current lmf */
- /*---------------------------------------------------------------*/
- s390_l (code, s390_r0, 0, s390_r2, 0);
-
- /*---------------------------------------------------------------*/
- /* Set our lmf as the current lmf */
- /*---------------------------------------------------------------*/
- s390_st (code, s390_r13, 0, s390_r2, 0);
-
- /*---------------------------------------------------------------*/
- /* Have our lmf.previous_lmf point to the last lmf */
- /*---------------------------------------------------------------*/
- s390_st (code, s390_r0, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, previous_lmf));
-
- /*---------------------------------------------------------------*/
- /* save method info */
- /*---------------------------------------------------------------*/
- s390_basr (code, s390_r1, 0);
- s390_j (code, 4);
- s390_word (code, method);
- s390_l (code, s390_r1, 0, s390_r1, 4);
- s390_st (code, s390_r1, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, method));
-
- /*---------------------------------------------------------------*/
- /* save the current IP */
- /*---------------------------------------------------------------*/
- s390_st (code, STK_BASE, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, ebp));
- s390_basr (code, s390_r1, 0);
- s390_la (code, s390_r1, 0, s390_r1, 0);
- s390_st (code, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, eip));
-
- /*---------------------------------------------------------------*/
- /* Save general and floating point registers */
- /*---------------------------------------------------------------*/
- s390_stm (code, s390_r2, s390_r12, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, gregs[2]));
- for (i = 0; i < 16; i++) {
- s390_std (code, i, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, fregs[i]));
- }
-
- /*---------------------------------------------------------------*/
- /* Restore the parameter registers now that we've set up the lmf */
- /*---------------------------------------------------------------*/
- s390_lm (code, s390_r2, s390_r6, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, pregs[0]));
- }
-
- if (tracing)
- code = mono_arch_instrument_prolog(cfg, enter_method, code, TRUE);
-
- cfg->code_len = code - cfg->native_code;
-
- g_assert (cfg->code_len < cfg->code_size);
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_epilog */
-/* */
-/* Function - Emit the instructions for a function epilog. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_epilog (MonoCompile *cfg)
-{
- MonoMethod *method = cfg->method;
- int tracing = 0;
- guint8 *code;
- int max_epilog_size = 96;
-
- if (cfg->method->save_lmf)
- max_epilog_size += 128;
-
- if (mono_jit_trace_calls != NULL)
- max_epilog_size += 128;
-
- if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE)
- max_epilog_size += 128;
-
- while ((cfg->code_len + max_epilog_size) > (cfg->code_size - 16)) {
- cfg->code_size *= 2;
- cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- cfg->stat_code_reallocs++;
- }
-
- code = cfg->native_code + cfg->code_len;
-
- if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) {
- code = mono_arch_instrument_epilog (cfg, leave_method, code, TRUE);
- tracing = 1;
- }
-
- if (method->save_lmf)
- restoreLMF(code, cfg->frame_reg, cfg->stack_usage);
-
- if (cfg->flags & MONO_CFG_HAS_ALLOCA)
- s390_l (code, STK_BASE, 0, STK_BASE, 0);
- else
- code = backUpStackPtr(cfg, code, STK_BASE);
-
- s390_lm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_br (code, s390_r14);
-
- cfg->code_len = code - cfg->native_code;
-
- g_assert (cfg->code_len < cfg->code_size);
-
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_exceptions */
-/* */
-/* Function - Emit the blocks to handle exception conditions. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_exceptions (MonoCompile *cfg)
-{
- MonoJumpInfo *patch_info;
- guint8 *code;
- int nThrows = 0,
- exc_count = 0,
- iExc;
- guint32 code_size;
- MonoClass *exc_classes [MAX_EXC];
- guint8 *exc_throw_start [MAX_EXC];
-
- for (patch_info = cfg->patch_info;
- patch_info;
- patch_info = patch_info->next) {
- if (patch_info->type == MONO_PATCH_INFO_EXC)
- exc_count++;
- }
-
- code_size = exc_count * 26;
-
- while ((cfg->code_len + code_size) > (cfg->code_size - 16)) {
- cfg->code_size *= 2;
- cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- cfg->stat_code_reallocs++;
- }
-
- code = cfg->native_code + cfg->code_len;
-
- /*---------------------------------------------------------------------*/
- /* Add code to raise exceptions */
- /*---------------------------------------------------------------------*/
- for (patch_info = cfg->patch_info; patch_info; patch_info = patch_info->next) {
- switch (patch_info->type) {
- case MONO_PATCH_INFO_EXC: {
- guint8 *ip = patch_info->ip.i + cfg->native_code;
- MonoClass *exc_class;
- guint32 throw_ip;
-
- /*-----------------------------------------------------*/
- /* Patch the branch in epilog to come here */
- /*-----------------------------------------------------*/
- s390_patch (ip + 2, (guint32) (S390_RELATIVE(code,ip)));
-
- exc_class = mono_class_from_name (mono_defaults.corlib,
- "System",
- patch_info->data.name);
- g_assert (exc_class);
- throw_ip = patch_info->ip.i;
-
- for (iExc = 0; iExc < nThrows; ++iExc)
- if (exc_classes [iExc] == exc_class)
- break;
-
- if (iExc < nThrows) {
- s390_jcl (code, S390_CC_UN, (guint32) exc_throw_start [iExc]);
- patch_info->type = MONO_PATCH_INFO_NONE;
- } else {
-
- if (nThrows < MAX_EXC) {
- exc_classes [nThrows] = exc_class;
- exc_throw_start [nThrows] = code;
- }
-
- /*---------------------------------------------*/
- /* Patch the parameter passed to the handler */
- /*---------------------------------------------*/
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, patch_info->data.target);
- /*---------------------------------------------*/
- /* Load return address & parameter register */
- /*---------------------------------------------*/
- s390_larl (code, s390_r14, (gsize)S390_RELATIVE((patch_info->ip.i +
- cfg->native_code + 8), code));
- s390_l (code, s390_r2, 0, s390_r13, 4);
- /*---------------------------------------------*/
- /* Reuse the current patch to set the jump */
- /*---------------------------------------------*/
- patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD;
- patch_info->data.name = "mono_arch_throw_exception_by_name";
- patch_info->ip.i = code - cfg->native_code;
- s390_jcl (code, S390_CC_UN, 0);
- }
- break;
- }
- default:
- /* do nothing */
- break;
- }
- }
-
- cfg->code_len = code - cfg->native_code;
-
- g_assert (cfg->code_len < cfg->code_size);
-
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_finish_init */
-/* */
-/* Function - Setup the JIT's Thread Level Specific Data. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_finish_init (void)
-{
-#if HAVE_KW_THREAD
-# if 0
- __asm__ ("\tear\t%r1,0\n"
- "\tlr\t%0,%3\n"
- "\tsr\t%0,%r1\n"
- "\tlr\t%1,%4\n"
- "\tsr\t%1,%r1\n"
- "\tlr\t%2,%5\n"
- "\tsr\t%2,%r1\n"
- : "=r" (appdomain_tls_offset),
- "=r" (thread_tls_offset),
- "=r" (lmf_tls_offset)
- : "r" (&tls_appdomain),
- "r" (&tls_current_object),
- "r" (&mono_lmf_addr)
- : "1", "cc");
-# endif
-#endif
-
- if (!lmf_addr_key_inited) {
- lmf_addr_key_inited = TRUE;
- pthread_key_create (&lmf_addr_key, NULL);
- }
- pthread_setspecific (lmf_addr_key, &tls->lmf);
-
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_free_jit_tls_data */
-/* */
-/* Function - Free tls data. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
-{
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_inst_for_method */
-/* */
-/*------------------------------------------------------------------*/
-
-MonoInst*
-mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
-{
- return NULL;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_decompose_opts */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins)
-{
- switch (ins->opcode) {
- case OP_ISUB_OVF:
- ins->opcode = OP_S390_ISUB_OVF;
- break;
- case OP_ISUB_OVF_UN:
- ins->opcode = OP_S390_ISUB_OVF_UN;
- break;
- case OP_IADD_OVF:
- ins->opcode = OP_S390_IADD_OVF;
- break;
- case OP_IADD_OVF_UN:
- ins->opcode = OP_S390_IADD_OVF_UN;
- break;
- default:
- break;
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_decompose_long_opts */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *ins)
-{
- // The generic code seems to work for OP_LSUB fine on s390, why is a different
- // implementation needed ? gcc also seems to use the different implementation.
- // FIXME: What about the other OP_L opcodes below ?
-
- switch (ins->opcode) {
- case OP_LADD_OVF:
- case OP_LADD_OVF_UN:
- case OP_LSUB_OVF:
- case OP_LSUB_OVF_UN: {
- int opcode = 0;
-
- switch (ins->opcode) {
- case OP_LADD:
- opcode = OP_S390_LADD;
- break;
- case OP_LADD_OVF:
- opcode = OP_S390_LADD_OVF;
- break;
- case OP_LADD_OVF_UN:
- opcode = OP_S390_LADD_OVF_UN;
- break;
- case OP_LSUB:
- opcode = OP_S390_LSUB;
- break;
- case OP_LSUB_OVF:
- opcode = OP_S390_LSUB_OVF;
- break;
- case OP_LSUB_OVF_UN:
- opcode = OP_S390_LSUB_OVF_UN;
- break;
- default:
- g_assert_not_reached ();
- }
-
- /* These hard regs make ssa crazy */
- cfg->disable_ssa = TRUE;
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, s390_r0, ins->sreg1 + 1);
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, s390_r1, ins->sreg1 + 2);
- MONO_EMIT_NEW_BIALU (cfg, opcode, ins->dreg, ins->sreg2 + 1, ins->sreg2 + 2);
- NULLIFY_INS (ins);
- break;
- }
- case OP_LADD_IMM: {
- int dreg = mono_alloc_dreg (cfg, STACK_I8);
- MONO_EMIT_NEW_I8CONST (cfg, dreg, ins->inst_l);
- MONO_EMIT_NEW_BIALU (cfg, OP_LADD, ins->dreg, ins->sreg1, dreg);
- NULLIFY_INS (ins);
- break;
- }
- case OP_LSUB_IMM: {
- int dreg = mono_alloc_dreg (cfg, STACK_I8);
- MONO_EMIT_NEW_I8CONST (cfg, dreg, ins->inst_l);
- MONO_EMIT_NEW_BIALU (cfg, OP_LSUB, ins->dreg, ins->sreg1, dreg);
- NULLIFY_INS (ins);
- break;
- }
- case OP_LNEG: {
- MONO_EMIT_NEW_BIALU (cfg, OP_S390_LNEG, ins->dreg, ins->sreg1 + 1, ins->sreg1 + 2);
- NULLIFY_INS (ins);
- break;
- }
- case OP_ISUB_OVF:
- ins->opcode = OP_S390_ISUB_OVF;
- break;
- case OP_ISUB_OVF_UN:
- ins->opcode = OP_S390_ISUB_OVF_UN;
- break;
- default:
- break;
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_print_tree */
-/* */
-/* Function - Print platform-specific opcode details. */
-/* */
-/* Returns - 1 - opcode details have been printed */
-/* 0 - opcode details have not been printed */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_print_tree (MonoInst *tree, int arity)
-{
- gboolean done;
-
- switch (tree->opcode) {
- case OP_S390_LOADARG:
- case OP_S390_ARGREG:
- case OP_S390_ARGPTR:
- printf ("[0x%lx(%s)]", tree->inst_offset,
- mono_arch_regname (tree->inst_basereg));
- done = 1;
- break;
- case OP_S390_STKARG:
- printf ("[0x%lx(previous_frame)]",
- tree->inst_offset);
- done = 1;
- break;
- case OP_S390_MOVE:
- printf ("[0x%lx(%d,%s),0x%lx(%s)]",
- tree->inst_offset, tree->backend.size,
- mono_arch_regname(tree->dreg), tree->inst_imm,
- mono_arch_regname(tree->sreg1));
- done = 1;
- break;
- case OP_S390_SETF4RET:
- printf ("[%s,%s]",
- mono_arch_fregname (tree->dreg),
- mono_arch_fregname (tree->sreg1));
- done = 1;
- break;
- case OP_TLS_GET:
- printf ("[0x%lx(0x%lx,%s)]", tree->inst_offset,
- tree->inst_imm,
- mono_arch_regname (tree->sreg1));
- done = 1;
- break;
- case OP_S390_BKCHAIN:
- printf ("[previous_frame(%s)]",
- mono_arch_regname (tree->sreg1));
- done = 1;
- break;
- default:
- done = 0;
- }
- return (done);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_regalloc_cost */
-/* */
-/* Function - Determine the cost, in the number of memory */
-/* references, of the action of allocating the var- */
-/* iable VMV into a register during global register */
-/* allocation. */
-/* */
-/* Returns - Cost */
-/* */
-/*------------------------------------------------------------------*/
-
-guint32
-mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv)
-{
- /* FIXME: */
- return 2;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_domain_intrinsic */
-/* */
-/* Function - */
-/* */
-/* Returns - */
-/* */
-/*------------------------------------------------------------------*/
-
-MonoInst *
-mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
- MonoInst *ins;
-
- if (appdomain_tls_offset == -1)
- return NULL;
-
- MONO_INST_NEW (cfg, ins, OP_TLS_GET);
- ins->inst_offset = appdomain_tls_offset;
- return (ins);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_flush_register_windows */
-/* */
-/* Function - */
-/* */
-/* Returns - */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_flush_register_windows (void)
-{
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_lmf_addr */
-/* */
-/* Function - */
-/* */
-/* Returns - */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_lmf_addr (void)
-{
- return pthread_getspecific (lmf_addr_key);
-}
-
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_patch_offset */
-/* */
-/* Function - Dummy entry point until s390x supports aot. */
-/* */
-/* Returns - Offset for patch. */
-/* */
-/*------------------------------------------------------------------*/
-
-guint32
-mono_arch_get_patch_offset (guint8 *code)
-{
- return 0;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_context_get_int_reg. */
-/* */
-/* Function - Dummy entry point until s390x supports aot. */
-/* */
-/* Returns - Pointer to intreg. */
-/* */
-/*------------------------------------------------------------------*/
-
-mgreg_t
-mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
-{
- /* FIXME: implement */
- g_assert_not_reached ();
- return NULL;
-}
-
-/*========================= End of Function ========================*/
+++ /dev/null
-#ifndef __MONO_MINI_S390_H__
-#define __MONO_MINI_S390_H__
-
-#include <mono/arch/s390/s390-codegen.h>
-#include <signal.h>
-
-#define MONO_ARCH_CPU_SPEC s390_cpu_desc
-
-#define MONO_MAX_IREGS 16
-#define MONO_MAX_FREGS 16
-
-/*-------------------------------------------*/
-/* Parameters used by the register allocator */
-/*-------------------------------------------*/
-
-struct MonoLMF {
- gpointer previous_lmf;
- gpointer lmf_addr;
- MonoMethod *method;
- gulong ebp;
- gulong eip;
- gulong pregs[6];
- gulong gregs[16];
- gdouble fregs[16];
-};
-
-typedef struct ucontext MonoContext;
-
-typedef struct MonoCompileArch {
- int bkchain_reg;
-} MonoCompileArch;
-
-typedef struct
-{
- void *prev;
- void *unused[5];
- void *regs[8];
- void *return_address;
-} MonoS390StackFrame;
-
-typedef struct
-{
- gint32 size;
- gint32 offset;
- gint32 offPrm;
-} MonoS390ArgParm;
-
-#define MONO_ARCH_EMULATE_FCONV_TO_I8 1
-#define MONO_ARCH_EMULATE_LCONV_TO_R8 1
-#define MONO_ARCH_EMULATE_LCONV_TO_R4 1
-#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
-#define MONO_ARCH_EMULATE_LMUL 1
-#define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
-#define MONO_ARCH_NEED_DIV_CHECK 1
-#define MONO_ARCH_HAVE_ATOMIC_ADD 1
-#define MONO_ARCH_HAVE_ATOMIC_EXCHANGE 1
-#define MONO_ARCH_HAVE_DECOMPOSE_OPTS 1
-#define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
-// #define MONO_ARCH_SIGSEGV_ON_ALTSTACK 1
-// #define MONO_ARCH_SIGNAL_STACK_SIZE 65536
-
-#define MONO_ARCH_USE_SIGACTION 1
-
-#define S390_STACK_ALIGNMENT 8
-#define S390_FIRST_ARG_REG s390_r2
-#define S390_LAST_ARG_REG s390_r6
-#define S390_FIRST_FPARG_REG s390_f0
-#define S390_LAST_FPARG_REG s390_f2
-#define S390_PASS_STRUCTS_BY_VALUE 1
-#define S390_SMALL_RET_STRUCT_IN_REG 1
-
-#define S390_NUM_REG_ARGS (S390_LAST_ARG_REG-S390_FIRST_ARG_REG+1)
-#define S390_NUM_REG_FPARGS (S390_LAST_FPARG_REG-S390_FIRST_FPARG_REG)
-
-/*===============================================*/
-/* Definitions used by mini-codegen.c */
-/*===============================================*/
-
-/*-----------------------------------------------------*/
-/* use s390_r2-s390_r6 as parm registers */
-/* s390_r0, s390_r1, s390_r12, s390_r13 used internally*/
-/* s390_r8..s390_r11 are used for global regalloc */
-/* s390_r15 is the stack pointer */
-/*-----------------------------------------------------*/
-#define MONO_ARCH_CALLEE_REGS (0xfc)
-
-#define MONO_ARCH_CALLEE_SAVED_REGS 0xff80
-
-/*----------------------------------------*/
-/* use s390_f1/s390_f3-s390_f15 as temps */
-/*----------------------------------------*/
-
-#define MONO_ARCH_CALLEE_FREGS (0xfffe)
-
-#define MONO_ARCH_CALLEE_SAVED_FREGS 0
-
-#define MONO_ARCH_USE_FPSTACK FALSE
-#define MONO_ARCH_FPSTACK_SIZE 0
-
-#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? s390_r2 : \
- ((desc == 'L') ? s390_r3 : \
- ((desc == 'g') ? s390_f0 : - 1)))
-
-#define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g'))
-
-#define MONO_ARCH_INST_SREG2_MASK(ins) (0)
-
-#define MONO_ARCH_INST_IS_REGPAIR(desc) ((desc == 'l') || (desc == 'L'))
-//#define MONO_ARCH_INST_IS_REGPAIR(desc) (0)
-#define MONO_ARCH_INST_REGPAIR_REG2(desc,hr) ((desc == 'l') ? (hr + 1) : \
- ((desc == 'L') ? s390_r2 : -1))
-
-#define MONO_ARCH_IS_GLOBAL_IREG(reg) 0
-
-#define MONO_ARCH_FRAME_ALIGNMENT 4
-#define MONO_ARCH_CODE_ALIGNMENT 32
-
-#define MONO_ARCH_RETREG1 s390_r2
-
-/*-----------------------------------------------*/
-/* Macros used to generate instructions */
-/*-----------------------------------------------*/
-#define S390_OFFSET(b, t) (guchar *) ((gint32) (b) - (gint32) (t))
-#define S390_RELATIVE(b, t) (guchar *) ((((gint32) (b) - (gint32) (t))) / 2)
-
-#define CODEPTR(c, o) (o) = (short *) ((guint32) c - 2)
-#define PTRSLOT(c, o) *(o) = (short) ((guint32) c - (guint32) (o) + 2)/2
-
-#define S390_CC_EQ 8
-#define S390_ALIGN(v, a) (((a) > 0 ? (((v) + ((a) - 1)) & ~((a) - 1)) : (v)))
-
-#define MONO_CONTEXT_SET_IP(ctx,ip) \
- do { \
- (ctx)->uc_mcontext.gregs[14] = (unsigned long)ip; \
- (ctx)->uc_mcontext.psw.addr = (unsigned long)ip; \
- } while (0);
-
-#define MONO_CONTEXT_SET_SP(ctx,bp) MONO_CONTEXT_SET_BP((ctx),(bp))
-#define MONO_CONTEXT_SET_BP(ctx,bp) \
- do { \
- (ctx)->uc_mcontext.gregs[15] = (unsigned long)bp; \
- (ctx)->uc_stack.ss_sp = (void*)bp; \
- } while (0);
-
-#define MONO_CONTEXT_GET_IP(ctx) context_get_ip ((ctx))
-#define MONO_CONTEXT_GET_BP(ctx) MONO_CONTEXT_GET_SP((ctx))
-#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.gregs[15]))
-
-#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do { \
- MonoS390StackFrame *sframe; \
- __asm__ volatile("lr %0,15" : "=r" (sframe)); \
- MONO_CONTEXT_SET_BP ((ctx), sframe->prev); \
- MONO_CONTEXT_SET_SP ((ctx), sframe->prev); \
- sframe = (MonoS390StackFrame*)sframe->prev; \
- MONO_CONTEXT_SET_IP ((ctx), sframe->return_address); \
- } while (0)
-
-#define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) do { (lmf)->ebp = -1; } while (0)
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - context_get_ip */
-/* */
-/* Function - Extract the current instruction address from the */
-/* context. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline gpointer
-context_get_ip (MonoContext *ctx)
-{
- gpointer ip;
-
- ip = (gpointer) ((gint32) (ctx->uc_mcontext.psw.addr) & 0x7fffffff);
- return ip;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - s390_patch */
-/* */
-/* Function - Patch the code with a given value. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-s390_patch (guchar *code, gint32 target)
-{
- gint32 *offset = (gint32 *) code;
-
- if (target != 00) {
- *offset = target;
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - restoreLMF */
-/* */
-/* Function - Restore the LMF state prior to exiting a method. */
-/* */
-/*------------------------------------------------------------------*/
-
-#define restoreLMF(code, frame_reg, stack_usage) do \
-{ \
- int lmfOffset = 0; \
- \
- s390_lr (code, s390_r13, frame_reg); \
- \
- lmfOffset = stack_usage - sizeof(MonoLMF); \
- \
- /*-------------------------------------------------*/ \
- /* r13 = my lmf */ \
- /*-------------------------------------------------*/ \
- s390_ahi (code, s390_r13, lmfOffset); \
- \
- /*-------------------------------------------------*/ \
- /* r6 = &jit_tls->lmf */ \
- /*-------------------------------------------------*/ \
- s390_l (code, s390_r6, 0, s390_r13, \
- G_STRUCT_OFFSET(MonoLMF, lmf_addr)); \
- \
- /*-------------------------------------------------*/ \
- /* r0 = lmf.previous_lmf */ \
- /*-------------------------------------------------*/ \
- s390_l (code, s390_r0, 0, s390_r13, \
- G_STRUCT_OFFSET(MonoLMF, previous_lmf)); \
- \
- /*-------------------------------------------------*/ \
- /* jit_tls->lmf = previous_lmf */ \
- /*-------------------------------------------------*/ \
- s390_l (code, s390_r13, 0, s390_r6, 0); \
- s390_st (code, s390_r0, 0, s390_r6, 0); \
-} while (0)
-
-/*========================= End of Function ========================*/
-
-#endif /* __MONO_MINI_S390_H__ */
#endif
void
-mono_arch_finish_init (void)
+mono_arch_tls_init (void)
{
+ MonoJitTlsData *jit_tls;
+
if (!lmf_addr_key_inited) {
int res;
}
+ jit_tls = pthread_getspecific (mono_get_jit_tls_key ());
+
#ifdef MONO_SPARC_THR_TLS
- thr_setspecific (lmf_addr_key, &tls->lmf);
+ thr_setspecific (lmf_addr_key, &jit_tls->lmf);
#else
- pthread_setspecific (lmf_addr_key, &tls->lmf);
+ pthread_setspecific (lmf_addr_key, &jit_tls->lmf);
#endif
}
+void
+mono_arch_finish_init (void)
+{
+}
+
void
mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
{
#define MONO_ARCH_HAVE_IMT 1
#define MONO_ARCH_IMT_REG sparc_g1
#define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
+#define MONO_ARCH_HAVE_TLS_INIT 1
+
+void mono_arch_tls_init (void);
#ifdef SPARCV9
#define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-logger-internal.h>
#include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-path.h>
#include <mono/utils/mono-tls.h>
#include <mono/utils/dtrace.h>
return FALSE;
if (assembly->in_gac || assembly->image == mono_defaults.corlib)
return FALSE;
- if (mono_security_get_mode () != MONO_SECURITY_MODE_NONE)
+ if (mono_security_enabled ())
return FALSE;
return mono_assembly_has_skip_verification (assembly);
}
jit_tls->lmf = lmf;
#endif
+#ifdef MONO_ARCH_HAVE_TLS_INIT
+ mono_arch_tls_init ();
+#endif
+
mono_setup_altstack (jit_tls);
return jit_tls;
printf ("Number of try block holes %d\n", num_holes);
}
- if (mono_method_has_declsec (cfg->method_to_register)) {
+ if (mono_security_method_has_declsec (cfg->method_to_register)) {
cas_size = sizeof (MonoMethodCasInfo);
}
gboolean gsharedvt = FALSE;
MonoGenericContainer *class_container, *method_container = NULL;
- if (method->is_generic || method->klass->generic_container) {
+ if (method->is_generic || (method->klass->generic_container && !method->is_inflated)) {
declaring_method = method;
} else {
declaring_method = mono_method_get_declaring_generic_method (method);
case MONO_EXCEPTION_FIELD_ACCESS:
ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "FieldAccessException", cfg->exception_message);
break;
+#ifndef DISABLE_SECURITY
/* this can only be set if the security manager is active */
case MONO_EXCEPTION_SECURITY_LINKDEMAND: {
MonoSecurityManager* secman = mono_security_manager_get_methods ();
ex = (MonoException*)exc;
break;
}
+#endif
case MONO_EXCEPTION_OBJECT_SUPPLIED: {
MonoException *exp = cfg->exception_ptr;
MONO_GC_UNREGISTER_ROOT (cfg->exception_ptr);
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
}
}
mono_domain_unlock (domain);
if (!info) {
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+ if (mono_security_core_clr_enabled ()) {
/*
* This might be redundant since mono_class_vtable () already does this,
* but keep it just in case for moonlight.
if (getenv ("MONO_DEBUG") != NULL)
mini_parse_debug_options ();
-
+
+ mono_code_manager_init ();
+
mono_arch_cpu_init ();
mono_arch_init ();
mono_install_imt_thunk_builder (mono_arch_build_imt_thunk);
}
#endif
+
/*Init arch tls information only after the metadata side is inited to make sure we see dynamic appdomain tls keys*/
mono_arch_finish_init ();
-
/* This must come after mono_init () in the aot-only case */
mono_exceptions_init ();
g_print ("JIT info table lookups: %ld\n", mono_stats.jit_info_table_lookup_count);
g_print ("Hazardous pointers: %ld\n", mono_stats.hazardous_pointer_count);
- if (mono_security_get_mode () == MONO_SECURITY_MODE_CAS) {
+ if (mono_security_cas_enabled ()) {
g_print ("\nDecl security check : %ld\n", mono_jit_stats.cas_declsec_check);
g_print ("LinkDemand (user) : %ld\n", mono_jit_stats.cas_linkdemand);
g_print ("LinkDemand (icall) : %ld\n", mono_jit_stats.cas_linkdemand_icall);
DeleteCriticalSection (&mono_delegate_section);
+ mono_code_manager_cleanup ();
+
#ifdef USE_JUMP_TABLES
mono_jumptable_cleanup ();
#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,
+++ /dev/null
-/*------------------------------------------------------------------*/
-/* */
-/* Name - tramp-s390.c */
-/* */
-/* Function - JIT trampoline code for S/390. */
-/* */
-/* Name - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */
-/* */
-/* Date - January, 2004 */
-/* */
-/* Derivation - From exceptions-x86 & exceptions-ppc */
-/* Paolo Molaro (lupus@ximian.com) */
-/* Dietmar Maurer (dietmar@ximian.com) */
-/* */
-/* Copyright - 2001 Ximian, Inc. */
-/* */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* D e f i n e s */
-/*------------------------------------------------------------------*/
-
-#define GR_SAVE_SIZE 4*sizeof(long)
-#define FP_SAVE_SIZE 16*sizeof(double)
-#define METHOD_SAVE_OFFSET S390_MINIMAL_STACK_SIZE
-#define CREATE_GR_OFFSET METHOD_SAVE_OFFSET+sizeof(gpointer)
-#define CREATE_FP_OFFSET CREATE_GR_OFFSET+GR_SAVE_SIZE
-#define CREATE_LMF_OFFSET CREATE_FP_OFFSET+FP_SAVE_SIZE
-#define CREATE_STACK_SIZE (CREATE_LMF_OFFSET+2*sizeof(long)+sizeof(MonoLMF))
-
-/*------------------------------------------------------------------*/
-/* Specific trampoline code fragment sizes */
-/*------------------------------------------------------------------*/
-#define SPECIFIC_TRAMPOLINE_SIZE 64
-
-/*========================= End of Defines =========================*/
-
-/*------------------------------------------------------------------*/
-/* I n c l u d e s */
-/*------------------------------------------------------------------*/
-
-#include <config.h>
-#include <glib.h>
-#include <string.h>
-
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/marshal.h>
-#include <mono/metadata/tabledefs.h>
-#include <mono/arch/s390/s390-codegen.h>
-
-#include "mini.h"
-#include "mini-s390.h"
-
-/*========================= End of Includes ========================*/
-
-/*------------------------------------------------------------------*/
-/* T y p e d e f s */
-/*------------------------------------------------------------------*/
-
-/*========================= End of Typedefs ========================*/
-
-/*------------------------------------------------------------------*/
-/* P r o t o t y p e s */
-/*------------------------------------------------------------------*/
-
-/*========================= End of Prototypes ======================*/
-
-/*------------------------------------------------------------------*/
-/* G l o b a l V a r i a b l e s */
-/*------------------------------------------------------------------*/
-
-
-/*====================== End of Global Variables ===================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_unbox_trampoline */
-/* */
-/* Function - Return a pointer to a trampoline which does the */
-/* unboxing before calling the method. */
-/* */
-/* When value type methods are called through the */
-/* vtable we need to unbox the 'this' argument. */
-/* */
-/* Parameters - method - Methd pointer */
-/* addr - Pointer to native code for method */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr)
-{
- guint8 *code, *start;
- int this_pos = s390_r2;
- MonoDomain *domain = mono_domain_get ();
-
- start = addr;
- if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret))
- this_pos = s390_r3;
-
- start = code = mono_domain_code_reserve (domain, 28);
-
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, addr);
- s390_l (code, s390_r1, 0, s390_r13, 4);
- s390_ahi (code, this_pos, sizeof(MonoObject));
- s390_br (code, s390_r1);
-
- g_assert ((code - start) <= 28);
-
- mono_arch_flush_icache (start, code - start);
-
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_patch_callsite */
-/* */
-/* Function - Patch a non-virtual callsite so it calls @addr. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
-{
- gint32 displace;
- unsigned short opcode;
-
- opcode = *((unsigned short *) (orig_code - 6));
- /* This should be a 'brasl' instruction */
- g_assert (opcode == 0xc0e5);
- orig_code -= 4;
- displace = ((gint32) addr - (gint32) (orig_code - 2)) / 2;
- s390_patch (orig_code, displace);
- mono_arch_flush_icache (orig_code, 4);
-}
-
-/*========================= End of Function ========================*/
-
-void
-mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
-{
- g_assert_not_reached ();
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_nullify_class_init_trampoline */
-/* */
-/* Function - Nullify a call which calls a class init trampoline */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
-{
- char patch[6] = {0x47, 0x00, 0x00, 0x00, 0x07, 0x00};
-
- code = code - 6;
-
- memcpy(code, patch, sizeof(patch));
-}
-
-/*========================= End of Function ========================*/
-
-void
-mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs)
-{
- g_assert_not_reached ();
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_vcall_slot */
-/* */
-/* Function - This method is called by the arch independent */
-/* trampoline code to determine the vtable slot used by */
-/* the call which invoked the trampoline. */
-/* The calls */
-/* generated by mono for S/390 will look like either:*/
-/* 1. l %r1,xxx(%rx) */
-/* bras %r14,%r1 */
-/* 2. brasl %r14,xxxxxx */
-/* */
-/* Parameters - code - Pointer into caller code */
-/* regs - Register state at the point of the call */
-/* displacement - Out parameter which will receive */
-/* the displacement of the vtable slot */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement)
-{
- int reg;
- guchar* base;
- unsigned short opcode;
- char *sp;
-
- // We are passed sp instead of the register array
- sp = (char*)regs;
-
- *displacement = 0;
-
- opcode = *((unsigned short *) (code - 6));
- switch (opcode) {
- case 0x5810 :
- /* This is a bras r14,r1 instruction */
- code -= 4;
- reg = *code >> 4;
- *displacement = *((short *)code) & 0x0fff;
- if (reg > 5)
- base = *((guchar **) (sp + S390_REG_SAVE_OFFSET+
- sizeof(int)*(reg-6)));
- else
- base = *((guchar **) ((sp - CREATE_STACK_SIZE) +
- CREATE_GR_OFFSET +
- sizeof(int)*(reg-2)));
- return base;
- case 0x581d :
- /* l %r1,OFFSET(%r13,%r7) */
- code -= 4;
- reg = *code >> 4;
- *displacement = *((short *)code) & 0x0fff;
- if (reg > 5)
- base = *((guchar **) (sp + S390_REG_SAVE_OFFSET+
- sizeof(int)*(reg-6)));
- else
- base = *((guchar **) ((sp - CREATE_STACK_SIZE) +
- CREATE_GR_OFFSET +
- sizeof(int)*(reg-2)));
- base += *((guint32*) (sp + S390_REG_SAVE_OFFSET+
- sizeof(int)*(s390_r13-6)));
- return base;
- case 0xc0e5 :
- /* This is the 'brasl' instruction */
- return NULL;
- default :
- g_error("Unable to patch instruction prior to %p",code);
- }
-
- return NULL;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_trampoline_code */
-/* */
-/* Function - Create the designated type of trampoline according*/
-/* to the 'tramp_type' parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-guchar*
-mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot)
-{
- guint8 *buf, *tramp, *code;
- int i, offset, lmfOffset;
-
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- /* Now we'll create in 'buf' the S/390 trampoline code. This
- is the trampoline code common to all methods */
-
- code = buf = mono_global_codeman_reserve (512);
-
- /*-----------------------------------------------------------
- STEP 0: First create a non-standard function prologue with a
- stack size big enough to save our registers.
- -----------------------------------------------------------*/
-
- s390_stm (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_lr (buf, s390_r11, s390_r15);
- s390_ahi (buf, STK_BASE, -CREATE_STACK_SIZE);
- s390_st (buf, s390_r11, 0, STK_BASE, 0);
- s390_st (buf, s390_r1, 0, STK_BASE, METHOD_SAVE_OFFSET);
- s390_stm (buf, s390_r2, s390_r5, STK_BASE, CREATE_GR_OFFSET);
-
- /* Save the FP registers */
- offset = CREATE_FP_OFFSET;
- for (i = s390_f0; i <= s390_f15; ++i) {
- s390_std (buf, i, 0, STK_BASE, offset);
- offset += 8;
- }
-
- /*----------------------------------------------------------
- STEP 1: call 'mono_get_lmf_addr()' to get the address of our
- LMF. We'll need to restore it after the call to
- 's390_magic_trampoline' and before the call to the native
- method.
- ----------------------------------------------------------*/
-
- s390_basr (buf, s390_r13, 0);
- s390_j (buf, 4);
- s390_word (buf, mono_get_lmf_addr);
- s390_l (buf, s390_r1, 0, s390_r13, 4);
- s390_basr (buf, s390_r14, s390_r1);
-
- /*---------------------------------------------------------------*/
- /* we build the MonoLMF structure on the stack - see mini-s390.h */
- /* Keep in sync with the code in mono_arch_emit_prolog */
- /*---------------------------------------------------------------*/
- lmfOffset = CREATE_STACK_SIZE - sizeof(MonoLMF);
-
- s390_lr (buf, s390_r13, STK_BASE);
- s390_ahi (buf, s390_r13, lmfOffset);
-
- /*---------------------------------------------------------------*/
- /* Set lmf.lmf_addr = jit_tls->lmf */
- /*---------------------------------------------------------------*/
- s390_st (buf, s390_r2, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, lmf_addr));
-
- /*---------------------------------------------------------------*/
- /* Get current lmf */
- /*---------------------------------------------------------------*/
- s390_l (buf, s390_r0, 0, s390_r2, 0);
-
- /*---------------------------------------------------------------*/
- /* Set our lmf as the current lmf */
- /*---------------------------------------------------------------*/
- s390_st (buf, s390_r13, 0, s390_r2, 0);
-
- /*---------------------------------------------------------------*/
- /* Have our lmf.previous_lmf point to the last lmf */
- /*---------------------------------------------------------------*/
- s390_st (buf, s390_r0, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, previous_lmf));
-
- /*---------------------------------------------------------------*/
- /* save method info */
- /*---------------------------------------------------------------*/
- s390_l (buf, s390_r1, 0, STK_BASE, METHOD_SAVE_OFFSET);
- s390_st (buf, s390_r1, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, method));
-
- /*---------------------------------------------------------------*/
- /* save the current SP */
- /*---------------------------------------------------------------*/
- s390_l (buf, s390_r1, 0, STK_BASE, 0);
- s390_st (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, ebp));
-
- /*---------------------------------------------------------------*/
- /* save the current IP */
- /*---------------------------------------------------------------*/
- if (tramp_type == MONO_TRAMPOLINE_JUMP) {
- s390_lhi (buf, s390_r1, 0);
- } else {
- s390_l (buf, s390_r1, 0, s390_r1, S390_RET_ADDR_OFFSET);
- s390_la (buf, s390_r1, 0, s390_r1, 0);
- }
- s390_st (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, eip));
-
- /*---------------------------------------------------------------*/
- /* Save general and floating point registers */
- /*---------------------------------------------------------------*/
- s390_stm (buf, s390_r2, s390_r12, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, gregs[2]));
- for (i = 0; i < 16; i++) {
- s390_std (buf, i, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, fregs[i]));
- }
-
- /*---------------------------------------------------------------*/
- /* STEP 2: call the C trampoline function */
- /*---------------------------------------------------------------*/
-
- /* Set arguments */
-
- /* Arg 1: mgreg_t *regs. We pass sp instead */
- s390_lr (buf, s390_r2, STK_BASE);
- s390_ahi (buf, s390_r2, CREATE_STACK_SIZE);
-
- /* Arg 2: code (next address to the instruction that called us) */
- if (tramp_type == MONO_TRAMPOLINE_JUMP) {
- s390_lhi (buf, s390_r3, 0);
- } else {
- s390_l (buf, s390_r3, 0, s390_r11, S390_RET_ADDR_OFFSET);
-
- /* Mask out bit 31 */
- s390_basr (buf, s390_r13, 0);
- s390_j (buf, 4);
- s390_word (buf, (~(1 << 31)));
- s390_n (buf, s390_r3, 0, s390_r13, 4);
- }
-
- /* Arg 3: MonoMethod *method. It was put in r1 by the
- method-specific trampoline code, and then saved before the call
- to mono_get_lmf_addr()'. */
- s390_l (buf, s390_r4, 0, STK_BASE, METHOD_SAVE_OFFSET);
-
- /* Arg 4: trampoline address. Ignore for now */
-
- /* Calculate call address and call the C trampoline. Return value will be in r2 */
- s390_basr (buf, s390_r13, 0);
- s390_j (buf, 4);
- tramp = (guint8*)mono_get_trampoline_func (tramp_type);
- s390_word (buf, tramp);
- s390_l (buf, s390_r1, 0, s390_r13, 4);
- s390_basr (buf, s390_r14, s390_r1);
-
- /* OK, code address is now on r2. Move it to r1, so that we
- can restore r2 and use it from r1 later */
- s390_lr (buf, s390_r1, s390_r2);
-
- /*----------------------------------------------------------
- STEP 3: Restore the LMF
- ----------------------------------------------------------*/
- restoreLMF(buf, STK_BASE, CREATE_STACK_SIZE);
-
- /*----------------------------------------------------------
- STEP 4: call the compiled method
- ----------------------------------------------------------*/
-
- /* Restore registers */
-
- s390_lm (buf, s390_r2, s390_r5, STK_BASE, CREATE_GR_OFFSET);
-
- /* Restore the FP registers */
- offset = CREATE_FP_OFFSET;
- for (i = s390_f0; i <= s390_f15; ++i) {
- s390_ld (buf, i, 0, STK_BASE, offset);
- offset += 8;
- }
-
- /* Restore stack pointer and jump to the code -
- R14 contains the return address to our caller */
- s390_lr (buf, STK_BASE, s390_r11);
- s390_lm (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
-
- if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT || tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT)
- s390_br (buf, s390_r14);
- else
- s390_br (buf, s390_r1);
-
- /* Flush instruction cache, since we've generated code */
- mono_arch_flush_icache (code, buf - code);
-
- /* Sanity check */
- g_assert ((buf - code) <= 512);
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_specific_trampoline */
-/* */
-/* Function - Creates the given kind of specific trampoline */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
-{
- guint8 *code, *buf, *tramp;
- gint32 displace;
-
- tramp = mono_get_trampoline_code (tramp_type);
-
- /*----------------------------------------------------------*/
- /* This is the method-specific part of the trampoline. Its */
- /* purpose is to provide the generic part with the */
- /* MonoMethod *method pointer. We'll use r1 to keep it. */
- /*----------------------------------------------------------*/
- code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);
-
- s390_basr (buf, s390_r1, 0);
- s390_j (buf, 4);
- s390_word (buf, arg1);
- s390_l (buf, s390_r1, 0, s390_r1, 4);
- displace = (tramp - buf) / 2;
- s390_jcl (buf, S390_CC_UN, displace);
-
- /* Flush instruction cache, since we've generated code */
- mono_arch_flush_icache (code, buf - code);
-
- /* Sanity check */
- g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE);
-
- if (code_len)
- *code_len = buf - code;
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-gpointer
-mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot)
-{
- /* FIXME: implement! */
- g_assert_not_reached ();
- return NULL;
-}
#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;
#include <mono/metadata/threads.h>
#include <mono/metadata/profiler.h>
#include <mono/metadata/loader.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
#define LOCATION_INDENT " "
#define BACKTRACE_SIZE 64
{
MonoProfiler *prof = g_new0 (MonoProfiler, 1);
- mono_mutex_init (&mismatched_files_section, NULL);
+ mono_mutex_init (&mismatched_files_section);
prof->mismatched_files_hash = g_hash_table_new (mismatched_files_guint32_hash, mismatched_files_guint32_equal);
prof->saved_strings_hash = g_hash_table_new (NULL, NULL);
prof->string_locations_hash = g_hash_table_new (mismatched_files_guint32_hash, mismatched_files_guint32_equal);
#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 \
$(MCS) -Warn:0 descriptor-tests.cs
descriptor-tests.cs : descriptor-tests-driver.cs descriptor-tests-prefix.cs gen-descriptor-tests.py
- ./gen-descriptor-tests.py >descriptor-tests.cs
+ -cp $^ .
+ $(srcdir)/gen-descriptor-tests.py >descriptor-tests.cs
EXTRA_DIST = descriptor-tests-driver.cs descriptor-tests-prefix.cs gen-descriptor-tests.py
//Console.WriteLine (new IntPtr (val));
return val;
}
+
+ public static bool pack_u2 (ushort us) {
+ return true;
+ }
+
+ public static bool pack_i2 (short value) {
+ int c = 0;
+ // Force 'value' to be register allocated
+ for (int i = 0; i < value; ++i)
+ c += value;
+ return value < 0x80;
+ }
+
+ // #11750
+ public static int test_0_i2_u2 () {
+ typeof (Tests).GetMethod ("pack_u2").Invoke (null, new object [] { (ushort)0 });
+ var res = typeof (Tests).GetMethod ("pack_i2").Invoke (null, new object [] { (short)-1 });
+ return (bool)res ? 0 : 1;
+ }
+
+ public static bool pack_bool (bool b) {
+ return true;
+ }
+
+ public static bool pack_i1 (sbyte value) {
+ int c = 0;
+ // Force 'value' to be register allocated
+ for (int i = 0; i < value; ++i)
+ c += value;
+ return value < -1;
+ }
+
+ public static int test_0_i1_bool () {
+ typeof (Tests).GetMethod ("pack_bool").Invoke (null, new object [] { true });
+ var res = typeof (Tests).GetMethod ("pack_i1").Invoke (null, new object [] { (sbyte)-0x40 });
+ return (bool)res ? 0 : 1;
+ }
}
mono-math.c \
mono-mmap.c \
mono-mmap.h \
+ mono-mutex.c \
+ mono-mutex.h \
mono-networkinterfaces.c \
mono-networkinterfaces.h \
mono-proclib.c \
return ret;
}
-#elif __s390__
+#elif __s390x__
static inline gint32
InterlockedCompareExchange(volatile gint32 *dest,
return(old);
}
-#ifndef __s390x__
-static inline gpointer
-InterlockedCompareExchangePointer(volatile gpointer *dest,
- gpointer exch, gpointer comp)
-{
- gpointer old;
-
- __asm__ __volatile__ ("\tLA\t1,%0\n"
- "\tLR\t%1,%3\n"
- "\tCS\t%1,%2,0(1)\n"
- : "+m" (*dest), "=&r" (old)
- : "r" (exch), "r" (comp)
- : "1", "cc");
- return(old);
-}
-# else
static inline gpointer
InterlockedCompareExchangePointer(volatile gpointer *dest,
gpointer exch,
return(old);
}
-# endif
-# ifndef __s390x__
-static inline gint32
-InterlockedIncrement(volatile gint32 *val)
-{
- gint32 tmp;
-
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tL\t%0,%1\n"
- "\tLR\t1,%0\n"
- "\tAHI\t1,1\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b\n"
- "\tLR\t%0,1"
- : "=r" (tmp), "+m" (*val)
- : : "1", "2", "cc");
-
- return(tmp);
-}
-# else
static inline gint32
InterlockedIncrement(volatile gint32 *val)
{
return(tmp);
}
-# endif
-
-# ifndef __s390x__
-static inline gint32
-InterlockedDecrement(volatile gint32 *val)
-{
- gint32 tmp;
-
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tL\t%0,%1\n"
- "\tLR\t1,%0\n"
- "\tAHI\t1,-1\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b\n"
- "\tLR\t%0,1"
- : "=r" (tmp), "+m" (*val)
- : : "1", "2", "cc");
- return(tmp);
-}
-# else
static inline gint32
InterlockedDecrement(volatile gint32 *val)
{
return(tmp);
}
-# endif
static inline gint32
InterlockedExchange(volatile gint32 *val, gint32 new_val)
return(ret);
}
-# ifndef __s390x__
-static inline gpointer
-InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
-{
- gpointer ret;
-
- __asm__ __volatile__ ("\tLA\t1,%0\n"
- "0:\tL\t%1,%0\n"
- "\tCS\t%1,%2,0(1)\n"
- "\tJNZ\t0b"
- : "+m" (*val), "=&r" (ret)
- : "r" (new_val)
- : "1", "cc");
-
- return(ret);
-}
-# else
static inline gpointer
InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
{
return(ret);
}
-# endif
-# ifndef __s390x__
-static inline gint32
-InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
-{
- gint32 ret;
-
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tL\t%0,%1\n"
- "\tLR\t1,%0\n"
- "\tAR\t1,%2\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b"
- : "=&r" (ret), "+m" (*val)
- : "r" (add)
- : "1", "2", "cc");
-
- return(ret);
-}
-# else
static inline gint32
InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
{
return(ret);
}
-# endif
#elif defined(__mono_ppc__)
#elif defined(__arm__)
+#ifdef __native_client__
+#define MASK_REGISTER(reg, cond) "bic" cond " " reg ", " reg ", #0xc0000000\n"
+#define NACL_ALIGN() ".align 4\n"
+#else
+#define MASK_REGISTER(reg, cond)
+#define NACL_ALIGN()
+#endif
+
/*
* Atomic operations on ARM doesn't contain memory barriers, and the runtime code
* depends on this, so we add them explicitly.
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7S__)
gint32 ret, tmp;
__asm__ __volatile__ ( "1:\n"
+ NACL_ALIGN()
"dmb\n"
"mov %0, #0\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"ldrex %1, [%2]\n"
"teq %1, %3\n"
"it eq\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "eq")
"strexeq %0, %4, [%2]\n"
"teq %0, #0\n"
"bne 1b\n"
gint32 a, b;
__asm__ __volatile__ ( "0:\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"ldr %1, [%2]\n\t"
"cmp %1, %4\n\t"
"mov %0, %1\n\t"
"bne 1f\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"swp %0, %3, [%2]\n\t"
"cmp %0, %1\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "ne")
"swpne %3, %0, [%2]\n\t"
"bne 0b\n\t"
"1:"
__asm__ __volatile__ (
"dmb\n"
"1:\n"
+ NACL_ALIGN()
"mov %0, #0\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"ldrex %1, [%2]\n"
"teq %1, %3\n"
"it eq\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "eq")
"strexeq %0, %4, [%2]\n"
"teq %0, #0\n"
"bne 1b\n"
gpointer a, b;
__asm__ __volatile__ ( "0:\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"ldr %1, [%2]\n\t"
"cmp %1, %4\n\t"
"mov %0, %1\n\t"
"bne 1f\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "eq")
"swpeq %0, %3, [%2]\n\t"
"cmp %0, %1\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "ne")
"swpne %3, %0, [%2]\n\t"
"bne 0b\n\t"
"1:"
__asm__ __volatile__ (
"dmb\n"
"1:\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"ldrex %0, [%2]\n"
"add %0, %0, %3\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"strex %1, %0, [%2]\n"
"teq %1, #0\n"
"bne 1b\n"
gint32 a, b, c;
__asm__ __volatile__ ( "0:\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"ldr %0, [%3]\n\t"
"add %1, %0, %4\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"swp %2, %1, [%3]\n\t"
"cmp %0, %2\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "ne")
"swpne %1, %2, [%3]\n\t"
"bne 0b"
: "=&r" (a), "=&r" (b), "=&r" (c)
__asm__ __volatile__ (
"dmb\n"
"1:\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"ldrex %0, [%2]\n"
"sub %0, %0, %3\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%2", "al")
"strex %1, %0, [%2]\n"
"teq %1, #0\n"
"bne 1b\n"
gint32 a, b, c;
__asm__ __volatile__ ( "0:\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"ldr %0, [%3]\n\t"
"add %1, %0, %4\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"swp %2, %1, [%3]\n\t"
"cmp %0, %2\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "ne")
"swpne %1, %2, [%3]\n\t"
"bne 0b"
: "=&r" (a), "=&r" (b), "=&r" (c)
__asm__ __volatile__ (
"dmb\n"
"1:\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"ldrex %0, [%3]\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"strex %1, %2, [%3]\n"
"teq %1, #0\n"
"bne 1b\n"
#else
gint32 a;
- __asm__ __volatile__ ( "swp %0, %2, [%1]"
+ __asm__ __volatile__ ( NACL_ALIGN()
+ MASK_REGISTER("%1", "al")
+ "swp %0, %2, [%1]"
: "=&r" (a)
: "r" (dest), "r" (exch));
__asm__ __volatile__ (
"dmb\n"
"1:\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"ldrex %0, [%3]\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"strex %1, %2, [%3]\n"
"teq %1, #0\n"
"bne 1b\n"
#else
gpointer a;
- __asm__ __volatile__ ( "swp %0, %2, [%1]"
+ __asm__ __volatile__ ( NACL_ALIGN()
+ MASK_REGISTER("%1", "al")
+ "swp %0, %2, [%1]"
: "=&r" (a)
: "r" (dest), "r" (exch));
__asm__ __volatile__ (
"dmb\n"
"1:\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"ldrex %0, [%3]\n"
"add %1, %0, %4\n"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"strex %2, %1, [%3]\n"
"teq %2, #0\n"
"bne 1b\n"
int a, b, c;
__asm__ __volatile__ ( "0:\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"ldr %0, [%3]\n\t"
"add %1, %0, %4\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "al")
"swp %2, %1, [%3]\n\t"
"cmp %0, %2\n\t"
+ NACL_ALIGN()
+ MASK_REGISTER("%3", "ne")
"swpne %1, %2, [%3]\n\t"
"bne 0b"
: "=&r" (a), "=&r" (b), "=&r" (c)
CodeChunk *current;
CodeChunk *full;
#if defined(__native_client_codegen__) && defined(__native_client__)
- MonoGHashTable *hash;
+ GHashTable *hash;
#endif
};
#endif /* __native_client_codegen && __native_client__ */
+#define VALLOC_FREELIST_SIZE 16
+
+static CRITICAL_SECTION valloc_mutex;
+static GHashTable *valloc_freelists;
+
+static void*
+codechunk_valloc (guint32 size)
+{
+ void *ptr;
+ GSList *freelist;
+
+ if (!valloc_freelists) {
+ InitializeCriticalSection (&valloc_mutex);
+ valloc_freelists = g_hash_table_new (NULL, NULL);
+ }
+
+ /*
+ * Keep a small freelist of memory blocks to decrease pressure on the kernel memory subsystem to avoid #3321.
+ */
+ EnterCriticalSection (&valloc_mutex);
+ freelist = g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
+ if (freelist) {
+ ptr = freelist->data;
+ memset (ptr, 0, size);
+ freelist = g_slist_remove_link (freelist, freelist);
+ g_hash_table_insert (valloc_freelists, GUINT_TO_POINTER (size), freelist);
+ } else {
+ ptr = mono_valloc (NULL, size + MIN_ALIGN - 1, MONO_PROT_RWX | ARCH_MAP_FLAGS);
+ }
+ LeaveCriticalSection (&valloc_mutex);
+ return ptr;
+}
+
+static void
+codechunk_vfree (void *ptr, guint32 size)
+{
+ GSList *freelist;
+
+ EnterCriticalSection (&valloc_mutex);
+ freelist = g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
+ if (!freelist || g_slist_length (freelist) < VALLOC_FREELIST_SIZE) {
+ freelist = g_slist_prepend (freelist, ptr);
+ g_hash_table_insert (valloc_freelists, GUINT_TO_POINTER (size), freelist);
+ } else {
+ mono_vfree (ptr, size);
+ }
+ LeaveCriticalSection (&valloc_mutex);
+}
+
+static void
+codechunk_cleanup (void)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (!valloc_freelists)
+ return;
+ g_hash_table_iter_init (&iter, valloc_freelists);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ GSList *freelist = value;
+ GSList *l;
+
+ for (l = freelist; l; l = l->next) {
+ mono_vfree (l->data, GPOINTER_TO_UINT (key));
+ }
+ g_slist_free (freelist);
+ }
+ g_hash_table_destroy (valloc_freelists);
+}
+
+void
+mono_code_manager_init (void)
+{
+}
+
+void
+mono_code_manager_cleanup (void)
+{
+ codechunk_cleanup ();
+}
+
/**
* mono_code_manager_new:
*
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 *));
mono_profiler_code_chunk_destroy ((gpointer) dead->data);
chunk = chunk->next;
if (dead->flags == CODE_FLAG_MMAP) {
- mono_vfree (dead->data, dead->size);
+ codechunk_vfree (dead->data, dead->size);
/* valgrind_unregister(dead->data); */
} else if (dead->flags == CODE_FLAG_MALLOC) {
dlfree (dead->data);
/* Allocate MIN_ALIGN-1 more than we need so we can still */
/* guarantee MIN_ALIGN alignment for individual allocs */
/* from mono_code_manager_reserve_align. */
- ptr = mono_valloc (NULL, chunk_size + MIN_ALIGN - 1, MONO_PROT_RWX | ARCH_MAP_FLAGS);
+ ptr = codechunk_valloc (chunk_size);
if (!ptr)
return NULL;
}
/* 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
void* mono_code_manager_reserve (MonoCodeManager *cman, int size);
void mono_code_manager_commit (MonoCodeManager *cman, void *data, int size, int newsize);
int mono_code_manager_size (MonoCodeManager *cman, int *used_size);
+void mono_code_manager_init (void);
+void mono_code_manager_cleanup (void);
/* find the extra block allocated to resolve branches close to code */
typedef int (*MonoCodeManagerFunc) (void *data, int csize, int size, void *user_data);
{
#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
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * mono-mutex.h: Portability wrappers around POSIX Mutexes
+ *
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#include "mono-mutex.h"
+
+#ifndef HOST_WIN32
+
+#if defined(__APPLE__)
+#define _DARWIN_C_SOURCE
+// #include <pthread_spis.h>
+#endif
+
+#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+/* Android does not implement pthread_mutex_timedlock(), but does provide an
+ * unusual declaration: http://code.google.com/p/android/issues/detail?id=7807
+ */
+#ifdef PLATFORM_ANDROID
+#define CONST_NEEDED
+#else
+#define CONST_NEEDED const
+#endif
+
+int pthread_mutex_timedlock (pthread_mutex_t *mutex,
+ CONST_NEEDED struct timespec *timeout);
+int
+pthread_mutex_timedlock (pthread_mutex_t *mutex, CONST_NEEDED struct timespec *timeout)
+{
+ struct timeval timenow;
+ struct timespec sleepytime;
+ int retcode;
+
+ /* This is just to avoid a completely busy wait */
+ sleepytime.tv_sec = 0;
+ sleepytime.tv_nsec = 10000000; /* 10ms */
+
+ while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
+ gettimeofday (&timenow, NULL);
+
+ if (timenow.tv_sec >= timeout->tv_sec &&
+ (timenow.tv_usec * 1000) >= timeout->tv_nsec) {
+ return ETIMEDOUT;
+ }
+
+ nanosleep (&sleepytime, NULL);
+ }
+
+ return retcode;
+}
+#endif /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
+
+
+int
+mono_once (mono_once_t *once, void (*once_init) (void))
+{
+ int thr_ret;
+
+ if (!once->complete) {
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&once->mutex);
+ thr_ret = pthread_mutex_lock (&once->mutex);
+ g_assert (thr_ret == 0);
+
+ if (!once->complete) {
+ once_init ();
+ once->complete = TRUE;
+ }
+ thr_ret = pthread_mutex_unlock (&once->mutex);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+ }
+
+ return 0;
+}
+
+#endif
+
+/*
+Returns a recursive mutex that is safe under suspension.
+
+A suspension safe mutex means one that can handle this scenario:
+
+mutex M
+
+thread 1:
+1)lock M
+2)suspend thread 2
+3)unlock M
+4)lock M
+
+thread 2:
+5)lock M
+
+Say (1) happens before (5) and (5) happens before (2).
+This means that thread 2 was suspended by the kernel because
+it's waiting on mutext M.
+
+Thread 1 then proceed to suspend thread 2 and unlock/lock the
+mutex.
+
+If the kernel implements mutexes with FIFO wait lists, this means
+that thread 1 will be blocked waiting for thread 2 acquire the lock.
+Since thread 2 is suspended, we have a deadlock.
+
+A suspend safe mutex is an unfair lock but will schedule any runable
+thread that is waiting for a the lock.
+
+This problem was witnessed on OSX in mono/tests/thread-exit.cs.
+
+*/
+int
+mono_mutex_init_suspend_safe (mono_mutex_t *mutex)
+{
+#if defined(__APPLE__)
+ int res;
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init (&attr);
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+ // pthread_mutexattr_setpolicy_np (&attr, _PTHREAD_MUTEX_POLICY_FIRSTFIT);
+ res = pthread_mutex_init (mutex, &attr);
+ pthread_mutexattr_destroy (&attr);
+
+ return res;
+#else
+ return mono_mutex_init (mutex);
+#endif
+}
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * mono-mutex.h: Portability wrappers around POSIX Mutexes
+ *
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ */
+
+
+#ifndef __MONO_MUTEX_H__
+#define __MONO_MUTEX_H__
+
+#include <glib.h>
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include <time.h>
+
+#ifdef HOST_WIN32
+#include <windows.h>
+#endif
+
+G_BEGIN_DECLS
+
+#ifndef HOST_WIN32
+
+typedef struct {
+ pthread_mutex_t mutex;
+ gboolean complete;
+} mono_once_t;
+
+#define MONO_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, FALSE }
+
+int mono_once (mono_once_t *once, void (*once_init) (void));
+
+typedef pthread_mutex_t mono_mutex_t;
+typedef pthread_cond_t mono_cond_t;
+
+#define mono_mutex_init(mutex) pthread_mutex_init (mutex, NULL)
+#define mono_mutex_lock(mutex) pthread_mutex_lock (mutex)
+#define mono_mutex_trylock(mutex) pthread_mutex_trylock (mutex)
+#define mono_mutex_timedlock(mutex,timeout) pthread_mutex_timedlock (mutex, timeout)
+#define mono_mutex_unlock(mutex) pthread_mutex_unlock (mutex)
+#define mono_mutex_destroy(mutex) pthread_mutex_destroy (mutex)
+
+#define mono_cond_init(cond,attr) pthread_cond_init (cond,attr)
+#define mono_cond_wait(cond,mutex) pthread_cond_wait (cond, mutex)
+#define mono_cond_timedwait(cond,mutex,timeout) pthread_cond_timedwait (cond, mutex, timeout)
+#define mono_cond_signal(cond) pthread_cond_signal (cond)
+#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
+#define mono_cond_destroy(cond)
+
+/* This is a function so it can be passed to pthread_cleanup_push -
+ * that is a macro and giving it a macro as a parameter breaks.
+ */
+G_GNUC_UNUSED
+static inline int mono_mutex_unlock_in_cleanup (mono_mutex_t *mutex)
+{
+ return(mono_mutex_unlock (mutex));
+}
+
+/* Returns zero on success. */
+static inline int
+mono_mutex_init_recursive (mono_mutex_t *mutex)
+{
+ int res;
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init (&attr);
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+ res = pthread_mutex_init (mutex, &attr);
+ pthread_mutexattr_destroy (&attr);
+
+ return res;
+}
+
+#else
+
+typedef CRITICAL_SECTION mono_mutex_t;
+typedef HANDLE mono_cond_t;
+
+#define mono_mutex_init(mutex) (InitializeCriticalSection((mutex)), 0)
+#define mono_mutex_init_recursive(mutex) (InitializeCriticalSection((mutex)), 0)
+#define mono_mutex_lock(mutex) EnterCriticalSection((mutex))
+#define mono_mutex_trylock(mutex) TryEnterCriticalSection((mutex))
+#define mono_mutex_unlock(mutex) LeaveCriticalSection((mutex))
+#define mono_mutex_destroy(mutex) DeleteCriticalSection((mutex))
+
+
+#define mono_cond_init(cond,attr) do{*(cond) = CreateEvent(NULL,FALSE,FALSE,NULL); } while (0)
+#define mono_cond_wait(cond,mutex) WaitForSingleObject(*(cond),INFINITE)
+#define mono_cond_timedwait(cond,mutex,timeout) WaitForSingleObject(*(cond),timeout)
+#define mono_cond_signal(cond) SetEvent(*(cond))
+#define mono_cond_broadcast(cond) (!SetEvent(*(cond)))
+#define mono_cond_destroy(cond) CloseHandle(*(cond))
+
+#endif
+
+int mono_mutex_init_suspend_safe (mono_mutex_t *mutex);
+
+G_END_DECLS
+
+#endif /* __MONO_MUTEX_H__ */
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
mono_threads_core_suspend (MonoThreadInfo *info)
{
kern_return_t ret;
+ gboolean res;
+
g_assert (info);
ret = thread_suspend (info->native_handle);
if (ret != KERN_SUCCESS)
return FALSE;
- return mono_threads_get_runtime_callbacks ()->
+ res = mono_threads_get_runtime_callbacks ()->
thread_state_init_from_handle (&info->suspend_state, mono_thread_info_get_tid (info), info->native_handle);
+ if (!res)
+ thread_resume (info->native_handle);
+ return res;
}
gboolean
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
a runtime suspend won't make it wronly see a thread in a safepoint
when it is in fact not.
*/
-static CRITICAL_SECTION global_suspend_lock;
+static mono_mutex_t global_suspend_lock;
static int thread_info_size;
{
MonoThreadInfo *info = mem;
- DeleteCriticalSection (&info->suspend_lock);
+ mono_mutex_destroy (&info->suspend_lock);
MONO_SEM_DESTROY (&info->resume_semaphore);
MONO_SEM_DESTROY (&info->finish_resume_semaphore);
mono_threads_platform_free (info);
mono_thread_info_set_tid (info, mono_native_thread_id_get ());
info->small_id = small_id;
- InitializeCriticalSection (&info->suspend_lock);
+ mono_mutex_init_suspend_safe (&info->suspend_lock);
MONO_SEM_INIT (&info->resume_semaphore, 0);
MONO_SEM_INIT (&info->finish_resume_semaphore, 0);
res = mono_native_tls_alloc (&small_id_key, NULL);
g_assert (res);
- InitializeCriticalSection (&global_suspend_lock);
+ mono_mutex_init_suspend_safe (&global_suspend_lock);
mono_lls_init (&thread_list, NULL);
mono_thread_smr_init ();
if (!info)
return NULL;
- EnterCriticalSection (&info->suspend_lock);
+ mono_mutex_lock (&info->suspend_lock);
/*thread is on the process of detaching*/
if (mono_thread_info_run_state (info) > STATE_RUNNING) {
if (info->suspend_count) {
++info->suspend_count;
mono_hazard_pointer_clear (hp, 1);
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
return info;
}
if (!mono_threads_core_suspend (info)) {
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
mono_hazard_pointer_clear (hp, 1);
return NULL;
}
++info->suspend_count;
info->thread_state |= STATE_SUSPENDED;
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
mono_hazard_pointer_clear (hp, 1);
return info;
if (!info)
return;
- EnterCriticalSection (&info->suspend_lock);
+ mono_mutex_lock (&info->suspend_lock);
THREADS_DEBUG ("self suspend IN COUNT %d\n", info->suspend_count);
ret = mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->suspend_state, NULL);
g_assert (ret);
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
while (MONO_SEM_WAIT (&info->resume_semaphore) != 0) {
/*if (EINTR != errno) ABORT("sem_wait failed"); */
if (!info)
return FALSE;
- EnterCriticalSection (&info->suspend_lock);
+ mono_mutex_lock (&info->suspend_lock);
THREADS_DEBUG ("resume %x IN COUNT %d\n",tid, info->suspend_count);
if (info->suspend_count <= 0) {
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
mono_hazard_pointer_clear (hp, 1);
return FALSE;
}
if (--info->suspend_count == 0)
result = mono_thread_info_resume_internal (info);
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
mono_hazard_pointer_clear (hp, 1);
return result;
void
mono_thread_info_suspend_lock (void)
{
- EnterCriticalSection (&global_suspend_lock);
+ mono_mutex_lock (&global_suspend_lock);
}
void
mono_thread_info_suspend_unlock (void)
{
- LeaveCriticalSection (&global_suspend_lock);
+ mono_mutex_unlock (&global_suspend_lock);
}
void
#include <mono/utils/mono-semaphore.h>
#include <mono/utils/mono-stack-unwinding.h>
#include <mono/utils/mono-linked-list-set.h>
-
-/* FIXME used for CRITICAL_SECTION replace with mono-mutex */
-#include <mono/io-layer/io-layer.h>
+#include <mono/utils/mono-mutex.h>
#include <glib.h>
int thread_state;
/* suspend machinery, fields protected by the suspend_lock */
- CRITICAL_SECTION suspend_lock;
+ mono_mutex_t suspend_lock;
int suspend_count;
MonoSemType finish_resume_semaphore;
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
-
-<?xml version="1.0" encoding="utf-8"?>\r
+<?xml version="1.0" encoding="utf-8"?>\r
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
<ItemGroup Label="ProjectConfigurations">\r
<ProjectConfiguration Include="Debug_SGen|Win32">\r
<ClCompile Include="..\mono\metadata\sgen-hash-table.c" />\r
<ClCompile Include="..\mono\metadata\sgen-internal.c" />\r
<ClCompile Include="..\mono\metadata\sgen-los.c" />\r
- <ClCompile Include="..\mono\metadata\sgen-major-copying.c" />\r
<ClCompile Include="..\mono\metadata\sgen-marksweep-fixed-par.c" />\r
<ClCompile Include="..\mono\metadata\sgen-marksweep-fixed.c" />\r
<ClCompile Include="..\mono\metadata\sgen-marksweep-par.c" />\r
<ClCompile Include="..\mono\metadata\sgen-os-mach.c" />\r
<ClCompile Include="..\mono\metadata\sgen-os-posix.c" />\r
<ClCompile Include="..\mono\metadata\sgen-os-win32.c" />\r
- <ClCompile Include="..\mono\metadata\sgen-pinned-allocator.c" />\r
<ClCompile Include="..\mono\metadata\sgen-pinning-stats.c" />\r
<ClCompile Include="..\mono\metadata\sgen-pinning.c" />\r
<ClCompile Include="..\mono\metadata\sgen-protocol.c" />\r
<ClCompile Include="..\mono\metadata\sgen-simple-nursery.c" />\r
<ClCompile Include="..\mono\metadata\sgen-split-nursery.c" />\r
- <ClCompile Include="..\mono\metadata\sgen-ssb.c" />\r
<ClCompile Include="..\mono\metadata\sgen-toggleref.c" />\r
<ClCompile Include="..\mono\metadata\sgen-workers.c" />\r
<ClCompile Include="..\mono\metadata\socket-io.c" />\r
<ClInclude Include="..\mono\metadata\sgen-pinning.h" />\r
<ClInclude Include="..\mono\metadata\sgen-protocol.h" />\r
<ClInclude Include="..\mono\metadata\sgen-scan-object.h" />\r
- <ClInclude Include="..\mono\metadata\sgen-ssb.h" />\r
<ClInclude Include="..\mono\metadata\sgen-toggleref.h" />\r
<ClInclude Include="..\mono\metadata\sgen-workers.h" />\r
<ClInclude Include="..\mono\metadata\socket-io.h" />\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<ImportGroup Label="ExtensionTargets">\r
</ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
@$(MAKE) dist2
# This is a separate target because 'update-po' must be executed before.
dist2: stamp-po $(DISTFILES)
+ mkdir -p $(distdir)
dists="$(DISTFILES)"; \
if test "$(PACKAGE)" = "gettext-tools"; then \
dists="$$dists Makevars.template"; \
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" "$@"
} while ((r = getpwuid_r (uid, &_pwbuf, buf, buflen, (struct passwd**) pwbufp)) &&
recheck_range (r));
+ if (r == 0 && !(*pwbufp))
+ /* On solaris, this function returns 0 even if the entry was not found */
+ r = errno = ENOENT;
+
if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
r = errno = ENOMEM;
free (buf);