ACLOCAL_AMFLAGS = -I m4
+AM_CFLAGS = $(WERROR_CFLAGS)
+
MONOTOUCH_SUBDIRS = $(libgc_dir) eglib/src mono
if CROSS_COMPILING
dolt_supported=no
fi
case $host in
-i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \
+i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \
|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*|aarch64*)
pic_options='-fPIC'
;;
tagok=false
for arg in "$[]@"; do
case "$arg" in
- --silent) ;;
+ --silent) ;;
--mode=compile) modeok=true ;;
--tag=CC|--tag=CXX) tagok=true ;;
--quiet) ;;
CPPFLAGS_FOR_EGLIB=$CPPFLAGS
CFLAGS_FOR_EGLIB=$CFLAGS
+# libgc uses some deprecated APIs
+CFLAGS_FOR_LIBGC="$CFLAGS -Wno-deprecated-declarations"
+
#
# These are the flags that need to be stored in the mono.pc file for
# compiling code that will embed Mono
fi
)
+AC_ARG_ENABLE(werror, [ --enable-werror Pass -Werror to the C compiler], werror_flag=$enableval, werror_flag=no)
+if test x$werror_flag = xyes; then
+ WERROR_CFLAGS="-Werror"
+fi
+AC_SUBST([WERROR_CFLAGS])
+
ac_configure_args="$ac_configure_args \"CPPFLAGS_FOR_EGLIB=$EGLIB_CPPFLAGS\" \"CFLAGS_FOR_EGLIB=$CFLAGS_FOR_EGLIB\""
AC_CONFIG_SUBDIRS(eglib)
ACLOCAL_AMFLAGS = -I m4
+AM_CFLAGS = $(WERROR_CFLAGS)
+
if HOST_WIN32
SUBDIRS = m4 src
else
dolt_supported=no
fi
case $host in
-i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \
-|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*)
+i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \
+|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*|aarch64*)
pic_options='-fPIC'
;;
?86-pc-cygwin*|i?86-pc-cygwin*)
fi
)
+AC_ARG_ENABLE(werror, [ --enable-werror Pass -Werror to the C compiler], werror_flag=$enableval, werror_flag=no)
+if test x$werror_flag = xyes; then
+ WERROR_CFLAGS="-Werror"
+fi
+AC_SUBST([WERROR_CFLAGS])
+
AC_SUBST(GPOINTER_TO_INT)
AC_SUBST(GPOINTER_TO_UINT)
AC_SUBST(GINT_TO_POINTER)
noinst_LTLIBRARIES = libeglib.la libeglib-static.la
+AM_CFLAGS = $(WERROR_CFLAGS)
+
win_files = \
eglib-config.hw \
gdate-win32.c gdir-win32.c gfile-win32.c gmisc-win32.c \
garray.c \
gbytearray.c \
gerror.c \
+ vasprintf.h \
ghashtable.c \
giconv.c \
gmem.c \
#include <string.h>
#include <glib.h>
+#include "vasprintf.h"
+
GError *
g_error_new (gpointer domain, gint code, const char *format, ...)
{
G_BEGIN_DECLS
-#ifdef G_OS_WIN32
-/* MSC and Cross-compilatin will use this */
-int vasprintf (char **strp, const char *fmt, va_list ap);
-#endif
-
-
/*
* Basic data types
*/
#include <stdlib.h>
#include <glib.h>
+#include "vasprintf.h"
+
/* The current fatal levels, error is always fatal */
static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR;
#include <ctype.h>
#include <glib.h>
+#include "vasprintf.h"
+
/* This is not a macro, because I dont want to put _GNU_SOURCE in the glib.h header */
gchar *
g_strndup (const gchar *str, gsize n)
static inline list_node *
sweep_up (struct sort_info *si, list_node *list, int upto)
{
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
+ /*
+ * GCC incorrectly thinks we're writing below si->ranks array bounds.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+
int i;
for (i = si->min_rank; i < upto; ++i) {
list = merge_lists (si->ranks [i], list, si->func);
si->ranks [i] = NULL;
}
return list;
+
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
+#pragma GCC diagnostic pop
+#endif
}
/*
static inline void
insert_list (struct sort_info *si, list_node* list, int rank)
{
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
+ /*
+ * GCC incorrectly thinks we're writing below si->ranks array bounds.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+
int i;
if (rank > si->n_ranks) {
si->n_ranks = i + 1;
si->min_rank = i;
si->ranks [i] = list;
+
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
+#pragma GCC diagnostic pop
+#endif
}
#undef stringify2
--- /dev/null
+#ifndef __VASPRINTF_H
+#define __VASPRINTF_H
+
+#include <stdarg.h>
+#include <config.h>
+
+#ifndef HAVE_VASPRINTF
+int vasprintf(char **ret, const char *fmt, va_list ap);
+#endif
+
+#endif /* __VASPRINTF_H */
#ifndef G_OS_WIN32 /* FIXME */
gchar *sympath;
- gint ignored;
+ gint ignored G_GNUC_UNUSED;
#endif
res = g_file_test (NULL, 0);
0 // jlong JNICALL GetDirectBufferCapacity(jobject buf);
};
-JNIEXPORT void** JNICALL ikvm_GetJNIEnvVTable()
+void** ikvm_GetJNIEnvVTable(void);
+
+JNIEXPORT void** JNICALL ikvm_GetJNIEnvVTable(void)
{
return JNIEnv_vtable;
}
+void* JNICALL ikvm_MarshalDelegate(void* p);
+
JNIEXPORT void* JNICALL ikvm_MarshalDelegate(void* p)
{
return p;
typedef jint (JNICALL *PJNI_ONLOAD)(JavaVM* vm, void* reserved);
+jint JNICALL ikvm_CallOnLoad(PJNI_ONLOAD method, JavaVM* vm, void* reserved);
+
JNIEXPORT jint JNICALL ikvm_CallOnLoad(PJNI_ONLOAD method, JavaVM* vm, void* reserved)
{
return method(vm, reserved);
#include <sys/mman.h>
#include "jni.h"
+ void* JNICALL ikvm_LoadLibrary(char* psz);
+
JNIEXPORT void* JNICALL ikvm_LoadLibrary(char* psz)
{
return g_module_open(psz, 0);
}
+ void JNICALL ikvm_FreeLibrary(GModule* handle);
+
JNIEXPORT void JNICALL ikvm_FreeLibrary(GModule* handle)
{
g_module_close(handle);
}
+ void* JNICALL ikvm_GetProcAddress(GModule* handle, char* name, jint argc);
+
JNIEXPORT void* JNICALL ikvm_GetProcAddress(GModule* handle, char* name, jint argc)
{
void *symbol;
return NULL;
}
+ void* JNICALL ikvm_mmap(int fd, jboolean writeable, jboolean copy_on_write, jlong position, jint size);
+
JNIEXPORT void* JNICALL ikvm_mmap(int fd, jboolean writeable, jboolean copy_on_write, jlong position, jint size)
{
return mmap(0, size, writeable ? PROT_WRITE | PROT_READ : PROT_READ, copy_on_write ? MAP_PRIVATE : MAP_SHARED, fd, position);
}
+ int JNICALL ikvm_munmap(void* address, jint size);
+
JNIEXPORT int JNICALL ikvm_munmap(void* address, jint size)
{
return munmap(address, size);
}
+ int JNICALL ikvm_msync(void* address, jint size);
+
JNIEXPORT int JNICALL ikvm_msync(void* address, jint size)
{
#if defined(__native_client__) && defined(USE_NEWLIB)
EXTRA_DIST += alpha_mach_dep.S mips_sgi_mach_dep.s sparc_mach_dep.S
-AM_CFLAGS = @GC_CFLAGS@
+AM_CFLAGS = $(WERROR_CFLAGS) @GC_CFLAGS@
if CPLUSPLUS
extra_checks = test_cpp
dolt_supported=no
fi
case $host in
-i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \
-|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*)
+i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \
+|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*|aarch64*)
pic_options='-fPIC'
;;
?86-pc-cygwin*|i?86-pc-cygwin*)
AC_ARG_ENABLE(quiet-build, [ --enable-quiet-build Enable quiet libgc build (on by default)], enable_quiet_build=$enableval, enable_quiet_build=yes)
AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
+AC_ARG_ENABLE(werror, [ --enable-werror Pass -Werror to the C compiler], werror_flag=$enableval, werror_flag=no)
+if test x$werror_flag = xyes; then
+ WERROR_CFLAGS="-Werror"
+fi
+AC_SUBST([WERROR_CFLAGS])
+
if test "${multilib}" = "yes"; then
multilib_arg="--enable-multilib"
else
/* doing something wrong. */
# ifdef _MSC_VER
# pragma warning(disable:4172)
+# endif
+# if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 408)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wreturn-local-addr"
# endif
return((ptr_t)(&dummy));
+# if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 408)
+# pragma GCC diagnostic pop
+# endif
# ifdef _MSC_VER
# pragma warning(default:4172)
# endif
.IP \[bu] 2
\f[I]heapshot\f[]: perform a heapshot as soon as possible
.RE
+.IP \[bu] 2
+\f[I]counters\f[]: sample counters values every 1 second. This allow
+a really lightweight way to have insight in some of the runtime key
+metrics. Counters displayed in non verbose mode are : Methods from AOT,
+Methods JITted using mono JIT, Methods JITted using LLVM, Total time
+spent JITting (sec), User Time, System Time, Total Time, Working Set,
+Private Bytes, Virtual Bytes, Page Faults and CPU Load Average (1min,
+5min and 15min).
+.RE
.SS Analyzing the profile data
.PP
Currently there is a command line program (\f[I]mprof-report\f[])
.IP \[bu] 2
\f[I]bytes\f[]: the total number of bytes used by objects of the
given type
+.PP
+To change the sort order of counters, use the option:
+.PP
+\f[B]--counters-sort=MODE\f[]
+.PP
+where \f[I]MODE\f[] can be:
+.IP \[bu] 2
+\f[I]time\f[]: sort values by time then category
+.IP \[bu] 2
+\f[I]category\f[]: sort values by category then time
.SS Selecting what data to report
.PP
The profiler by default collects data about many runtime subsystems
\f[I]thread\f[]: thread information
.IP \[bu] 2
\f[I]heapshot\f[]: live heap usage at heap shots
+.IP \[bu] 2
+\f[I]counters\f[]: counters samples
.PP
It is possible to limit some of the data displayed to a timeframe
of the program execution with the option:
{
if (display == IntPtr.Zero) {
throw new ArgumentNullException("Display",
- "Could not open display (X-Server required. Check you DISPLAY environment variable)");
+ "Could not open display (X-Server required. Check your DISPLAY environment variable)");
}
this.display = display;
ErrorHandler = new XErrorHandler(HandleError);
XSetErrorHandler(ErrorHandler);
} else {
- throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
+ throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check your DISPLAY environment variable)");
}
}
#endregion // Internal Methods
ErrorHandler = new XErrorHandler (HandleError);
XSetErrorHandler (ErrorHandler);
} else {
- throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)");
+ throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check your DISPLAY environment variable)");
}
}
#endregion // Internal Methods
// IL_0008: br IL_000d
// IL_000d: ldloc.0
// IL_000e: ret
+ // ... or returns a simple constant:
+ // IL_0000: ldc.i4 1024
+ // IL_0005: conv.i8
+ // IL_0006: ret
if (args != null && args.Length != 0)
- throw new NotSupportedException ();
+ throw new NotSupportedException ();
+
if (method.IsStatic || method.DeclaringType.IsValueType || this_val == null || !(this_val is ObjectMirror))
throw new NotSupportedException ();
var instructions = body.Instructions;
- if (instructions.Count > 16)
+ if (instructions.Count < 1 || instructions.Count > 16)
throw new NotSupportedException ();
- Value[] stack = new Value [16];
+ var stack = new Value [16];
+ var ins = instructions [0];
Value locals_0 = null;
- Value res = null;
-
- int sp = 0;
int ins_count = 0;
- var ins = instructions [0];
+ int sp = 0;
+
while (ins != null) {
if (ins_count > 16)
throw new NotImplementedException ();
- ins_count ++;
+
var next = ins.Next;
+ ins_count++;
var op = ins.OpCode;
if (op == OpCodes.Nop) {
} else if (op == OpCodes.Ldarg_0) {
- if (sp > 0)
+ if (sp != 0)
throw new NotSupportedException ();
+
stack [sp++] = this_val;
} else if (op == OpCodes.Ldfld) {
if (sp != 1)
throw new NotSupportedException ();
- var obj = (ObjectMirror)stack [--sp];
- var field = (FieldInfoMirror)ins.Operand;
+
+ var obj = (ObjectMirror) stack [--sp];
+ var field = (FieldInfoMirror) ins.Operand;
try {
stack [sp++] = obj.GetValue (field);
} catch (ArgumentException) {
throw new NotSupportedException ();
}
+ } else if (op == OpCodes.Ldc_I4_0) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 0);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_1) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 1);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_2) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 2);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_3) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 3);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_4) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 4);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_5) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 5);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_6) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 6);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_7) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 7);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_8) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, 8);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_M1) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, -1);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I4_S) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_I8) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_R4) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Ldc_R8) {
+ if (sp != 0)
+ throw new NotSupportedException ();
+
+ try {
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand);
+ } catch (ArgumentException) {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_I) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_I1) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToSByte (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_U1) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToByte (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_I2) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt16 (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_U2) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt16 (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_I4) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_U4) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt32 (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_I8) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt64 (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_U8) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt64 (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_R4) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToSingle (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
+ } else if (op == OpCodes.Conv_R8) {
+ if (sp != 1)
+ throw new NotSupportedException ();
+
+ try {
+ var primitive = (PrimitiveValue) stack [--sp];
+ stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToDouble (primitive.Value));
+ } catch {
+ throw new NotSupportedException ();
+ }
} else if (op == OpCodes.Stloc_0) {
if (sp != 1)
throw new NotSupportedException ();
+
locals_0 = stack [--sp];
} else if (op == OpCodes.Br) {
- next = (ILInstruction)ins.Operand;
+ next = (ILInstruction) ins.Operand;
} else if (op == OpCodes.Ldloc_0) {
if (sp != 0)
throw new NotSupportedException ();
+
stack [sp++] = locals_0;
} else if (op == OpCodes.Ret) {
- if (sp == 0)
- res = null;
- else
- res = stack [--sp];
- break;
+ if (sp > 0) {
+ var res = stack [--sp];
+
+ var primitive = res as PrimitiveValue;
+ if (method.ReturnType.IsPrimitive && primitive != null) {
+ // cast the primitive value to the return type
+ try {
+ switch (method.ReturnType.CSharpName) {
+ case "double": res = new PrimitiveValue (method.VirtualMachine, Convert.ToDouble (primitive.Value)); break;
+ case "float": res = new PrimitiveValue (method.VirtualMachine, Convert.ToSingle (primitive.Value)); break;
+ case "ulong": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt64 (primitive.Value)); break;
+ case "long": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt64 (primitive.Value)); break;
+ case "uint": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt32 (primitive.Value)); break;
+ case "int": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value)); break;
+ case "ushort": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt16 (primitive.Value)); break;
+ case "short": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt16 (primitive.Value)); break;
+ case "sbyte": res = new PrimitiveValue (method.VirtualMachine, Convert.ToSByte (primitive.Value)); break;
+ case "byte": res = new PrimitiveValue (method.VirtualMachine, Convert.ToByte (primitive.Value)); break;
+ case "char": res = new PrimitiveValue (method.VirtualMachine, Convert.ToChar (primitive.Value)); break;
+ case "bool": res = new PrimitiveValue (method.VirtualMachine, Convert.ToBoolean (primitive.Value)); break;
+ }
+ } catch {
+ throw new NotSupportedException ();
+ }
+ }
+
+ return res;
+ }
+
+ return null;
} else {
throw new NotSupportedException ();
}
+
ins = next;
}
- return res;
+ return null;
}
}
}
public override bool Equals (object obj) {
if (value == obj)
return true;
- if (obj != null && obj is PrimitiveValue)
- return value == (obj as PrimitiveValue).Value;
+
+ var primitive = obj as PrimitiveValue;
+ if (primitive != null)
+ return value == primitive.Value;
+
return base.Equals (obj);
}
namespace Microsoft.Win32.SafeHandles
{
public sealed class SafeMemoryMappedViewHandle : SafeBuffer {
- internal SafeMemoryMappedViewHandle (IntPtr handle, long size) : base (true) {
- this.handle = handle;
+ IntPtr mmap_handle;
+
+ internal SafeMemoryMappedViewHandle (IntPtr mmap_handle, IntPtr base_address, long size) : base (true) {
+ this.mmap_handle = mmap_handle;
+ this.handle = base_address;
Initialize ((ulong)size);
}
protected override bool ReleaseHandle () {
if (this.handle != (IntPtr) (-1))
- return MemoryMapImpl.Unmap (this.handle, ByteLength);
+ return MemoryMapImpl.Unmap (this.mmap_handle);
throw new NotImplementedException ();
}
}
using System.Collections.Generic;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
-
-
-#if !MOBILE
-using Mono.Unix.Native;
-using Mono.Unix;
-#else
using System.Runtime.CompilerServices;
-#endif
+
namespace System.IO.MemoryMappedFiles
{
- internal static partial class MemoryMapImpl {
- static Exception ArgumentCapacity ()
- {
- return new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
- }
-
- static Exception CapacitySmallerThanSize ()
- {
- return new ArgumentOutOfRangeException ("The capacity may not be smaller than the file size.");
- }
- }
-
-
-#if !MOBILE
- partial class MemoryMapImpl {
- //
- // Turns the FileMode into the first half of open(2) flags
- //
- static OpenFlags ToUnixMode (FileMode mode)
- {
- switch (mode){
- case FileMode.CreateNew:
- return OpenFlags.O_CREAT | OpenFlags.O_EXCL;
-
- case FileMode.Create:
- return OpenFlags.O_CREAT | OpenFlags.O_TRUNC;
-
- case FileMode.OpenOrCreate:
- return OpenFlags.O_CREAT;
-
- case FileMode.Truncate:
- return OpenFlags.O_TRUNC;
-
- case FileMode.Append:
- return OpenFlags.O_APPEND;
- default:
- case FileMode.Open:
- return 0;
- }
- }
-
- //
- // Turns the MemoryMappedFileAccess into the second half of open(2) flags
- //
- static OpenFlags ToUnixMode (MemoryMappedFileAccess access)
- {
- switch (access){
- case MemoryMappedFileAccess.CopyOnWrite:
- case MemoryMappedFileAccess.ReadWriteExecute:
- case MemoryMappedFileAccess.ReadWrite:
- return OpenFlags.O_RDWR;
-
- case MemoryMappedFileAccess.Write:
- return OpenFlags.O_WRONLY;
-
- case MemoryMappedFileAccess.ReadExecute:
- case MemoryMappedFileAccess.Read:
- default:
- return OpenFlags.O_RDONLY;
- }
- }
-
- static MmapProts ToUnixProts (MemoryMappedFileAccess access)
- {
- switch (access){
- case MemoryMappedFileAccess.ReadWrite:
- return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
-
- case MemoryMappedFileAccess.Write:
- return MmapProts.PROT_WRITE;
-
- case MemoryMappedFileAccess.CopyOnWrite:
- return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
-
- case MemoryMappedFileAccess.ReadExecute:
- return MmapProts.PROT_EXEC;
-
- case MemoryMappedFileAccess.ReadWriteExecute:
- return MmapProts.PROT_WRITE | MmapProts.PROT_READ | MmapProts.PROT_EXEC;
-
- case MemoryMappedFileAccess.Read:
- default:
- return MmapProts.PROT_READ;
- }
- }
-
- internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
- {
- if (MonoUtil.IsUnix){
- Stat buf;
-
- int result = Syscall.stat (path, out buf);
-
- if (mode == FileMode.Truncate || mode == FileMode.Append || mode == FileMode.Open){
- if (result == -1)
- UnixMarshal.ThrowExceptionForLastError ();
- }
- if (mode == FileMode.CreateNew && result == 0)
- throw new IOException ("The file already exists");
-
- if (result == 0){
- if (capacity == 0) {
- // Special files such as FIFOs, sockets, and devices can
- // have a size of 0. Specifying a capacity for these
- // also makes little sense, so don't do the check if the
- // file is one of these.
- if (buf.st_size == 0 &&
- (buf.st_mode & (FilePermissions.S_IFCHR |
- FilePermissions.S_IFBLK |
- FilePermissions.S_IFIFO |
- FilePermissions.S_IFSOCK)) == 0) {
- throw ArgumentCapacity ();
- }
-
- capacity = buf.st_size;
- } else if (capacity < buf.st_size) {
- throw CapacitySmallerThanSize ();
- }
- } else {
- if (mode == FileMode.CreateNew){
- if (capacity == 0)
- throw ArgumentCapacity ();
- }
- }
-
- int fd = Syscall.open (path, ToUnixMode (mode) | ToUnixMode (access), FilePermissions.DEFFILEMODE);
-
- if (fd == -1)
- UnixMarshal.ThrowExceptionForLastError ();
- return fd;
- }
-
- throw new NotImplementedException ();
- }
-
- internal static void CloseFD (int fd) {
- Syscall.close (fd);
- }
-
- internal static void Flush (int fd) {
- if (MonoUtil.IsUnix)
- Syscall.fsync (fd);
- else
- throw new NotImplementedException ("Not implemented on Windows");
-
- }
-
- static int pagesize;
-
- internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
- {
- if (!MonoUtil.IsUnix)
- throw new NotImplementedException ("Not implemented on windows.");
-
- if (pagesize == 0)
- pagesize = Syscall.getpagesize ();
-
- Stat buf;
- Syscall.fstat (file_handle, out buf);
- long fsize = buf.st_size;
-
- if (size == 0 || size > fsize)
- size = fsize;
-
- // Align offset
- long real_offset = offset & ~(pagesize - 1);
-
- offset_diff = (int)(offset - real_offset);
-
- // FIXME: Need to determine the unix fd for the file, Handle is only
- // equal to it by accident
- //
- // The new API no longer uses FileStream everywhere, but exposes instead
- // the filename (with one exception), we could move this API to use
- // file descriptors instead of the FileStream plus its Handle.
- //
- map_addr = Syscall.mmap (IntPtr.Zero, (ulong) size,
- ToUnixProts (access),
- access == MemoryMappedFileAccess.CopyOnWrite ? MmapFlags.MAP_PRIVATE : MmapFlags.MAP_SHARED,
- file_handle, real_offset);
-
- if (map_addr == (IntPtr)(-1))
- throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
- }
-
- internal static bool Unmap (IntPtr map_addr, ulong map_size)
- {
- if (!MonoUtil.IsUnix)
- return false;
- return Syscall.munmap (map_addr, map_size) == 0;
- }
-
- static void ConfigureUnixFD (IntPtr handle, HandleInheritability h)
- {
- // TODO: Mono.Posix is lacking O_CLOEXEC definitions for fcntl.
- }
-
-
- [DllImport("kernel32", SetLastError = true)]
- static extern bool SetHandleInformation (IntPtr hObject, int dwMask, int dwFlags);
- static void ConfigureWindowsFD (IntPtr handle, HandleInheritability h)
- {
- SetHandleInformation (handle, 1 /* FLAG_INHERIT */, h == HandleInheritability.None ? 0 : 1);
- }
-
- internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
- {
- if (MonoUtil.IsUnix)
- ConfigureUnixFD (handle, inheritability);
- else
- ConfigureWindowsFD (handle, inheritability);
- }
-
- }
-#else
- partial class MemoryMapImpl {
- [DllImport ("libc")]
- static extern int fsync (int fd);
-
- [DllImport ("libc")]
- static extern int close (int fd);
-
- [DllImport ("libc")]
- static extern int fcntl (int fd, int cmd, int arg0);
-
- //XXX check if android off_t is 64bits or not. on iOS / darwin it is.
- [DllImport ("libc")]
- static extern IntPtr mmap (IntPtr addr, IntPtr len, int prot, int flags, int fd, long offset);
-
- [DllImport ("libc")]
- static extern int munmap (IntPtr addr, IntPtr size);
-
- [DllImport ("libc", SetLastError=true)]
- static extern int open (string path, int flags, int access);
-
-#if MONODROID
- [DllImport ("__Internal")]
- static extern int monodroid_getpagesize ();
-
- static int getpagesize ()
- {
- return monodroid_getpagesize ();
- }
-#else
- [DllImport ("libc")]
- static extern int getpagesize ();
-#endif
-
+ internal static class MemoryMapImpl {
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- static extern long mono_filesize_from_path (string str);
+ static extern IntPtr OpenFileInternal (string path, FileMode mode, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, out int error);
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- static extern long mono_filesize_from_fd (int fd);
-
- //Values valid on iOS/OSX and android ndk r6
- const int F_GETFD = 1;
- const int F_SETFD = 2;
- const int FD_CLOEXEC = 1;
- const int DEFFILEMODE = 0x666;
-
- const int O_RDONLY = 0x0;
- const int O_WRONLY = 0x1;
- const int O_RDWR = 0x2;
+ static extern IntPtr OpenHandleInternal (IntPtr handle, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, out int error);
- const int PROT_READ = 0x1;
- const int PROT_WRITE = 0x2;
- const int PROT_EXEC = 0x4;
-
- const int MAP_PRIVATE = 0x2;
- const int MAP_SHARED = 0x1;
-
- const int EINVAL = 22;
-
-#if MONODROID
- const int O_CREAT = 0x040;
- const int O_TRUNC = 0x080;
- const int O_EXCL = 0x200;
-
- const int ENAMETOOLONG = 63;
-#else
- /* MONOTOUCH - usr/include/sys/fcntl.h */
- const int O_CREAT = 0x0200;
- const int O_TRUNC = 0x0400;
- const int O_EXCL = 0x0800;
-
- // usr/include/sys/errno.h
- const int ENAMETOOLONG = 63;
-#endif
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void CloseMapping (IntPtr handle);
- static int ToUnixMode (FileMode mode)
- {
- switch (mode) {
- case FileMode.CreateNew:
- return O_CREAT | O_EXCL;
-
- case FileMode.Create:
- return O_CREAT | O_TRUNC;
-
- case FileMode.OpenOrCreate:
- return O_CREAT;
-
- case FileMode.Truncate:
- return O_TRUNC;
- default:
- case FileMode.Open:
- return 0;
- }
- }
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void Flush (IntPtr file_handle);
- //
- // Turns the MemoryMappedFileAccess into the second half of open(2) flags
- //
- static int ToUnixMode (MemoryMappedFileAccess access)
- {
- switch (access) {
- case MemoryMappedFileAccess.CopyOnWrite:
- case MemoryMappedFileAccess.ReadWriteExecute:
- case MemoryMappedFileAccess.ReadWrite:
- return O_RDWR;
-
- case MemoryMappedFileAccess.Write:
- return O_WRONLY;
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static void ConfigureHandleInheritability (IntPtr handle, HandleInheritability inheritability);
- case MemoryMappedFileAccess.ReadExecute:
- case MemoryMappedFileAccess.Read:
- default:
- return O_RDONLY;
- }
- }
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ internal extern static bool Unmap (IntPtr mmap_handle);
- static int ToUnixProts (MemoryMappedFileAccess access)
- {
- switch (access){
- case MemoryMappedFileAccess.ReadWrite:
- return PROT_WRITE | PROT_READ;
-
- case MemoryMappedFileAccess.Write:
- return PROT_WRITE;
-
- case MemoryMappedFileAccess.CopyOnWrite:
- return PROT_WRITE | PROT_READ;
-
- case MemoryMappedFileAccess.ReadExecute:
- return PROT_EXEC;
-
- case MemoryMappedFileAccess.ReadWriteExecute:
- return PROT_WRITE | PROT_READ | PROT_EXEC;
-
- case MemoryMappedFileAccess.Read:
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ extern static int MapInternal (IntPtr handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr mmap_handle, out IntPtr base_address);
+
+ internal static void Map (IntPtr handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr mmap_handle, out IntPtr base_address)
+ {
+ int error = MapInternal (handle, offset, ref size, access, out mmap_handle, out base_address);
+ if (error != 0)
+ throw CreateException (error, "<none>");
+ }
+
+ static Exception CreateException (int error, string path) {
+ switch (error){
+ case 1:
+ return new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
+ case 2:
+ return new ArgumentOutOfRangeException ("The capacity may not be smaller than the file size.");
+ case 3:
+ return new FileNotFoundException (path);
+ case 4:
+ return new IOException ("The file already exists");
+ case 5:
+ return new PathTooLongException ();
+ case 6:
+ return new IOException ("Could not open file");
+ case 7:
+ return new ArgumentException ("Capacity must be bigger than zero for non-file mappings");
+ case 8:
+ return new ArgumentException ("Invalid FileMode value.");
+ case 9:
+ return new IOException ("Could not map file");
default:
- return PROT_READ;
+ return new IOException ("Failed with unknown error code " + error);
}
}
- static void ThrowErrorFromErrno (int errno)
+ internal static IntPtr OpenFile (string path, FileMode mode, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options)
{
- switch (errno) {
- case EINVAL: throw new ArgumentException ();
- case ENAMETOOLONG: throw new PathTooLongException ();
- default: throw new IOException ("Failed with errno " + errno);
- }
- }
-
- internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
- {
- long file_size = mono_filesize_from_path (path);
-
- Console.WriteLine ("{0} is {1} big", path, file_size);
- if (mode == FileMode.Truncate || mode == FileMode.Append || mode == FileMode.Open){
- if (file_size < 0)
- throw new FileNotFoundException (path);
- if (capacity == 0)
- capacity = file_size;
- if (capacity < file_size)
- throw CapacitySmallerThanSize ();
- } else {
- if (mode == FileMode.CreateNew){
- if (file_size >= 0)
- throw new IOException ("The file already exists");
- if (capacity == 0)
- throw ArgumentCapacity ();
- }
- }
-
- int fd = open (path, ToUnixMode (mode) | ToUnixMode (access), DEFFILEMODE);
-
- if (fd == -1)
- ThrowErrorFromErrno (Marshal.GetLastWin32Error ());
- return fd;
- }
-
- internal static void CloseFD (int fd)
- {
- close (fd);
- }
-
- internal static void Flush (int fd)
- {
- fsync (fd);
- }
-
- internal static bool Unmap (IntPtr map_addr, ulong map_size)
- {
- return munmap (map_addr, (IntPtr)map_size) == 0;
- }
-
- static int pagesize;
-
- internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
- {
- if (pagesize == 0)
- pagesize = getpagesize ();
-
- long fsize = mono_filesize_from_fd (file_handle);
- if (fsize < 0)
- throw new FileNotFoundException ();
-
- if (size == 0 || size > fsize)
- size = fsize;
-
- // Align offset
- long real_offset = offset & ~(pagesize - 1);
-
- offset_diff = (int)(offset - real_offset);
-
- map_addr = mmap (IntPtr.Zero, (IntPtr) size,
- ToUnixProts (access),
- access == MemoryMappedFileAccess.CopyOnWrite ? MAP_PRIVATE : MAP_SHARED,
- file_handle, real_offset);
-
- if (map_addr == (IntPtr)(-1))
- throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
+ int error = 0;
+ IntPtr res = OpenFileInternal (path, mode, mapName, out capacity, access, options, out error);
+ if (error != 0)
+ throw CreateException (error, path);
+ return res;
}
- internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
+ internal static IntPtr OpenHandle (IntPtr handle, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options)
{
- int fd = (int)handle;
- int flags = fcntl (fd, F_GETFD, 0);
- if (inheritability == HandleInheritability.None)
- flags &= ~FD_CLOEXEC;
- else
- flags |= FD_CLOEXEC;
- fcntl (fd, F_SETFD, flags);
+ int error = 0;
+ IntPtr res = OpenHandleInternal (handle, mapName, out capacity, access, options, out error);
+ if (error != 0)
+ throw CreateException (error, "<none>");
+ return res;
}
-
}
-#endif
+
public class MemoryMappedFile : IDisposable {
MemoryMappedFileAccess fileAccess;
//
FileStream stream;
bool keepOpen;
- int unix_fd;
+ IntPtr handle;
public static MemoryMappedFile CreateFromFile (string path)
{
public static MemoryMappedFile CreateFromFile (string path, FileMode mode)
{
- return CreateFromFile (path, mode, null, 0, MemoryMappedFileAccess.ReadWrite);
+ long capacity = 0;
+ if (path == null)
+ throw new ArgumentNullException ("path");
+ if (path.Length == 0)
+ throw new ArgumentException ("path");
+ if (mode == FileMode.Append)
+ throw new ArgumentException ("mode");
+
+ IntPtr handle = MemoryMapImpl.OpenFile (path, mode, null, out capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages);
+
+ return new MemoryMappedFile () {
+ handle = handle,
+ fileAccess = MemoryMappedFileAccess.ReadWrite,
+ fileCapacity = capacity
+ };
}
public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName)
if (capacity < 0)
throw new ArgumentOutOfRangeException ("capacity");
- int fd = MemoryMapImpl.Open (path, mode, ref capacity, access);
+ IntPtr handle = MemoryMapImpl.OpenFile (path, mode, mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages);
return new MemoryMappedFile () {
- unix_fd = fd,
+ handle = handle,
fileAccess = access,
name = mapName,
fileCapacity = capacity
};
}
-#if MOBILE
- public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
- HandleInheritability inheritability,
- bool leaveOpen)
-#else
+
[MonoLimitation ("memoryMappedFileSecurity is currently ignored")]
public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability,
bool leaveOpen)
-#endif
{
if (fileStream == null)
throw new ArgumentNullException ("fileStream");
if ((!MonoUtil.IsUnix && capacity == 0 && fileStream.Length == 0) || (capacity > fileStream.Length))
throw new ArgumentException ("capacity");
- MemoryMapImpl.ConfigureFD (fileStream.Handle, inheritability);
+ IntPtr handle = MemoryMapImpl.OpenHandle (fileStream.Handle, mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages);
+
+ MemoryMapImpl.ConfigureHandleInheritability (handle, inheritability);
return new MemoryMappedFile () {
- stream = fileStream,
+ handle = handle,
fileAccess = access,
name = mapName,
fileCapacity = capacity,
+
+ stream = fileStream,
keepOpen = leaveOpen
};
}
- [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
+
+ static MemoryMappedFile CoreShmCreate (string mapName, long capacity, MemoryMappedFileAccess access,
+ MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity,
+ HandleInheritability inheritability, FileMode mode)
+ {
+ if (mapName != null && mapName.Length == 0)
+ throw new ArgumentException ("mapName");
+ if (capacity < 0)
+ throw new ArgumentOutOfRangeException ("capacity");
+
+ IntPtr handle = MemoryMapImpl.OpenFile (null, mode, mapName, out capacity, access, options);
+
+ return new MemoryMappedFile () {
+ handle = handle,
+ fileAccess = access,
+ name = mapName,
+ fileCapacity = capacity
+ };
+ }
+
+ [MonoLimitation ("Named mappings scope is process local")]
public static MemoryMappedFile CreateNew (string mapName, long capacity)
{
-#if MOBILE
- return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, 0);
-#else
- return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
-#endif
+ return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
}
- [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
+ [MonoLimitation ("Named mappings scope is process local")]
public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access)
{
-#if MOBILE
- return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, 0);
-#else
- return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
-#endif
+ return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
}
-#if MOBILE
- public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
- MemoryMappedFileOptions options,
- HandleInheritability handleInheritability)
-#else
- [MonoLimitation ("CreateNew requires that mapName be a file name on Unix; options and memoryMappedFileSecurity are ignored")]
+ [MonoLimitation ("Named mappings scope is process local; options and memoryMappedFileSecurity are ignored")]
public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity,
HandleInheritability inheritability)
-#endif
{
- return CreateFromFile (mapName, FileMode.CreateNew, mapName, capacity, access);
+ return CoreShmCreate (mapName, capacity, access, options, memoryMappedFileSecurity, inheritability, FileMode.CreateNew);
}
- [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
+ [MonoLimitation ("Named mappings scope is process local")]
public static MemoryMappedFile CreateOrOpen (string mapName, long capacity)
{
return CreateOrOpen (mapName, capacity, MemoryMappedFileAccess.ReadWrite);
}
- [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
+ [MonoLimitation ("Named mappings scope is process local")]
public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access)
{
- return CreateFromFile (mapName, FileMode.OpenOrCreate, mapName, capacity, access);
+ return CreateOrOpen (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
}
- [MonoTODO]
-#if MOBILE
- public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, HandleInheritability inheritability)
-#else
+ [MonoLimitation ("Named mappings scope is process local")]
public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability)
-#endif
{
- throw new NotImplementedException ();
+ return CoreShmCreate (mapName, capacity, access, options, memoryMappedFileSecurity, inheritability, FileMode.OpenOrCreate);
}
- [MonoTODO]
+ [MonoLimitation ("Named mappings scope is process local")]
public static MemoryMappedFile OpenExisting (string mapName)
{
throw new NotImplementedException ();
}
- [MonoTODO]
+ [MonoLimitation ("Named mappings scope is process local")]
public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights)
{
throw new NotImplementedException ();
}
- [MonoTODO]
+ [MonoLimitation ("Named mappings scope is process local")]
public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability)
{
throw new NotImplementedException ();
public MemoryMappedViewStream CreateViewStream ()
{
- return CreateViewStream (0, 0);
+ return CreateViewStream (0, 0);//FIXME this is wrong
}
public MemoryMappedViewStream CreateViewStream (long offset, long size)
public MemoryMappedViewStream CreateViewStream (long offset, long size, MemoryMappedFileAccess access)
{
- return new MemoryMappedViewStream (stream != null ? (int)stream.Handle : unix_fd, offset, size, access);
+ return new MemoryMappedViewStream (handle, offset, size, access);
}
public MemoryMappedViewAccessor CreateViewAccessor ()
public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size, MemoryMappedFileAccess access)
{
- int file_handle = stream != null ? (int) stream.Handle : unix_fd;
-
- return new MemoryMappedViewAccessor (file_handle, offset, size, access);
+ return new MemoryMappedViewAccessor (handle, offset, size, access);
}
MemoryMappedFile ()
if (stream != null){
if (keepOpen == false)
stream.Close ();
- unix_fd = -1;
stream = null;
}
- if (unix_fd != -1) {
- MemoryMapImpl.CloseFD (unix_fd);
- unix_fd = -1;
+ if (handle != IntPtr.Zero) {
+ MemoryMapImpl.CloseMapping (handle);
+ handle = IntPtr.Zero;
}
}
}
-#if !MOBILE
[MonoTODO]
public MemoryMappedFileSecurity GetAccessControl ()
{
{
throw new NotImplementedException ();
}
-#endif
[MonoTODO]
public SafeMemoryMappedFileHandle SafeMemoryMappedFileHandle {
namespace System.IO.MemoryMappedFiles
{
public sealed class MemoryMappedViewAccessor : UnmanagedMemoryAccessor, IDisposable {
- int file_handle;
- IntPtr mmap_addr;
- SafeMemoryMappedViewHandle handle;
+ IntPtr mmap_handle;
+ SafeMemoryMappedViewHandle safe_handle;
- internal MemoryMappedViewAccessor (int file_handle, long offset, long size, MemoryMappedFileAccess access)
+ internal MemoryMappedViewAccessor (IntPtr handle, long offset, long size, MemoryMappedFileAccess access)
{
- this.file_handle = file_handle;
- Create (offset, size, access);
+ Create (handle, offset, size, access);
}
static FileAccess ToFileAccess (MemoryMappedFileAccess access)
}
}
- unsafe void Create (long offset, long size, MemoryMappedFileAccess access)
+ unsafe void Create (IntPtr handle, long offset, long size, MemoryMappedFileAccess access)
{
- int offset_diff;
+ IntPtr base_address;
- MemoryMapImpl.Map (file_handle, offset, ref size, access, out mmap_addr, out offset_diff);
+ MemoryMapImpl.Map (handle, offset, ref size, access, out mmap_handle, out base_address);
+ safe_handle = new SafeMemoryMappedViewHandle (mmap_handle, base_address, size);
- handle = new SafeMemoryMappedViewHandle ((IntPtr)((long)mmap_addr + offset_diff), size);
- Initialize (handle, 0, size, ToFileAccess (access));
+ Initialize (safe_handle, 0, size, ToFileAccess (access));
}
public SafeMemoryMappedViewHandle SafeMemoryMappedViewHandle {
get {
- return handle;
+ return safe_handle;
}
}
public void Flush ()
{
- MemoryMapImpl.Flush (file_handle);
+ MemoryMapImpl.Flush (mmap_handle);
}
}
}
namespace System.IO.MemoryMappedFiles
{
public sealed class MemoryMappedViewStream : UnmanagedMemoryStream {
- IntPtr mmap_addr;
- ulong mmap_size;
+ IntPtr mmap_handle;
object monitor;
- int fd;
- internal MemoryMappedViewStream (int fd, long offset, long size, MemoryMappedFileAccess access) {
- this.fd = fd;
+ internal MemoryMappedViewStream (IntPtr handle, long offset, long size, MemoryMappedFileAccess access) {
monitor = new Object ();
- CreateStream (fd, offset, size, access);
+ CreateStream (handle, offset, size, access);
}
public SafeMemoryMappedViewHandle SafeMemoryMappedViewHandle {
}
}
- unsafe void CreateStream (int fd, long offset, long size, MemoryMappedFileAccess access)
+ unsafe void CreateStream (IntPtr handle, long offset, long size, MemoryMappedFileAccess access)
{
- int offset_diff;
- mmap_size = (ulong) size;
- MemoryMapImpl.Map (fd, offset, ref size, access, out mmap_addr, out offset_diff);
- FileAccess faccess;
+ IntPtr base_address;
+
+ MemoryMapImpl.Map (handle, offset, ref size, access, out mmap_handle, out base_address);
+ FileAccess faccess;
switch (access) {
case MemoryMappedFileAccess.ReadWrite:
faccess = FileAccess.ReadWrite;
default:
throw new NotImplementedException ("access mode " + access + " not supported.");
}
- Initialize ((byte*)mmap_addr + offset_diff, size, size, faccess);
+ Initialize ((byte*)base_address, size, size, faccess);
}
protected override void Dispose (bool disposing)
{
base.Dispose (disposing);
lock (monitor) {
- if (mmap_addr != (IntPtr)(-1)) {
- MemoryMapImpl.Unmap (mmap_addr, mmap_size);
- mmap_addr = (IntPtr)(-1);
+ if (mmap_handle != (IntPtr)(-1)) {
+ MemoryMapImpl.Unmap (mmap_handle);
+ mmap_handle = (IntPtr)(-1);
}
}
}
public override void Flush ()
{
- MemoryMapImpl.Flush (fd);
+ MemoryMapImpl.Flush (mmap_handle);
}
}
}
Assert.IsTrue (thrown);
}
+ static int named_index;
+ static String MkNamedMapping ()
+ {
+ return "test-" + named_index++;
+ }
+
+
static string tempDir = Path.Combine (Path.GetTempPath (), typeof (MemoryMappedFileTest).FullName);
string fname;
Assert.AreEqual ("Hello", s);
}
}
+
+
+ [Test]
+ public void NamedMappingToInvalidFile ()
+ {
+ var fileName = Path.Combine (tempDir, "temp_file_123");
+ if (File.Exists (fileName))
+ File.Delete (fileName);
+ var memoryMappedFile90 = MemoryMappedFile.CreateNew (fileName, 4194304, MemoryMappedFileAccess.ReadWrite);
+ memoryMappedFile90.CreateViewStream (4186112, 3222, MemoryMappedFileAccess.Write);
+ }
+
+ [Test]
+ public void CreateTheSameAreaTwiceShouldFail ()
+ {
+ var name = MkNamedMapping ();
+ using (var m0 = MemoryMappedFile.CreateNew(name, 4096, MemoryMappedFileAccess.ReadWrite)) {
+ try {
+ using (var m1 = MemoryMappedFile.CreateNew (name, 4096, MemoryMappedFileAccess.ReadWrite)) {
+ Assert.Fail ("Must fail");
+ }
+ } catch (IOException) {}
+ }
+ }
+
+ [Test]
+ public void MapAFileToAMemoryAreaShouldFail ()
+ {
+ var name = MkNamedMapping ();
+ using (var m0 = MemoryMappedFile.CreateNew(name, 4096, MemoryMappedFileAccess.ReadWrite)) {
+ try {
+ using (var m1 = MemoryMappedFile.CreateFromFile (fname, FileMode.OpenOrCreate, name)) {
+ Assert.Fail ("Must fail");
+ }
+ } catch (IOException) {}
+ }
+ }
+
+ [Test]
+ public void NamedMappingsShareMemoryArea ()
+ {
+ var name = MkNamedMapping ();
+ using (var m0 = MemoryMappedFile.CreateNew(name, 4096, MemoryMappedFileAccess.ReadWrite)) {
+ using (var m1 = MemoryMappedFile.CreateOrOpen (name, 4096, MemoryMappedFileAccess.ReadWrite)) {
+ using (MemoryMappedViewAccessor v0 = m0.CreateViewAccessor (), v1 = m1.CreateViewAccessor ()) {
+ v0.Write (10, 0x12345);
+ Assert.AreEqual (0x12345, v1.ReadInt32 (10));
+ }
+ }
+ }
+ }
+
+ [Test]
+ public void NamedFileCanBeOpen ()
+ {
+ var name = MkNamedMapping ();
+ using (var sw = new FileStream (fname, FileMode.Open)) {
+ byte[] b = new byte[20];
+ for (int i = 0; i < 20; ++i)
+ b[i] = 0xFF;
+ sw.Write (b, 0, 20);
+ }
+
+ using (var m0 = MemoryMappedFile.CreateFromFile (fname, FileMode.Open, name)) {
+ using (var m1 = MemoryMappedFile.CreateOrOpen (name, 4096)) {
+ using (MemoryMappedViewAccessor v0 = m0.CreateViewAccessor (), v1 = m1.CreateViewAccessor ()) {
+ v0.Write (10, 0x11223344);
+ Assert.AreEqual (0x11223344, v1.ReadInt32 (10));
+ }
+ }
+ }
+ }
+
+ [Test]
+ public void MapAtEdgeOfPage ()
+ {
+ using (var f = new FileStream (fname, FileMode.Open)) {
+ var b = new byte [4096];
+ for (int i = 0; i < 4096; ++i)
+ b[i] = 0xAA;
+ for (int i = 0; i < 2; ++i)
+ f.Write (b, 0, 4096);
+ }
+ var m0 = MemoryMappedFile.CreateFromFile (fname, FileMode.Open);
+ var v0 = m0.CreateViewAccessor (500, 4096);
+ var v1 = m0.CreateViewAccessor (0, 4096 * 2);
+ for (int i = 0; i < 4096; ++i) {
+ Assert.AreEqual (0xAA, v1.ReadByte (i + 500));
+ v0.Write (i, (byte)0xFF);
+ Assert.AreEqual (0xFF, v1.ReadByte (i + 500));
+ }
+ }
}
}
string str = sb.ToString ();
- if (str.IndexOf(".") == -1)
- return Int64.Parse (str);
- else
- return double.Parse (str);
+ if (str.IndexOf ('.') < 0)
+ return Int64.Parse (str, CultureInfo.InvariantCulture);
+
+ return double.Parse (str, CultureInfo.InvariantCulture);
}
private char ProcessEscapes(char c)
case '#':
string date = ReadString ('#');
- val = DateTime.Parse (date);
+ val = DateTime.Parse (date, CultureInfo.InvariantCulture);
return Token.DateLiteral;
case '\'':
if (GDIPlus.Display == IntPtr.Zero) {
GDIPlus.Display = GDIPlus.XOpenDisplay (IntPtr.Zero);
if (GDIPlus.Display == IntPtr.Zero)
- throw new NotSupportedException ("Could not open display (X-Server required. Check you DISPLAY environment variable)");
+ throw new NotSupportedException ("Could not open display (X-Server required. Check your DISPLAY environment variable)");
}
if (hwnd == IntPtr.Zero) {
hwnd = GDIPlus.XRootWindow (GDIPlus.Display, GDIPlus.XDefaultScreen (GDIPlus.Display));
var stream = await wrequest.GetRequestStreamAsync ().ConfigureAwait (false);
await request.Content.CopyToAsync (stream).ConfigureAwait (false);
+ } else if (HttpMethod.Post.Equals (request.Method) || HttpMethod.Put.Equals (request.Method) || HttpMethod.Delete.Equals (request.Method)) {
+ // Explicitly set this to make sure we're sending a "Content-Length: 0" header.
+ // This fixes the issue that's been reported on the forums:
+ // http://forums.xamarin.com/discussion/17770/length-required-error-in-http-post-since-latest-release
+ wrequest.ContentLength = 0;
}
HttpWebResponse wresponse = null;
}
}
+ [Test]
+ public void Send_Complete_NoContent ()
+ {
+ foreach (var method in new HttpMethod[] { HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete }) {
+ bool? failed = null;
+ var listener = CreateListener (l => {
+ try {
+ var request = l.Request;
+
+ Assert.AreEqual (2, request.Headers.Count, "#1");
+ Assert.AreEqual ("0", request.Headers ["Content-Length"], "#1b");
+ Assert.AreEqual (method.Method, request.HttpMethod, "#2");
+ failed = false;
+ } catch {
+ failed = true;
+ }
+ });
+
+ try {
+ var client = new HttpClient ();
+ var request = new HttpRequestMessage (method, LocalServer);
+ var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result;
+
+ Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100");
+ Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101");
+ Assert.AreEqual (false, failed, "#102");
+ } finally {
+ listener.Close ();
+ }
+ }
+ }
+
[Test]
public void Send_Complete_Error ()
{
Test/XmlFiles/*.xml \
Test/XmlFiles/*.xaml
-VALID_PROFILE := $(filter 4, $(FRAMEWORK_VERSION_MAJOR))
+VALID_PROFILE := $(filter 4 monodroid monotouch, $(FRAMEWORK_VERSION_MAJOR))
ifndef VALID_PROFILE
LIBRARY_NAME = dummy-System.Xaml.dll
NO_INSTALL = yes
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, Inherited = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class AmbientAttribute : Attribute
{
}
{
[MarkupExtensionReturnType (typeof (Array))]
[ContentProperty ("Items")]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)]
-#endif
public class ArrayExtension : MarkupExtension
{
public ArrayExtension ()
public Type Type { get; set; }
IList items;
-#if !NET_2_1
[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-#endif
public IList Items {
get { return items; }
}
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class ConstructorArgumentAttribute : Attribute
{
public ConstructorArgumentAttribute (string argumentName)
// member regardless of this attribute.
[AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class ContentPropertyAttribute : Attribute
{
public ContentPropertyAttribute ()
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class ContentWrapperAttribute : Attribute
{
public ContentWrapperAttribute (Type contentWrapper)
}
public Type ContentWrapper { get; private set; }
-#if !NET_2_1
+
+#if !__MOBILE__
public override Object TypeId {
get { return this; }
}
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public class DateTimeValueSerializer : ValueSerializer
{
const DateTimeStyles styles = DateTimeStyles.RoundtripKind | DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite;
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class DependsOnAttribute : Attribute
{
public DependsOnAttribute (string name)
public string Name { get; private set; }
-#if !NET_2_1
+#if !__MOBILE__
// really? I doubt it should be overriden.
public override Object TypeId {
get { return this; }
namespace System.Windows.Markup
{
[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class DictionaryKeyPropertyAttribute : Attribute
{
public DictionaryKeyPropertyAttribute (string name)
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public interface IComponentConnector
{
void Connect (int connectionId, object target);
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public interface INameScope
{
object FindName (string name);
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)]
-#endif
public interface IProvideValueTarget
{
object TargetObject { get; }
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationCore_3_5)]
-#endif
public interface IUriContext
{
Uri BaseUri { get; set; }
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public interface IValueSerializerContext : ITypeDescriptorContext, IServiceProvider
{
ValueSerializer GetValueSerializerFor (PropertyDescriptor descriptor);
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public interface IXamlTypeResolver
{
Type Resolve (string qualifiedTypeName);
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public abstract class MarkupExtension
{
public abstract object ProvideValue (IServiceProvider serviceProvider);
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class NameScopePropertyAttribute : Attribute
{
public NameScopePropertyAttribute (string name)
namespace System.Windows.Markup
{
[MarkupExtensionReturnType (typeof (Object))]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)]
-#endif
public class NullExtension : MarkupExtension
{
public override Object ProvideValue (IServiceProvider serviceProvider)
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Assembly)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class RootNamespaceAttribute : Attribute
{
public RootNamespaceAttribute (string nameSpace)
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class RuntimeNamePropertyAttribute : Attribute
{
public RuntimeNamePropertyAttribute (string name)
{
[MarkupExtensionReturnType (typeof (object))]
[TypeConverter (typeof (StaticExtensionConverter))]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)]
-#endif
public class StaticExtension : MarkupExtension
{
public StaticExtension ()
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class TrimSurroundingWhitespaceAttribute : Attribute
{
}
{
[MarkupExtensionReturnType (typeof (Type))]
[TypeConverter (typeof (TypeExtensionConverter))]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)]
-#endif
public class TypeExtension : MarkupExtension
{
public TypeExtension ()
[ConstructorArgument ("type")]
[DefaultValue (null)]
public Type Type { get; set; }
-#if !NET_2_1
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-#endif
public string TypeName { get; set; }
public override object ProvideValue (IServiceProvider serviceProvider)
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class, AllowMultiple = false)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class UidPropertyAttribute : Attribute
{
public UidPropertyAttribute (string name)
namespace System.Windows.Markup
{
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public abstract class ValueSerializer
{
-#if !NET_2_1
public static ValueSerializer GetSerializerFor (PropertyDescriptor descriptor)
{
return GetSerializerFor (descriptor, null);
}
-#endif
public static ValueSerializer GetSerializerFor (Type type)
{
return GetSerializerFor (type, null);
}
-#if !NET_2_1
// untested
public static ValueSerializer GetSerializerFor (PropertyDescriptor descriptor, IValueSerializerContext context)
{
return new TypeConverterValueSerializer (tc);
return null;
}
-#endif
public static ValueSerializer GetSerializerFor (Type type, IValueSerializerContext context)
{
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class ValueSerializerAttribute : Attribute
{
public ValueSerializerAttribute (string valueSerializerTypeName)
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class WhitespaceSignificantCollectionAttribute : Attribute
{
}
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Class, AllowMultiple = false)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class XmlLangPropertyAttribute : Attribute
{
public XmlLangPropertyAttribute (string name)
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class XmlnsCompatibleWithAttribute : Attribute
{
public XmlnsCompatibleWithAttribute (string oldNamespace, string newNamespace)
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class XmlnsDefinitionAttribute : Attribute
{
public XmlnsDefinitionAttribute (string xmlNamespace, string clrNamespace)
namespace System.Windows.Markup
{
[AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)]
-#if !NET_2_1
[System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)]
-#endif
public sealed class XmlnsPrefixAttribute : Attribute
{
public XmlnsPrefixAttribute (string xmlNamespace, string prefix)
namespace System.Xaml
{
-#if !NET_2_1
[Serializable]
-#endif
public class XamlDuplicateMemberException : XamlException
{
public XamlDuplicateMemberException ()
{
}
-#if !NET_2_1
protected XamlDuplicateMemberException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
DuplicateMember = (XamlMember) info.GetValue ("member", typeof (XamlMember));
ParentType = (XamlType) info.GetValue ("type", typeof (XamlType));
}
-#endif
public XamlMember DuplicateMember { get; set; }
public XamlType ParentType { get; set; }
-#if !NET_2_1
public override void GetObjectData (SerializationInfo info, StreamingContext context)
{
base.GetObjectData (info, context);
info.AddValue ("member", DuplicateMember);
info.AddValue ("type", ParentType);
}
-#endif
}
}
namespace System.Xaml
{
-#if !NET_2_1
[Serializable]
-#endif
public class XamlException : Exception
{
public XamlException ()
LinePosition = linePosition;
}
-#if !NET_2_1
protected XamlException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
LineNumber = info.GetInt32 ("lineNumber");
LinePosition = info.GetInt32 ("linePosition");
}
-#endif
public int LineNumber { get; protected internal set; }
public int LinePosition { get; protected internal set; }
get { return FormatLine (base.Message, LineNumber, LinePosition); }
}
-#if !NET_2_1
public override void GetObjectData (SerializationInfo info, StreamingContext context)
{
info.AddValue ("lineNumber", LineNumber);
info.AddValue ("linePosition", LinePosition);
}
-#endif
}
}
namespace System.Xaml
{
-#if !NET_2_1
[Serializable]
-#endif
public class XamlInternalException : XamlException
{
public XamlInternalException ()
{
}
-#if !NET_2_1
protected XamlInternalException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
}
-#endif
}
}
get { return directive_ns ?? (DeclaringType == null ? null : DeclaringType.PreferredXamlNamespace); }
}
-#if !NET_2_1
public DesignerSerializationVisibility SerializationVisibility {
get {
var c= GetCustomAttributeProvider ();
return a != null ? a.Visibility : DesignerSerializationVisibility.Visible;
}
}
-#endif
public bool IsAttachable {
get { return is_attachable; }
namespace System.Xaml
{
-#if !NET_2_1
[Serializable]
-#endif
public class XamlObjectReaderException : XamlException
{
public XamlObjectReaderException ()
{
}
-#if !NET_2_1
protected XamlObjectReaderException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
}
-#endif
}
}
namespace System.Xaml
{
-#if !NET_2_1
[Serializable]
-#endif
public class XamlObjectWriterException : XamlException
{
public XamlObjectWriterException ()
{
}
-#if !NET_2_1
protected XamlObjectWriterException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
}
-#endif
}
}
using System.ComponentModel;
using System.Reflection;
using System.Windows.Markup;
-#if !NET_2_1
+#if !__MOBILE__
using System.Xaml.Permissions;
#endif
using System.Xaml.Schema;
: base (settings)
{
var s = settings;
-#if !NET_2_1
+#if !__MOBILE__
AccessLevel = s.AccessLevel;
#endif
AfterBeginInitHandler = s.AfterBeginInitHandler;
public EventHandler<XamlObjectEventArgs> BeforePropertiesHandler { get; set; }
public EventHandler<XamlSetValueEventArgs> XamlSetValueHandler { get; set; }
-#if !NET_2_1
+#if !__MOBILE__
[MonoTODO ("Ignored")]
public XamlAccessLevel AccessLevel { get; set; }
#endif
namespace System.Xaml
{
-#if !NET_2_1
[Serializable]
-#endif
public class XamlParseException : XamlException
{
public XamlParseException ()
{
}
-#if !NET_2_1
protected XamlParseException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
}
-#endif
}
}
{
if (referenceAssemblies != null)
reference_assemblies = new List<Assembly> (referenceAssemblies);
-#if !NET_2_1
else
AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoaded;
-#endif
if (settings == null)
return;
SupportMarkupExtensionsWithDuplicateArity = settings.SupportMarkupExtensionsWithDuplicateArity;
}
-#if !NET_2_1
~XamlSchemaContext ()
{
if (reference_assemblies == null)
AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoaded;
}
-#endif
IList<Assembly> reference_assemblies;
return compat_nss.TryGetValue (xamlNamespace, out compatibleNamespace);
}
-#if !NET_2_1
void OnAssemblyLoaded (object o, AssemblyLoadEventArgs e)
{
if (reference_assemblies != null)
if (all_xaml_types != null)
FillAllXamlTypes (e.LoadedAssembly);
}
-#endif
-
+
// cache updater methods
void FillXamlNamespaces (Assembly ass)
{
namespace System.Xaml
{
-#if !NET_2_1
[Serializable]
-#endif
public class XamlSchemaException : XamlException
{
public XamlSchemaException ()
{
}
-#if !NET_2_1
protected XamlSchemaException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
}
-#endif
}
}
return sw.ToString ();
}
-#if !NET_2_1
public static void Save (string fileName, object instance)
{
using (var xw = XmlWriter.Create (fileName, new XmlWriterSettings () { OmitXmlDeclaration = true, Indent = true }))
Save (xw, instance);
}
-#endif
public static void Save (Stream stream, object instance)
{
namespace System.Xaml
{
-#if !NET_2_1
[Serializable]
-#endif
public class XamlXmlWriterException : XamlException
{
public XamlXmlWriterException ()
{
}
-#if !NET_2_1
protected XamlXmlWriterException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
}
-#endif
}
}
}
value = header.Substring (beginQ, pos - beginQ);
- pos += 2;
+ pos += useQuote ? 2 : 1;
return true;
}
}
throw new ArgumentException ("value");
maxServicePoints = value;
- RecycleServicePoints ();
}
}
if (address == null)
throw new ArgumentNullException ("address");
- if ((servicePoints.Count % 4) == 0)
- RecycleServicePoints ();
-
var origAddress = new Uri (address.Scheme + "://" + address.Authority);
bool usesProxy = false;
return sp;
}
- // Internal Methods
-
- static void RecycleServicePoints ()
- {
- lock (servicePoints) {
- var toRemove = new ArrayList ();
- var idleList = new SortedDictionary<DateTime, ServicePoint> ();
- IDictionaryEnumerator e = servicePoints.GetEnumerator ();
- while (e.MoveNext ()) {
- ServicePoint sp = (ServicePoint) e.Value;
- DateTime idleSince;
- if (sp.CheckAvailableForRecycling (out idleSince)) {
- toRemove.Add (e.Key);
- continue;
- }
-
- while (idleList.ContainsKey (idleSince))
- idleSince = idleSince.AddMilliseconds (1);
- idleList.Add (idleSince, sp);
- }
-
- for (int i = 0; i < toRemove.Count; i++)
- servicePoints.Remove (toRemove [i]);
-
- if (maxServicePoints == 0 || servicePoints.Count <= maxServicePoints)
- return;
-
- // get rid of the ones with the longest idle time
- foreach (var sp in idleList.Values) {
- if (servicePoints.Count <= maxServicePoints)
- break;
- servicePoints.Remove (sp);
- }
- }
- }
#if SECURITY_DEP
internal class ChainValidationHelper {
object sender;
{
if (!callbackDone && cb != null) {
callbackDone = true;
-// if (true || synch)
- cb (this);
-// else
-// ThreadPool.QueueUserWorkItem (CB, null);
+ cb (this);
}
}
- void CB (object unused)
- {
- cb (this);
- }
-
internal void WaitUntilComplete ()
{
if (IsCompleted)
//TODO: abort requests or wait for them to finish
lock (sPoint) {
closing = true;
- foreach (var cnc in connections) {
- if (cnc.Connection == null)
- continue;
- cnc.Connection.Close (false);
- cnc.Connection = null;
+ var iter = connections.First;
+ while (iter != null) {
+ var cnc = iter.Value.Connection;
+ var node = iter;
+ iter = iter.Next;
+
+ connections.Remove (node);
+ cnc.Close (false);
OnConnectionClosed ();
}
- connections.Clear ();
}
}
ConnectionState FindIdleConnection ()
{
foreach (var cnc in connections) {
- if (cnc.Busy || cnc.Connection == null)
+ if (cnc.Busy)
continue;
connections.Remove (cnc);
return cnc.Connection;
}
- if (sPoint.ConnectionLimit > connections.Count) {
+ if (sPoint.ConnectionLimit > connections.Count || connections.Count == 0) {
created = true;
cnc = new ConnectionState (this);
connections.AddFirst (cnc);
}
int count = 0;
- for (var node = connections.First; node != null; node = node.Next) {
- var cnc = node.Value;
-
- if (cnc.Connection == null) {
- connections.Remove (node);
- OnConnectionClosed ();
- continue;
- }
+ var iter = connections.First;
+ while (iter != null) {
+ var cnc = iter.Value;
+ var node = iter;
+ iter = iter.Next;
++count;
if (cnc.Busy)
if (connectionsToClose == null)
connectionsToClose = new List<WebConnection> ();
connectionsToClose.Add (cnc.Connection);
- cnc.Connection = null;
+ connections.Remove (node);
}
recycled = connections.Count == 0;
}
class ConnectionState : IWebConnectionState {
- public WebConnection Connection;
+ public WebConnection Connection {
+ get;
+ private set;
+ }
public WebConnectionGroup Group {
get;
if (identities == null)
throw new ArgumentNullException ("identities");
- identities = new List<ClaimsIdentity> (identities);
+ this.identities = new List<ClaimsIdentity> (identities);
}
public ClaimsPrincipal (IIdentity identity)
}
public AggregateException (params Exception[] innerExceptions)
- : this (string.Empty, innerExceptions)
+ : this (defaultMessage, innerExceptions)
{
}
public string Htmlize (XmlReader ecma_xml, XsltArgumentList args)
{
- EnsureTransform ();
-
- var output = new StringBuilder ();
- ecma_transform.Transform (ecma_xml,
- args,
- XmlWriter.Create (output, ecma_transform.OutputSettings),
- CreateDocumentResolver ());
- return output.ToString ();
+ try{
+ EnsureTransform ();
+
+ var output = new StringBuilder ();
+ ecma_transform.Transform (ecma_xml,
+ args,
+ XmlWriter.Create (output, ecma_transform.OutputSettings),
+ CreateDocumentResolver ());
+ return output.ToString ();
+ }
+ catch(Exception x)
+ {
+ var msg = x.ToString ();
+ return msg;
+ }
}
protected virtual XmlResolver CreateDocumentResolver ()
public string Export (Stream stream, Dictionary<string, string> extraArgs)
{
- return Htmlize (XmlReader.Create (WrapStream (new StreamReader (stream), extraArgs)), extraArgs);
+ return Htmlize (XmlReader.Create (new StreamReader(stream)), extraArgs);
}
public string Export (string input, Dictionary<string, string> extraArgs)
{
- return Htmlize (XmlReader.Create (WrapStream (new StringReader (input), extraArgs)), extraArgs);
+ return Htmlize (XmlReader.Create (new StringReader(input)), extraArgs);
}
- TextReader WrapStream (TextReader initialReader, Dictionary<string, string> renderArgs)
- {
- string show;
- if (renderArgs.TryGetValue ("show", out show) && show == "namespace")
- return new AvoidCDataTextReader (initialReader);
- return initialReader;
- }
static void EnsureTransform ()
{
}
}
}
-
- public class AvoidCDataTextReader : TextReader
- {
- static readonly char[] CDataPattern = new[] {
- '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '['
- };
- static readonly char[] CDataClosingPattern = new[] {
- ']', ']', '>'
- };
- TextReader wrappedReader;
- char[] backingArray = new char[9]; // "<![CDATA[".Length
- int currentIndex = -1;
- int eofIndex = -1;
- bool inCData;
-
- public AvoidCDataTextReader (TextReader wrappedReader)
- {
- this.wrappedReader = wrappedReader;
- }
-
- public override int Peek ()
- {
- if (!EnsureBuffer ())
- return -1;
- return (int)backingArray[currentIndex];
- }
-
- public override int Read ()
- {
- if (!EnsureBuffer ())
- return -1;
- var result = (int)backingArray[currentIndex];
- var next = wrappedReader.Read ();
- if (next == -1 && eofIndex == -1)
- eofIndex = currentIndex;
- else
- backingArray[currentIndex] = (char)next;
- currentIndex = (currentIndex + 1) % backingArray.Length;
- return result;
- }
-
- void ReadLength (int length)
- {
- for (int i = 0; i < length; i++)
- Read ();
- }
-
- bool EnsureBuffer ()
- {
- if (currentIndex == -1) {
- currentIndex = 0;
- var read = wrappedReader.ReadBlock (backingArray, 0, backingArray.Length);
- if (read < backingArray.Length)
- eofIndex = read;
- return read > 0;
- } else if (currentIndex == eofIndex) {
- return false;
- }
- if (!inCData && PatternDetect (CDataPattern)) {
- inCData = true;
- ReadLength (CDataPattern.Length);
- return EnsureBuffer ();
- }
- if (inCData && PatternDetect (CDataClosingPattern)) {
- inCData = false;
- ReadLength (CDataClosingPattern.Length);
- return EnsureBuffer ();
- }
-
- return true;
- }
-
- bool PatternDetect (char[] pattern)
- {
- return backingArray[currentIndex] == pattern[0] && Enumerable.Range (1, pattern.Length - 1).All (i => backingArray[(currentIndex + i) % backingArray.Length] == pattern[i]);
- }
- }
+
}
+++ /dev/null
-using System;
-using System.IO;
-using System.Linq;
-using System.Xml;
-using System.Collections.Generic;
-
-using NUnit.Framework;
-
-using Monodoc;
-using Monodoc.Generators;
-using Monodoc.Generators.Html;
-
-namespace MonoTests.Monodoc.Generators
-{
- [TestFixture]
- public class AvoidCDataTextReaderTest
- {
- void AssertSameInputOutput (string expected, string input)
- {
- var processed = new AvoidCDataTextReader (new StringReader (input)).ReadToEnd ();
- Assert.AreEqual (expected, processed);
- }
-
- [Test]
- public void NoCDataXmlTest ()
- {
- var input = @"<elements><summary>Addressbook APIs.</summary><remarks /><class name=""ABAddressBook"" fullname=""MonoTouch.AddressBook.ABAddressBook"" assembly=""monotouch""><summary>
- Provides access to the system Address Book.
- </summary></class></elements>";
-
- AssertSameInputOutput (input, input);
- }
-
- [Test]
- public void WithCDataXmlTest ()
- {
- var input = @"<elements><summary>Addressbook APIs.</summary><remarks /><class name=""ABAddressBook"" fullname=""MonoTouch.AddressBook.ABAddressBook"" assembly=""monotouch""><summary><![CDATA[
- Provides access to the system Address Book.]]>
- </summary></class></elements>";
-
- AssertSameInputOutput (input.Replace ("<![CDATA[", string.Empty).Replace ("]]>", string.Empty), input);
- }
-
- [Test]
- public void PartialCDataXmlTest ()
- {
- var input = @"<elements><summary>Addressbook APIs.</summary><remarks /><class name=""ABAddressBook"" fullname=""MonoTouch.AddressBook.ABAddressBook"" assembly=""monotouch""><summary><![CDA[
- Provides access to the system Address Book.]]>
- </summary></class></elements>";
-
- AssertSameInputOutput (input, input);
- }
-
- [Test]
- public void FinishWithPartialCDataXmlTest ()
- {
- var input = @"<elements><summary>Addressbook APIs.</summary><remarks /><class name=""ABAddressBook"" fullname=""MonoTouch.AddressBook.ABAddressBook"" assembly=""monotouch""><summary>
- Provides access to the system Address Book.
- </summary></class></elements><![CDA[";
-
- AssertSameInputOutput (input, input);
- }
-
- [Test]
- public void FinishWithCDataXmlTest ()
- {
- var input = @"<elements><summary>Addressbook APIs.</summary><remarks /><class name=""ABAddressBook"" fullname=""MonoTouch.AddressBook.ABAddressBook"" assembly=""monotouch""><summary>
- Provides access to the system Address Book.
- </summary></class></elements><![CDATA[";
-
- AssertSameInputOutput (input.Replace ("<![CDATA[", string.Empty), input);
- }
-
- [Test]
- public void EmptyInputTest ()
- {
- AssertSameInputOutput (string.Empty, string.Empty);
- }
-
- [Test]
- public void LimitedInputTest ()
- {
- AssertSameInputOutput ("foo", "foo");
- }
- }
-}
--- /dev/null
+.assembly extern mscorlib
+{
+}
+
+.assembly extern System.Core
+{
+}
+
+.assembly extern 'CS0012-lib-missing'
+{
+}
+
+.assembly 'CS0012-23-lib'
+{
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+
+.module 'CS0012-23-lib.dll'
+
+
+.class public abstract auto ansi sealed beforefieldinit B
+ extends [mscorlib]System.Object
+{
+ .field public static valuetype ['CS0012-lib-missing']Struct`1<int32>[] ArrayMember
+}
$(wildcard dlls/second/*.cs)
TEST_SUPPORT_FILES = \
- CS0012-lib.dll CS0012-2-lib.dll CS0012-3-lib.dll CS0012-4-lib.dll CS0012-5-lib.dll CS0012-6-lib.dll CS0012-9-lib.dll CS0012-10-lib.dll CS0012-11-lib.dll CS0012-12-lib.dll CS0012-13-lib.dll CS0012-14-lib.dll CS0012-15-lib.dll CS0012-16-lib.dll CS0012-17-lib.dll CS0012-18-lib.dll CS0012-21-lib.dll CS0012-22-lib.dll CS0019-71-lib.dll CS0029-26-lib.dll \
+ CS0012-lib.dll CS0012-2-lib.dll CS0012-3-lib.dll CS0012-4-lib.dll CS0012-5-lib.dll CS0012-6-lib.dll CS0012-9-lib.dll CS0012-10-lib.dll CS0012-11-lib.dll CS0012-12-lib.dll CS0012-13-lib.dll CS0012-14-lib.dll CS0012-15-lib.dll CS0012-16-lib.dll CS0012-17-lib.dll CS0012-18-lib.dll CS0012-21-lib.dll CS0012-22-lib.dll CS0012-23-lib.dll CS0019-71-lib.dll CS0029-26-lib.dll \
CS0103-2-lib.dll CS0118-2-lib.dll CS0122-8-lib.dll CS0122-10-lib.dll CS0122-14-lib.dll CS0122-15-lib.dll CS0122-19-lib.dll CS0122-35-lib.dll CS0122-36-lib.dll CS0143-lib.dll CS0144-3-lib.dll CS0165-19-lib.dll \
CS0205-3-lib.dll CS0246-29-lib.dll CS0229-3-lib.dll CS0229-4-lib.dll CS0266-25-lib.dll \
CS0315-2-lib.dll \
--- /dev/null
+// CS0012: The type `Struct`1<int>' is defined in an assembly that is not referenced. Consider adding a reference to assembly `CS0012-lib-missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
+// Line: 9
+// Compiler options: -r:CS0012-23-lib.dll
+
+public class C
+{
+ public static void Main ()
+ {
+ var val = B.ArrayMember;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS0070: The event `A.evt' can only appear on the left hand side of += or -= when used outside of the type `A'
+// Line: 22
+
+using System;
+
+public static class EventExtensions
+{
+ public static void Raise (this EventHandler h)
+ {
+ }
+}
+
+public class A
+{
+ public event EventHandler evt;
+}
+
+public class B : A
+{
+ public void Run()
+ {
+ Action a = () => evt.Raise ();
+ }
+}
\ No newline at end of file
+++ /dev/null
-// CS1984: The `await' operator cannot be used in the body of a finally clause
-// Line: 13
-
-using System;
-using System.Threading.Tasks;
-
-class C
-{
- public async Task Test ()
- {
- try {
- } finally {
- await Call ();
- }
- }
-
- static Task Call ()
- {
- return null;
- }
-}
return (p);
}
+#ifdef __GNUC__
+#define GNUC_UNUSED __attribute__((__unused__))
+#else
+#define GNUC_UNUSED
+#endif
create_file_names()
{
int i, len;
char *tmpdir;
+ int mkstemp_res GNUC_UNUSED;
#if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
tmpdir = ".";
prolog_file_name[len + 5] = 'p';
local_file_name[len + 5] = 'l';
- mkstemp(action_file_name);
- mkstemp(prolog_file_name);
- mkstemp(local_file_name);
+ mkstemp_res = mkstemp(action_file_name);
+ mkstemp_res = mkstemp(prolog_file_name);
+ mkstemp_res = mkstemp(local_file_name);
len = strlen(file_prefix);
protected override Expression DoResolve (ResolveContext rc)
{
- if (rc.HasSet (ResolveContext.Options.FinallyScope)) {
- rc.Report.Error (1984, loc, "The `await' operator cannot be used in the body of a finally clause");
- }
-
if (rc.HasSet (ResolveContext.Options.LockScope)) {
rc.Report.Error (1996, loc,
"The `await' operator cannot be used in the body of a lock statement");
}
}
+ public LocalVariable AsyncThrowVariable { get; set; }
+
#endregion
public void AddStatementEpilog (IExpressionCleanup cleanupExpression)
public override void FlowAnalysis (FlowAnalysisContext fc)
{
if ((oper & Operator.LogicalMask) == 0) {
- var fc_ontrue = fc.DefiniteAssignmentOnTrue;
- var fc_onfalse = fc.DefiniteAssignmentOnFalse;
fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment;
left.FlowAnalysis (fc);
fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment;
right.FlowAnalysis (fc);
- fc.DefiniteAssignmentOnTrue = fc_ontrue;
- fc.DefiniteAssignmentOnFalse = fc_onfalse;
return;
}
if (!Emit (ec, v))
v.Emit (ec);
}
-
+
public override void EmitStatement (EmitContext ec)
{
LocalTemporary v = null;
public override void Emit (EmitContext ec)
{
- EmitToFieldSource (ec);
+ var await_field = EmitToFieldSource (ec);
+ if (await_field != null)
+ await_field.Emit (ec);
}
protected sealed override FieldExpr EmitToFieldSource (EmitContext ec)
// with disable flow analysis as we don't know whether left side expression
// is used as variable or type
//
- if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) {
+ if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess || expr is EventExpr) {
expr = expr.Resolve (rc);
} else if (expr is TypeParameterExpr) {
expr.Error_UnexpectedKind (rc, flags, sn.Location);
return e;
}
+ public override void Emit (EmitContext ec)
+ {
+ if (method == null && TypeSpec.IsValueType (type) && initializers.Initializers.Count > 1 && initializers.ContainsEmitWithAwait ()) {
+ var fe = ec.GetTemporaryField (type);
+
+ if (!Emit (ec, fe))
+ fe.Emit (ec);
+
+ return;
+ }
+
+ base.Emit (ec);
+ }
+
public override bool Emit (EmitContext ec, IMemoryLocation target)
{
bool left_on_stack;
LocalTemporary temp = null;
instance = target as LocalTemporary;
+ if (instance == null)
+ instance = target as StackFieldExpr;
if (instance == null) {
if (!left_on_stack) {
if (tp != null)
return Inflate (tp);
- var ac = type as ArrayContainer;
- if (ac != null) {
- var et = Inflate (ac.Element);
- if (et != ac.Element)
- return ArrayContainer.MakeType (context.Module, et, ac.Rank);
+ var ec = type as ElementTypeSpec;
+ if (ec != null) {
+ var et = Inflate (ec.Element);
+ if (et != ec.Element) {
+ var ac = ec as ArrayContainer;
+ if (ac != null)
+ return ArrayContainer.MakeType (context.Module, et, ac.Rank);
+
+ throw new NotImplementedException ();
+ }
- return ac;
+ return ec;
}
if (type.Kind == MemberKind.MissingType)
protected override void DoEmit (EmitContext ec)
{
- if (expr == null)
- ec.Emit (OpCodes.Rethrow);
- else {
+ if (expr == null) {
+ var atv = ec.AsyncThrowVariable;
+ if (atv != null) {
+ if (atv.HoistedVariant != null) {
+ atv.HoistedVariant.Emit (ec);
+ } else {
+ atv.Emit (ec);
+ }
+
+ ec.Emit (OpCodes.Throw);
+ } else {
+ ec.Emit (OpCodes.Rethrow);
+ }
+ } else {
expr.Emit (ec);
ec.Emit (OpCodes.Throw);
{
li.CreateBuilder (ec);
- if (Initializer != null)
+ if (Initializer != null && !IsUnreachable)
((ExpressionStatement) Initializer).EmitStatement (ec);
if (declarators != null) {
foreach (var d in declarators) {
d.Variable.CreateBuilder (ec);
- if (d.Initializer != null) {
+ if (d.Initializer != null && !IsUnreachable) {
ec.Mark (d.Variable.Location);
((ExpressionStatement) d.Initializer).EmitStatement (ec);
}
DoEmit (ec);
}
- protected void EmitScopeInitializers (EmitContext ec)
+ public void EmitScopeInitializers (EmitContext ec)
{
foreach (Statement s in scope_initializers)
s.Emit (ec);
+
+ scope_initializers = null;
}
protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
end_unreachable = s.FlowAnalysis (fc);
if (s.IsUnreachable) {
- statements[startIndex] = new EmptyStatement (s.loc);
+ statements [startIndex] = RewriteUnreachableStatement (s);
continue;
}
if (s.IsUnreachable) {
s.FlowAnalysis (fc);
- statements[startIndex] = new EmptyStatement (s.loc);
+ statements [startIndex] = RewriteUnreachableStatement (s);
}
}
}
return !Explicit.HasReachableClosingBrace;
}
+ static Statement RewriteUnreachableStatement (Statement s)
+ {
+ // LAMESPEC: It's not clear whether declararion statement should be part of reachability
+ // analysis. Even csc report unreachable warning for it but it's actually used hence
+ // we try to emulate this behaviour
+ //
+ // Consider:
+ // goto L;
+ // int v;
+ // L:
+ // v = 1;
+
+ if (s is BlockVariable)
+ return s;
+
+ return new EmptyStatement (s.loc);
+ }
+
public void ScanGotoJump (Statement label)
{
int i;
EmitTryBodyPrepare (ec);
EmitTryBody (ec);
- ec.BeginFinallyBlock ();
+ bool begin = EmitBeginFinallyBlock (ec);
Label start_finally = ec.DefineLabel ();
if (resume_points != null) {
EmitFinallyBody (ec);
}
- ec.EndExceptionBlock ();
+ if (begin)
+ ec.EndExceptionBlock ();
}
public override void EmitForDispose (EmitContext ec, LocalBuilder pc, Label end, bool have_dispatcher)
return res;
}
+ protected virtual bool EmitBeginFinallyBlock (EmitContext ec)
+ {
+ ec.BeginFinallyBlock ();
+ return true;
+ }
+
public override Reachability MarkReachable (Reachability rc)
{
base.MarkReachable (rc);
if (li != null)
EmitCatchVariableStore (ec);
- } else {
- if (IsGeneral)
- ec.BeginCatchBlock (ec.BuiltinTypes.Object);
- else
- ec.BeginCatchBlock (CatchType);
- if (li != null) {
- EmitCatchVariableStore (ec);
+ if (Block.HasAwait) {
+ Block.EmitScopeInitializers (ec);
} else {
- ec.Emit (OpCodes.Pop);
+ Block.Emit (ec);
}
+
+ return;
+ }
+
+ if (IsGeneral)
+ ec.BeginCatchBlock (ec.BuiltinTypes.Object);
+ else
+ ec.BeginCatchBlock (CatchType);
+
+ if (li != null) {
+ EmitCatchVariableStore (ec);
+ } else {
+ ec.Emit (OpCodes.Pop);
}
if (!Block.HasAwait)
hoisted_temp = new LocalTemporary (li.Type);
hoisted_temp.Store (ec);
- // switch to assigning from the temporary variable and not from top of the stack
+ // switch to assignment from temporary variable and not from top of the stack
assign.UpdateSource (hoisted_temp);
}
}
public override bool Resolve (BlockContext bc)
{
using (bc.Set (ResolveContext.Options.CatchScope)) {
- if (type_expr != null) {
+ if (type_expr == null) {
+ if (CreateExceptionVariable (bc.Module.Compiler.BuiltinTypes.Object)) {
+ Expression source = new EmptyExpression (li.Type);
+ assign = new CompilerAssign (new LocalVariableReference (li, Location.Null), source, Location.Null);
+ Block.AddScopeStatement (new StatementExpression (assign, Location.Null));
+ }
+ } else {
type = type_expr.ResolveAsType (bc);
if (type == null)
return false;
+ if (li == null)
+ CreateExceptionVariable (type);
+
if (type.BuiltinType != BuiltinTypeSpec.Type.Exception && !TypeSpec.IsBaseClass (type, bc.BuiltinTypes.Exception, false)) {
bc.Report.Error (155, loc, "The type caught or thrown must be derived from System.Exception");
} else if (li != null) {
}
}
+ bool CreateExceptionVariable (TypeSpec type)
+ {
+ if (!Block.HasAwait)
+ return false;
+
+ // TODO: Scan the block for rethrow expression
+ //if (!Block.HasRethrow)
+ // return;
+
+ li = LocalVariable.CreateCompilerGenerated (type, block, Location.Null);
+ return true;
+ }
+
protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
{
- if (li != null) {
+ if (li != null && !li.IsCompilerGenerated) {
fc.SetVariableAssigned (li.VariableInfo, true);
}
stmt.Emit (ec);
}
+ protected override bool EmitBeginFinallyBlock (EmitContext ec)
+ {
+ if (fini.HasAwait)
+ return false;
+
+ return base.EmitBeginFinallyBlock (ec);
+ }
+
public override void EmitFinallyBody (EmitContext ec)
{
+ StackFieldExpr exception_field;
+
+ if (fini.HasAwait) {
+ //
+ // Emits catch block like
+ //
+ // catch (object temp) {
+ // this.exception_field = temp;
+ // }
+ //
+ var type = ec.BuiltinTypes.Object;
+ ec.BeginCatchBlock (type);
+
+ var temp = ec.GetTemporaryLocal (type);
+ ec.Emit (OpCodes.Stloc, temp);
+
+ exception_field = ec.GetTemporaryField (type);
+ ec.EmitThis ();
+ ec.Emit (OpCodes.Ldloc, temp);
+ exception_field.EmitAssignFromStack (ec);
+
+ ec.EndExceptionBlock ();
+
+ ec.FreeTemporaryLocal (temp, type);
+ } else {
+ exception_field = null;
+ }
+
fini.Emit (ec);
+
+ if (exception_field != null) {
+ //
+ // Emits exception rethrow
+ //
+ // if (this.exception_field != null)
+ // throw this.exception_field;
+ //
+ exception_field.Emit (ec);
+ var skip_throw = ec.DefineLabel ();
+ ec.Emit (OpCodes.Brfalse_S, skip_throw);
+ exception_field.Emit (ec);
+ ec.Emit (OpCodes.Throw);
+ ec.MarkLabel (skip_throw);
+
+ exception_field.IsAvailableForReuse = true;
+ }
}
protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
// 0 value is default label
ec.MarkLabel (labels [0]);
+ ec.Emit (OpCodes.Br, end);
+ var atv = ec.AsyncThrowVariable;
+ Catch c = null;
for (int i = 0; i < catch_sm.Count; ++i) {
- ec.Emit (OpCodes.Br, end);
+ if (c != null && c.Block.HasReachableClosingBrace)
+ ec.Emit (OpCodes.Br, end);
ec.MarkLabel (labels [i + 1]);
- catch_sm [i].Block.Emit (ec);
+ c = catch_sm [i];
+ ec.AsyncThrowVariable = c.Variable;
+ c.Block.Emit (ec);
}
+ ec.AsyncThrowVariable = atv;
ec.MarkLabel (end);
}
public VariableDeclaration (LocalVariable li, Location loc)
: base (li)
{
+ reachable = true;
this.loc = loc;
}
public RuntimeDispose (LocalVariable lv, Location loc)
: base (lv, loc)
{
+ reachable = true;
}
protected override void CheckIDiposableConversion (BlockContext bc, LocalVariable li, Expression initializer)
return ac;
}
+
+ public override List<MissingTypeSpecReference> ResolveMissingDependencies (MemberSpec caller)
+ {
+ return Element.ResolveMissingDependencies (caller);
+ }
}
class ReferenceContainer : ElementTypeSpec
--- /dev/null
+// Compiler options: -unsafe
+
+unsafe class X
+{
+ struct S
+ {
+ }
+
+ public class N<T>
+ {
+ S* s;
+ }
+}
+
+public class C
+{
+ public static void Main ()
+ {
+ new X.N<int> ();
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+
+class X
+{
+ public void Test (int g, out int results)
+ {
+ if ((results = Foo (g > 0 ? 1 : 2)) != 4)
+ {
+ Console.WriteLine (results);
+ }
+ }
+
+ int Foo (object o)
+ {
+ return 4;
+ }
+
+ public static void Main ()
+ {
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+
+class Program
+{
+ public static void Main ()
+ {
+ goto L1;
+ int z;
+ L1:
+ z = 3;
+ Console.WriteLine (z);
+ }
+}
\ No newline at end of file
-// Compiler options: -langversion:future
-
using System;
using System.Threading.Tasks;
using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
interface IFoo
{
}
}
+struct S2 : IEnumerable
+{
+ public List<int> Values;
+
+ public void Add (int x)
+ {
+ if (Values == null)
+ Values = new List<int> ();
+
+ Values.Add(x);
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return Values as IEnumerator;
+ }
+}
+
class Tester
{
async Task<T> NewInitTestGen<T> () where T : struct, IFoo
{
- int value = 9;
-
var s = new T () {
Value = await Task.Factory.StartNew (() => 13).ConfigureAwait (false)
};
return s;
}
+
+ static async Task<int> NewInitCol ()
+ {
+ var s = new S2 {
+ await Task.FromResult (1),
+ await Task.Factory.StartNew (() => 2)
+ };
+
+ return s.Values [0] + s.Values [1];
+ }
public static int Main ()
{
if (t.Result.Value != 13)
return 2;
+
+ var v = NewInitCol ().Result;
+ if (v != 3)
+ return 3;
return 0;
}
TestSingleAwait (false).Wait ();
if (counter != 2)
- return 1;
+ return 2;
counter = 0;
--- /dev/null
+using System;
+using System.Threading.Tasks;
+
+class C
+{
+ static int counter;
+
+ public static async Task TestRethrow (Exception e)
+ {
+ try {
+ throw e;
+ } catch (ApplicationException) {
+ Console.WriteLine ("x1a");
+ counter = 1;
+ await Task.Delay (1);
+ Console.WriteLine ("x2a");
+ counter = 3;
+ throw;
+ } catch {
+ counter = 9;
+ await Task.Delay (1);
+ Console.WriteLine ("ga");
+ throw;
+ }
+ }
+
+ public static int Main ()
+ {
+ var ex = new ApplicationException ();
+ try {
+ TestRethrow (ex).Wait ();
+ } catch (AggregateException e) {
+ if (e.InnerException != ex)
+ return 1;
+ }
+
+ if (counter != 3)
+ return 2;
+
+ var ex2 = new NotSupportedException ();
+ try {
+ TestRethrow (ex2).Wait ();
+ } catch (AggregateException e) {
+ if (e.InnerException != ex2)
+ return 3;
+ }
+
+ if (counter != 9)
+ return 4;
+
+ Console.WriteLine ("ok");
+ return 0;
+ }
+}
--- /dev/null
+using System;
+using System.Threading.Tasks;
+
+class TestFinally
+{
+ static int counter;
+
+ async static Task Test (bool throwException)
+ {
+ try {
+ if (throwException)
+ throw new ApplicationException ();
+
+ ++counter;
+ System.Console.WriteLine ();
+ } finally {
+ counter += 10;
+ await Task.Delay (2);
+ counter += 100;
+ }
+ counter += 1000;
+ }
+
+ static int Main ()
+ {
+ Test (false).Wait ();
+ if (counter != 1111)
+ return 1;
+
+ counter = 0;
+ try {
+ Test (true).Wait ();
+ return 2;
+ } catch (AggregateException) {
+ }
+
+ if (counter != 110)
+ return 3;
+
+ return 0;
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+using System.Threading.Tasks;
+
+class Test
+{
+ public static async Task<int[]> Run ()
+ {
+ return new int[] {
+ 1, await Task.Factory.StartNew (() => 2)
+ };
+ }
+
+ public static int Main ()
+ {
+ var t = Run ().Result;
+ if (t [0] != 1)
+ return 1;
+
+ if (t [1] != 2)
+ return 2;
+
+ return 0;
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+
+class X
+{
+ public static int Main ()
+ {
+ try {
+ bool x = true;
+ try {
+ throw new ApplicationException ();
+ } catch (NullReferenceException) if (x) {
+ throw;
+ }
+
+ return 1;
+ } catch (ApplicationException) {
+ Console.WriteLine ("ok");
+ return 0;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+using System.Threading.Tasks;
+
+class X
+{
+ static Exception ex = new ApplicationException ();
+
+ public static int Main ()
+ {
+ if (Test (5, null).Result != 5)
+ return 1;
+
+ try {
+ Test (5, ex).Wait ();
+ return 2;
+ } catch (AggregateException ae) {
+ if (ae.InnerException != ex)
+ return 3;
+ }
+
+ try {
+ Test (15, ex).Wait ();
+ return 4;
+ } catch (AggregateException ae) {
+ if (ae.InnerException != ex)
+ return 5;
+ }
+
+ try {
+ TestGeneric (5).Wait ();
+ return 10;
+ } catch (AggregateException ae) {
+ if (ae.InnerException != ex)
+ return 11;
+ }
+
+ try {
+ TestGeneric (15).Wait ();
+ return 12;
+ } catch (AggregateException ae) {
+ if (ae.InnerException != ex)
+ return 13;
+ }
+
+ return 0;
+ }
+
+ async static Task<int> Test (int x, Exception e)
+ {
+ try {
+ Console.WriteLine (x);
+ if (e != null)
+ throw e;
+ } catch (Exception) if (x != 15) {
+ await Task.FromResult (0);
+ throw;
+ }
+
+ return x;
+ }
+
+ async static Task<int> TestGeneric (int x)
+ {
+ try {
+ Console.WriteLine (x);
+ throw ex;
+ } catch if (x != 15) {
+ await Task.FromResult (0);
+ throw;
+ }
+
+ return x;
+ }
+}
\ No newline at end of file
</method>\r
</type>\r
</test>\r
+ <test name="gtest-615.cs">\r
+ <type name="X">\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="X+N`1[T]">\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="C">\r
+ <method name="Void Main()" attrs="150">\r
+ <size>8</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="gtest-anontype-01.cs">\r
<type name="Test">\r
<method name="Int32 Main()" attrs="150">\r
</method>\r
</type>\r
</test>\r
+ <test name="test-895.cs">\r
+ <type name="X">\r
+ <method name="Void Test(Int32, Int32 ByRef)" attrs="134">\r
+ <size>47</size>\r
+ </method>\r
+ <method name="Int32 Foo(System.Object)" attrs="129">\r
+ <size>10</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-896.cs">\r
+ <type name="Program">\r
+ <method name="Void Main()" attrs="150">\r
+ <size>15</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="test-9.cs">\r
<type name="X">\r
<method name="Int32 Main(System.String[])" attrs="150">\r
<size>33</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>82</size>\r
+ <size>107</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
</type>\r
<type name="Tester+<NewInitTestGen>c__async0`1[T]">\r
<method name="Void MoveNext()" attrs="486">\r
- <size>306</size>\r
+ <size>298</size>\r
</method>\r
<method name="Int32 <>m__0()" attrs="145">\r
<size>10</size>\r
<size>13</size>\r
</method>\r
</type>\r
+ <type name="S2">\r
+ <method name="Void Add(Int32)" attrs="134">\r
+ <size>36</size>\r
+ </method>\r
+ <method name="System.Collections.IEnumerator GetEnumerator()" attrs="486">\r
+ <size>20</size>\r
+ </method>\r
+ </type>\r
+ <type name="Tester">\r
+ <method name="System.Threading.Tasks.Task`1[System.Int32] NewInitCol()" attrs="145">\r
+ <size>33</size>\r
+ </method>\r
+ </type>\r
+ <type name="Tester+<NewInitCol>c__async1">\r
+ <method name="Void MoveNext()" attrs="486">\r
+ <size>370</size>\r
+ </method>\r
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">\r
+ <size>13</size>\r
+ </method>\r
+ <method name="Int32 <>m__0()" attrs="145">\r
+ <size>9</size>\r
+ </method>\r
+ </type>\r
</test>\r
<test name="test-async-16.cs">\r
<type name="Base">\r
</type>\r
<type name="C+<TestDoubleAwait>c__async1">\r
<method name="Void MoveNext()" attrs="486">\r
- <size>410</size>\r
+ <size>419</size>\r
</method>\r
<method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">\r
<size>13</size>\r
</method>\r
</type>\r
</test>\r
+ <test name="test-async-65.cs">\r
+ <type name="C">\r
+ <method name="Int32 Main()" attrs="150">\r
+ <size>161</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="C+<TestRethrow>c__async0">\r
+ <method name="Void MoveNext()" attrs="486">\r
+ <size>363</size>\r
+ </method>\r
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">\r
+ <size>13</size>\r
+ </method>\r
+ </type>\r
+ <type name="C">\r
+ <method name="System.Threading.Tasks.Task TestRethrow(System.Exception)" attrs="150">\r
+ <size>41</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
+ <test name="test-async-66.cs">\r
+ <type name="TestFinally">\r
+ <method name="System.Threading.Tasks.Task Test(Boolean)" attrs="145">\r
+ <size>41</size>\r
+ </method>\r
+ <method name="Int32 Main()" attrs="145">\r
+ <size>95</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="TestFinally+<Test>c__async0">\r
+ <method name="Void MoveNext()" attrs="486">\r
+ <size>277</size>\r
+ </method>\r
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">\r
+ <size>13</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
+ <test name="test-async-67.cs">\r
+ <type name="Test">\r
+ <method name="System.Threading.Tasks.Task`1[System.Int32[]] Run()" attrs="150">\r
+ <size>33</size>\r
+ </method>\r
+ <method name="Int32 Main()" attrs="150">\r
+ <size>53</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ <type name="Test+<Run>c__async0">\r
+ <method name="Void MoveNext()" attrs="486">\r
+ <size>239</size>\r
+ </method>\r
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">\r
+ <size>13</size>\r
+ </method>\r
+ <method name="Int32 <>m__0()" attrs="145">\r
+ <size>9</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="test-cls-00.cs">\r
<type name="CLSCLass_6">\r
<method name="Void add_Disposed(Delegate)" attrs="2182">\r
</method>\r
</type>\r
</test>\r
+ <test name="test-ex-filter-03.cs">\r
+ <type name="X">\r
+ <method name="Int32 Main()" attrs="150">\r
+ <size>52</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
+ <test name="test-ex-filter-04.cs">\r
+ <type name="X">\r
+ <method name="Int32 Main()" attrs="150">\r
+ <size>253</size>\r
+ </method>\r
+ <method name="System.Threading.Tasks.Task`1[System.Int32] Test(Int32, System.Exception)" attrs="145">\r
+ <size>49</size>\r
+ </method>\r
+ <method name="System.Threading.Tasks.Task`1[System.Int32] TestGeneric(Int32)" attrs="145">\r
+ <size>41</size>\r
+ </method>\r
+ <method name="Void .ctor()" attrs="6278">\r
+ <size>7</size>\r
+ </method>\r
+ <method name="Void .cctor()" attrs="6289">\r
+ <size>11</size>\r
+ </method>\r
+ </type>\r
+ <type name="X+<Test>c__async0">\r
+ <method name="Void MoveNext()" attrs="486">\r
+ <size>281</size>\r
+ </method>\r
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">\r
+ <size>13</size>\r
+ </method>\r
+ </type>\r
+ <type name="X+<TestGeneric>c__async1">\r
+ <method name="Void MoveNext()" attrs="486">\r
+ <size>250</size>\r
+ </method>\r
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">\r
+ <size>13</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
if (CheckProcessed (assembly))
return;
+ ProcessModule (assembly);
+
MarkCustomAttributes (assembly);
foreach (ModuleDefinition module in assembly.Modules)
MarkCustomAttributes (module);
}
+ void ProcessModule (AssemblyDefinition assembly)
+ {
+ // Pre-mark <Module> if there is any methods as they need to be executed
+ // at assembly load time
+ foreach (TypeDefinition type in assembly.MainModule.Types)
+ {
+ if (type.Name == "<Module>" && type.HasMethods)
+ {
+ MarkType (type);
+ break;
+ }
+ }
+ }
+
protected void MarkField (FieldReference reference)
{
// if (IgnoreScope (reference.DeclaringType.Scope))
case "mscorlib":
case "Accessibility":
case "Mono.Security":
+ // WPF
+ case "PresentationFramework":
+ case "PresentationCore":
+ case "WindowsBase":
+ case "UIAutomationProvider":
+ case "UIAutomationTypes":
+ case "PresentationUI":
+ case "ReachFramework":
return true;
default:
return name.Name.StartsWith ("System")
#include <sys/stat.h>
#include <unistd.h>
-
-/* Disclaimers */
-
-#if defined(__GNUC__)
-#ifndef HAVE_GETRESUID
- #warning getresuid not supported. WindowsImpersonationContext wont work
-#endif
-#ifndef HAVE_SETRESUID
- #warning setresuid not supported. WindowsImpersonationContext wont work
-#endif
-#endif
-
-
gboolean
ImpersonateLoggedOnUser (gpointer handle)
{
verify.c \
verify-internals.h \
wrapper-types.h \
- reflection-internals.h
+ reflection-internals.h \
+ file-mmap-posix.c \
+ file-mmap-windows.c \
+ file-mmap.h
+
# These source files have compile time dependencies on GC code
gc_dependent_sources = \
mono_gc_pthread_exit (void *retval)
{
pthread_exit (retval);
+ g_assert_not_reached ();
}
#endif
--- /dev/null
+/*
+ * file-mmap-posix.c: File mmap internal calls
+ *
+ * Author:
+ * Rodrigo Kumpera
+ *
+ * Copyright 2014 Xamarin Inc (http://www.xamarin.com)
+ */
+
+#include <config.h>
+
+#ifndef TARGET_WIN32
+
+#include <glib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#include <fcntl.h>
+
+
+#include <mono/metadata/object.h>
+#include <mono/metadata/file-io.h>
+#include <mono/metadata/file-mmap.h>
+#include <mono/utils/atomic.h>
+#include <mono/utils/mono-memory-model.h>
+#include <mono/utils/mono-mmap.h>
+
+enum {
+ MMAP_KIND_FILE = 1,
+ MMAP_KIND_MEMORY = 2
+};
+
+typedef struct {
+ int kind;
+ int ref_count;
+ gint64 capacity;
+ char *name;
+} Handle;
+
+typedef struct {
+ Handle handle;
+ int fd;
+} FileHandle;
+
+typedef struct {
+ Handle handle;
+ void *address;
+ size_t length;
+} MemoryHandle;
+
+typedef struct {
+ void *address;
+ void *free_handle;
+ int kind;
+ size_t length;
+} MmapHandle;
+
+enum {
+ BAD_CAPACITY_FOR_FILE_BACKED = 1,
+ CAPACITY_SMALLER_THAN_FILE_SIZE,
+ FILE_NOT_FOUND,
+ FILE_ALREADY_EXISTS,
+ PATH_TOO_LONG,
+ COULD_NOT_OPEN,
+ CAPACITY_MUST_BE_POSITIVE,
+ INVALID_FILE_MODE,
+ COULD_NOT_MAP_MEMORY
+};
+
+enum {
+ FILE_MODE_CREATE_NEW = 1,
+ FILE_MODE_CREATE = 2,
+ FILE_MODE_OPEN = 3,
+ FILE_MODE_OPEN_OR_CREATE = 4,
+ FILE_MODE_TRUNCATE = 5,
+ FILE_MODE_APPEND = 6,
+};
+
+enum {
+ MMAP_FILE_ACCESS_READ_WRITE = 0,
+ MMAP_FILE_ACCESS_READ = 1,
+ MMAP_FILE_ACCESS_WRITE = 2,
+ MMAP_FILE_ACCESS_COPY_ON_WRITE = 3,
+ MMAP_FILE_ACCESS_READ_EXECUTE = 4,
+ MMAP_FILE_ACCESS_READ_WRITE_EXECUTE = 5,
+};
+
+
+static int mmap_init_state;
+static mono_mutex_t named_regions_mutex;
+static GHashTable *named_regions;
+
+
+static gint64
+align_up_to_page_size (gint64 size)
+{
+ gint64 page_size = mono_pagesize ();
+ return (size + page_size - 1) & ~(page_size - 1);
+}
+
+static gint64
+align_down_to_page_size (gint64 size)
+{
+ gint64 page_size = mono_pagesize ();
+ return size & ~(page_size - 1);
+}
+
+static void
+file_mmap_init (void)
+{
+retry:
+ switch (mmap_init_state) {
+ case 0:
+ if (InterlockedCompareExchange (&mmap_init_state, 1, 0) != 0)
+ goto retry;
+ named_regions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+ mono_mutex_init (&named_regions_mutex);
+
+ mono_atomic_store_release (&mmap_init_state, 2);
+ break;
+
+ case 1:
+ do {
+ g_usleep (1000); /* Been init'd by other threads, this is very rare. */
+ } while (mmap_init_state != 2);
+ break;
+ case 2:
+ break;
+ default:
+ g_error ("Invalid init state %d", mmap_init_state);
+ }
+}
+
+static void
+named_regions_lock (void)
+{
+ file_mmap_init ();
+ mono_mutex_lock (&named_regions_mutex);
+}
+
+static void
+named_regions_unlock (void)
+{
+ mono_mutex_unlock (&named_regions_mutex);
+}
+
+
+static int
+file_mode_to_unix (int mode)
+{
+ switch (mode) {
+ case FILE_MODE_CREATE_NEW:
+ return O_CREAT | O_EXCL;
+ case FILE_MODE_CREATE:
+ return O_CREAT | O_TRUNC;
+ case FILE_MODE_OPEN:
+ return 0;
+ case FILE_MODE_OPEN_OR_CREATE:
+ return O_CREAT;
+ case FILE_MODE_TRUNCATE:
+ return O_TRUNC;
+ case FILE_MODE_APPEND:
+ return O_APPEND;
+ default:
+ g_error ("unknown FileMode %d", mode);
+ }
+}
+
+static int
+access_mode_to_unix (int access)
+{
+ switch (access) {
+ case MMAP_FILE_ACCESS_READ_WRITE:
+ case MMAP_FILE_ACCESS_COPY_ON_WRITE:
+ case MMAP_FILE_ACCESS_READ_WRITE_EXECUTE:
+ return O_RDWR;
+ case MMAP_FILE_ACCESS_READ:
+ case MMAP_FILE_ACCESS_READ_EXECUTE:
+ return O_RDONLY;
+ case MMAP_FILE_ACCESS_WRITE:
+ return O_WRONLY;
+ default:
+ g_error ("unknown MemoryMappedFileAccess %d", access);
+ }
+}
+
+static int
+acess_to_mmap_flags (int access)
+{
+ switch (access) {
+ case MMAP_FILE_ACCESS_READ_WRITE:
+ return MONO_MMAP_WRITE | MONO_MMAP_READ | MONO_MMAP_SHARED;
+
+ case MMAP_FILE_ACCESS_WRITE:
+ return MONO_MMAP_WRITE | MONO_MMAP_SHARED;
+
+ case MMAP_FILE_ACCESS_COPY_ON_WRITE:
+ return MONO_MMAP_WRITE | MONO_MMAP_READ | MONO_MMAP_PRIVATE;
+
+ case MMAP_FILE_ACCESS_READ_EXECUTE:
+ return MONO_MMAP_EXEC | MONO_MMAP_PRIVATE | MONO_MMAP_SHARED;
+
+ case MMAP_FILE_ACCESS_READ_WRITE_EXECUTE:
+ return MONO_MMAP_WRITE | MONO_MMAP_READ | MONO_MMAP_EXEC | MONO_MMAP_SHARED;
+
+ case MMAP_FILE_ACCESS_READ:
+ return MONO_MMAP_READ | MONO_MMAP_SHARED;
+ default:
+ g_error ("unknown MemoryMappedFileAccess %d", access);
+ }
+}
+
+/*
+XXX implement options
+*/
+static void*
+open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int access, int options, int *error)
+{
+ struct stat buf;
+ char *c_path = path ? mono_string_to_utf8 (path) : NULL;
+ FileHandle *handle = NULL;
+ int result, fd;
+
+ if (path)
+ result = stat (c_path, &buf);
+ else
+ result = fstat (input_fd, &buf);
+
+ if (mode == FILE_MODE_TRUNCATE || mode == FILE_MODE_APPEND || mode == FILE_MODE_OPEN) {
+ if (result == -1) { //XXX translate errno?
+ *error = FILE_NOT_FOUND;
+ goto done;
+ }
+ }
+
+ if (mode == FILE_MODE_CREATE_NEW && result == 0) {
+ *error = FILE_ALREADY_EXISTS;
+ goto done;
+ }
+
+ if (result == 0) {
+ if (*capacity == 0) {
+ /**
+ * Special files such as FIFOs, sockets, and devices can have a size of 0. Specifying a capacity for these
+ * also makes little sense, so don't do the check if th file is one of these.
+ */
+ if (buf.st_size == 0 && (buf.st_mode & (S_IFCHR | S_IFBLK | S_IFIFO | S_IFSOCK)) == 0) {
+ *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+ goto done;
+ }
+ *capacity = buf.st_size;
+ } else if (*capacity < buf.st_size) {
+ *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+ goto done;
+ }
+ } else {
+ if (mode == FILE_MODE_CREATE_NEW && *capacity == 0) {
+ *error = CAPACITY_SMALLER_THAN_FILE_SIZE;
+ goto done;
+ }
+ }
+
+ if (path) //FIXME use io portability?
+ fd = open (c_path, file_mode_to_unix (mode) | access_mode_to_unix (access), DEFFILEMODE);
+ else
+ fd = dup (input_fd);
+
+ if (fd == -1) { //XXX translate errno?
+ *error = COULD_NOT_OPEN;
+ goto done;
+ }
+
+ *capacity = align_up_to_page_size ((size_t)*capacity);
+
+ if (*capacity > buf.st_size)
+ ftruncate (fd, (off_t)*capacity);
+
+ handle = g_new0 (FileHandle, 1);
+ handle->handle.kind = MMAP_KIND_FILE;
+ handle->handle.ref_count = 1;
+ handle->handle.capacity = *capacity;
+ handle->fd = fd;
+
+done:
+ g_free (c_path);
+ return (void*)handle;
+}
+
+static void*
+open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, int options, int *error)
+{
+ char *c_mapName;
+ MemoryHandle *handle;
+ if (*capacity <= 1) {
+ *error = CAPACITY_MUST_BE_POSITIVE;
+ return NULL;
+ }
+
+ if (!(mode == FILE_MODE_CREATE_NEW || mode == FILE_MODE_OPEN_OR_CREATE || mode == FILE_MODE_OPEN)) {
+ *error = INVALID_FILE_MODE;
+ return NULL;
+ }
+
+ c_mapName = mono_string_to_utf8 (mapName);
+
+ named_regions_lock ();
+ handle = (MemoryHandle*)g_hash_table_lookup (named_regions, c_mapName);
+ if (handle) {
+ if (mode == FILE_MODE_CREATE_NEW)
+ *error = FILE_ALREADY_EXISTS;
+
+ handle->handle.ref_count++;
+ //XXX should we ftruncate if the file is smaller than capacity?
+ } else {
+ if (mode == FILE_MODE_OPEN)
+ *error = FILE_NOT_FOUND;
+
+ *capacity = align_up_to_page_size (*capacity);
+
+ handle = g_new0 (MemoryHandle, 1);
+ handle->handle.kind = MMAP_KIND_MEMORY;
+ handle->handle.ref_count = 1;
+ handle->handle.capacity = *capacity;
+ handle->handle.name = g_strdup (c_mapName);
+
+ //FIXME compute RWX from access
+ handle->address = mono_valloc (NULL, (size_t)*capacity, MONO_MMAP_READ | MONO_MMAP_WRITE | MONO_MMAP_PRIVATE | MONO_MMAP_ANON);
+ handle->length = (size_t)*capacity;
+ g_hash_table_insert (named_regions, handle->handle.name, handle);
+ }
+
+ named_regions_unlock ();
+
+ g_free (c_mapName);
+ return handle;
+}
+
+
+void *
+mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+{
+ g_assert (path || mapName);
+
+ if (!mapName)
+ return open_file_map (path, -1, mode, capacity, access, options, error);
+
+ if (path) {
+ FileHandle *file_handle;
+ char *c_mapName = mono_string_to_utf8 (mapName);
+
+ named_regions_lock ();
+ file_handle = (FileHandle*)g_hash_table_lookup (named_regions, c_mapName);
+ if (file_handle) {
+ *error = FILE_ALREADY_EXISTS;
+ file_handle = NULL;
+ } else {
+ file_handle = open_file_map (path, -1, mode, capacity, access, options, error);
+ if (file_handle) {
+ file_handle->handle.name = g_strdup (c_mapName);
+ g_hash_table_insert (named_regions, file_handle->handle.name, file_handle);
+ }
+ }
+ named_regions_unlock ();
+
+ g_free (c_mapName);
+ return file_handle;
+ }
+
+ return open_memory_map (mapName, mode, capacity, access, options, error);
+}
+
+void *
+mono_mmap_open_handle (void *handle, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+{
+ FileHandle *file_handle;
+ char *c_mapName = mono_string_to_utf8 (mapName);
+
+ named_regions_lock ();
+ file_handle = (FileHandle*)g_hash_table_lookup (named_regions, c_mapName);
+ if (file_handle) {
+ *error = FILE_ALREADY_EXISTS;
+ file_handle = NULL;
+ } else {
+ //XXX we're exploiting wapi HANDLE == FD equivalence. THIS IS FRAGILE, create a _wapi_handle_to_fd call
+ file_handle = open_file_map (NULL, GPOINTER_TO_INT (handle), FILE_MODE_OPEN, capacity, access, options, error);
+ file_handle->handle.name = g_strdup (c_mapName);
+ g_hash_table_insert (named_regions, file_handle->handle.name, file_handle);
+ }
+ named_regions_unlock ();
+
+ g_free (c_mapName);
+ return file_handle;
+}
+
+void
+mono_mmap_close (void *mmap_handle)
+{
+ Handle *handle = mmap_handle;
+
+ named_regions_lock ();
+ --handle->ref_count;
+ if (handle->ref_count == 0) {
+ if (handle->name)
+ g_hash_table_remove (named_regions, handle->name);
+
+ g_free (handle->name);
+ if (handle->kind == MMAP_KIND_MEMORY)
+ mono_vfree (((MemoryHandle*)handle)->address, ((MemoryHandle*)handle)->length);
+ else
+ close (((FileHandle*)handle)->fd);
+ g_free (handle);
+ }
+ named_regions_unlock ();
+}
+
+void
+mono_mmap_configure_inheritability (void *mmap_handle, gboolean inheritability)
+{
+ FileHandle *h = mmap_handle;
+ int fd, flags;
+
+ if (h->handle.kind != MMAP_KIND_FILE)
+ return;
+
+ fd = h->fd;
+ flags = fcntl (fd, F_GETFD, 0);
+ if (inheritability)
+ flags &= ~FD_CLOEXEC;
+ else
+ flags |= FD_CLOEXEC;
+ fcntl (fd, F_SETFD, flags);
+}
+
+void
+mono_mmap_flush (void *mmap_handle)
+{
+ MmapHandle *h = mmap_handle;
+
+ if (h)
+ msync (h->address, h->length, MS_SYNC);
+}
+
+int
+mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mmap_handle, void **base_address)
+{
+ gint64 mmap_offset = 0;
+ Handle *h = handle;
+ MmapHandle res = { 0 };
+ if (h->kind == MMAP_KIND_FILE) {
+ FileHandle *fh = (FileHandle*)h;
+ size_t eff_size = *size;
+ struct stat buf = { 0 };
+ fstat (fh->fd, &buf); //FIXME error handling
+
+ if (eff_size == 0 || eff_size > buf.st_size)
+ eff_size = buf.st_size;
+ *size = eff_size;
+
+ mmap_offset = align_down_to_page_size (offset);
+ eff_size += (offset - mmap_offset);
+ //FIXME translate some interesting errno values
+ res.address = mono_file_map ((size_t)eff_size, acess_to_mmap_flags (access), fh->fd, mmap_offset, &res.free_handle);
+ res.length = eff_size;
+ res.kind = MMAP_KIND_FILE;
+
+ } else {
+ MemoryHandle *mh = (MemoryHandle*)h;
+ size_t eff_size = *size;
+
+ if (!eff_size)
+ eff_size = *size = mh->length;
+ mmap_offset = (size_t)mmap_offset;
+ res.address = (char*)mh->address + offset;
+ res.length = (size_t)size;
+ res.kind = MMAP_KIND_MEMORY;
+ }
+
+ if (res.address) {
+ *mmap_handle = g_memdup (&res, sizeof (MmapHandle));
+ *base_address = (char*)res.address + (offset - mmap_offset);
+ return 0;
+ }
+
+ *mmap_handle = NULL;
+ *base_address = NULL;
+ return COULD_NOT_MAP_MEMORY;
+}
+
+gboolean
+mono_mmap_unmap (void *mmap_handle)
+{
+ int res = 0;
+ MmapHandle *h = mmap_handle;
+
+ if (h->kind == MMAP_KIND_FILE)
+ res = mono_file_unmap (h->address, h->free_handle);
+
+ g_free (h);
+ return res == 0;
+}
+
+#endif
--- /dev/null
+/*
+ * file-mmap-posix.c: File mmap internal calls
+ *
+ * Author:
+ * Rodrigo Kumpera
+ *
+ * Copyright 2014 Xamarin Inc (http://www.xamarin.com)
+ */
+
+#include <config.h>
+
+#ifdef TARGET_WIN32
+
+#include <glib.h>
+#include <string.h>
+#include <errno.h>
+
+
+#include <mono/metadata/object.h>
+#include <mono/metadata/file-mmap.h>
+
+void *
+mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+{
+ g_error ("No windows backend");
+ return NULL;
+}
+
+void *
+mono_mmap_open_handle (void *handle, MonoString *mapName, gint64 *capacity, int access, int options, int *error)
+{
+ g_error ("No windows backend");
+ return NULL;
+}
+
+void
+mono_mmap_close (void *mmap_handle)
+{
+ g_error ("No windows backend");
+}
+
+void
+mono_mmap_configure_inheritability (void *mmap_handle, gboolean inheritability)
+{
+ g_error ("No windows backend");
+}
+
+void
+mono_mmap_flush (void *mmap_handle)
+{
+ g_error ("No windows backend");
+}
+
+
+
+int
+mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mmap_handle, void **base_address)
+{
+ g_error ("No windows backend");
+ return 0;
+}
+
+gboolean
+mono_mmap_unmap (void *mmap_handle)
+{
+ g_error ("No windows backend");
+ return TRUE;
+}
+
+#endif
--- /dev/null
+/*
+ * file-mmap.h: Managed mmap wrappers.
+ *
+ * Authors:
+ * Rodrigo Kumpera
+ *
+ * Copyright 2014 Xamarin Inc (http://www.xamarin.com)
+ */
+
+#ifndef _MONO_METADATA_FILE_MMAP_H_
+#define _MONO_METADATA_FILE_MMAP_H_
+
+#include <config.h>
+#include <glib.h>
+
+#include <mono/metadata/object-internals.h>
+#include <mono/io-layer/io-layer.h>
+#include <mono/utils/mono-compiler.h>
+
+extern void mono_mmap_close (void *mmap_handle) MONO_INTERNAL;
+
+extern void mono_mmap_configure_inheritability (void *mmap_handle, gboolean inheritability) MONO_INTERNAL;
+
+extern void mono_mmap_flush (void *mmap_handle) MONO_INTERNAL;
+
+extern void *mono_mmap_open_file (MonoString *string, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error) MONO_INTERNAL;
+
+extern void *mono_mmap_open_handle (void *handle, MonoString *mapName, gint64 *capacity, int access, int options, int *error) MONO_INTERNAL;
+
+extern int mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mmap_handle, void **base_address) MONO_INTERNAL;
+
+extern gboolean mono_mmap_unmap (void *base_address) MONO_INTERNAL;
+
+#endif /* _MONO_METADATA_FILE_MMAP_H_ */
ICALL(INOW_2, "GetInotifyInstance", ves_icall_System_IO_InotifyWatcher_GetInotifyInstance)
ICALL(INOW_3, "RemoveWatch", ves_icall_System_IO_InotifyWatcher_RemoveWatch)
-#if defined (TARGET_IOS) || defined (TARGET_ANDROID)
ICALL_TYPE(MMAPIMPL, "System.IO.MemoryMappedFiles.MemoryMapImpl", MMAPIMPL_1)
-ICALL(MMAPIMPL_1, "mono_filesize_from_fd", mono_filesize_from_fd)
-ICALL(MMAPIMPL_2, "mono_filesize_from_path", mono_filesize_from_path)
-#endif
-
+ICALL(MMAPIMPL_1, "CloseMapping", mono_mmap_close)
+ICALL(MMAPIMPL_2, "ConfigureHandleInheritability", mono_mmap_configure_inheritability)
+ICALL(MMAPIMPL_3, "Flush", mono_mmap_flush)
+ICALL(MMAPIMPL_4, "MapInternal", mono_mmap_map)
+ICALL(MMAPIMPL_5, "OpenFileInternal", mono_mmap_open_file)
+ICALL(MMAPIMPL_6, "OpenHandleInternal", mono_mmap_open_handle)
+ICALL(MMAPIMPL_7, "Unmap", mono_mmap_unmap)
ICALL_TYPE(MONOIO, "System.IO.MonoIO", MONOIO_1)
ICALL(MONOIO_1, "Close(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Close)
#include <mono/metadata/mono-ptr-array.h>
#include <mono/metadata/verify-internals.h>
#include <mono/metadata/runtime.h>
+#include <mono/metadata/file-mmap.h>
#include <mono/io-layer/io-layer.h>
#include <mono/utils/strtod.h>
#include <mono/utils/monobitset.h>
{
mono_thread_info_detach ();
pthread_exit (retval);
+ g_assert_not_reached ();
}
#endif /* USE_PTHREAD_INTERCEPT */
/*frag->next read must happen before the first CAS*/
mono_memory_write_barrier ();
- /*Fail if the next done is removed concurrently and its CAS wins */
+ /*Fail if the next node is removed concurrently and its CAS wins */
if (InterlockedCompareExchangePointer ((volatile gpointer*)&frag->next, mask (next, 1), next) != next) {
continue;
}
mono_memory_write_barrier ();
/* Fail if the previous node was deleted and its CAS wins */
- if (InterlockedCompareExchangePointer ((volatile gpointer*)prev_ptr, next, frag) != frag) {
+ if (InterlockedCompareExchangePointer ((volatile gpointer*)prev_ptr, unmask (next), frag) != frag) {
prev_ptr = find_previous_pointer_fragment (allocator, frag);
continue;
}
iconst: dest:i len:5
r4const: dest:f len:15
r8const: dest:f len:16
-store_membase_imm: dest:b len:10
+store_membase_imm: dest:b len:11
store_membase_reg: dest:b src1:i len:7
storei1_membase_imm: dest:b len:10
storei1_membase_reg: dest:b src1:y len:7
LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter;
void *mono_win_vectored_exception_handle;
-extern gboolean mono_win_chained_exception_needs_run;
#define W32_SEH_HANDLE_EX(_ex) \
if (_ex##_handler) _ex##_handler(0, ep, sctx)
CONTEXT* ctx;
MonoContext* sctx;
LONG res;
+ MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+
+ /* If the thread is not managed by the runtime return early */
+ if (!jit_tls)
+ return EXCEPTION_CONTINUE_SEARCH;
- mono_win_chained_exception_needs_run = FALSE;
+ jit_tls->mono_win_chained_exception_needs_run = FALSE;
res = EXCEPTION_CONTINUE_EXECUTION;
er = ep->ExceptionRecord;
W32_SEH_HANDLE_EX(fpe);
break;
default:
+ jit_tls->mono_win_chained_exception_needs_run = TRUE;
break;
}
- if (mono_win_chained_exception_needs_run) {
+ if (jit_tls->mono_win_chained_exception_needs_run) {
/* Don't copy context back if we chained exception
* as the handler may have modfied the EXCEPTION_POINTERS
* directly. We don't pass sigcontext to chained handlers.
LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter;
gpointer mono_win_vectored_exception_handle;
-extern gboolean mono_win_chained_exception_needs_run;
extern int (*gUnhandledExceptionHandler)(EXCEPTION_POINTERS*);
#ifndef PROCESS_CALLBACK_FILTER_ENABLED
CONTEXT* ctx;
struct sigcontext* sctx;
LONG res;
+ MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+
+ /* If the thread is not managed by the runtime return early */
+ if (!jit_tls)
+ return EXCEPTION_CONTINUE_SEARCH;
- mono_win_chained_exception_needs_run = FALSE;
+ jit_tls->mono_win_chained_exception_needs_run = FALSE;
res = EXCEPTION_CONTINUE_EXECUTION;
er = ep->ExceptionRecord;
W32_SEH_HANDLE_EX(fpe);
break;
default:
+ jit_tls->mono_win_chained_exception_needs_run = TRUE;
break;
}
- if (mono_win_chained_exception_needs_run) {
+ if (jit_tls->mono_win_chained_exception_needs_run) {
/* Don't copy context back if we chained exception
* as the handler may have modfied the EXCEPTION_POINTERS
* directly. We don't pass sigcontext to chained handlers.
*lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3);
}
+#ifndef MONO_X86_NO_PUSHES
/* Pop arguments off the stack */
if (ji->has_arch_eh_info) {
int stack_size;
#endif
}
}
+#endif
return TRUE;
} else if (*lmf) {
/* Set method field */
method_ins = emit_get_rgctx_method (cfg, context_used, method, MONO_RGCTX_INFO_METHOD);
MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, obj->dreg, G_STRUCT_OFFSET (MonoDelegate, method), method_ins->dreg);
- if (cfg->gen_write_barriers) {
- dreg = alloc_preg (cfg);
- EMIT_NEW_BIALU_IMM (cfg, ptr, OP_PADD_IMM, dreg, obj->dreg, G_STRUCT_OFFSET (MonoDelegate, method));
- emit_write_barrier (cfg, ptr, method_ins);
- }
/*
* To avoid looking up the compiled code belonging to the target method
* in mono_delegate_trampoline (), we allocate a per-domain memory slot to
EMIT_NEW_ARGLOAD (cfg, call->args [i], i);
mono_arch_emit_call (cfg, call);
+ cfg->param_area = MAX(cfg->param_area, call->stack_usage);
MONO_ADD_INS (bblock, (MonoInst*)call);
} else {
for (i = 0; i < num_args; ++i)
ARM_CMP_REG_IMM (code, tmpreg, 0, 0);
buf [2] = code;
ARM_B_COND (code, ARMCOND_NE, 0);
- arm_patch (buf [2], buf [1]);
+ arm_patch (buf [2], buf [0]);
arm_patch (buf [1], code);
break;
case OP_ATOMIC_ADD_NEW_I4:
* reproduceable results for benchmarks */
#define MONO_ARCH_CODE_ALIGNMENT 32
+/* Argument marshallings for calls between gsharedvt and normal code */
+typedef enum {
+ GSHAREDVT_ARG_NONE = 0,
+ GSHAREDVT_ARG_BYVAL_TO_BYREF = 1,
+ GSHAREDVT_ARG_BYREF_TO_BYVAL = 2,
+ GSHAREDVT_ARG_BYREF_TO_BYVAL_I1 = 3,
+ GSHAREDVT_ARG_BYREF_TO_BYVAL_I2 = 4,
+ GSHAREDVT_ARG_BYREF_TO_BYVAL_U1 = 5,
+ GSHAREDVT_ARG_BYREF_TO_BYVAL_U2 = 6
+} GSharedVtArgMarshal;
+
/* Return value marshalling for calls between gsharedvt and normal code */
typedef enum {
GSHAREDVT_RET_NONE = 0,
#elif defined(TARGET_X86)
/* The offset is computed from the sp at the start of the call sequence */
g_assert (cfg->frame_reg == X86_EBP);
+#ifdef MONO_X86_NO_PUSHES
+ return (- cfg->arch.sp_fp_offset + sp_offset);
+#else
return (- cfg->arch.sp_fp_offset - sp_offset);
+#endif
#else
NOT_IMPLEMENTED;
return -1;
#ifdef TARGET_AMD64
min_offset = MIN (min_offset, -cfg->arch.sp_fp_offset);
#elif defined(TARGET_X86)
+#ifdef MONO_X86_NO_PUSHES
+ min_offset = MIN (min_offset, -cfg->arch.sp_fp_offset);
+#else
min_offset = MIN (min_offset, - (cfg->arch.sp_fp_offset + cfg->arch.param_area_size));
+#endif
#elif defined(TARGET_ARM)
// FIXME:
#elif defined(TARGET_s390X)
#include "jit-icalls.h"
-gboolean mono_win_chained_exception_needs_run;
-
void
mono_runtime_install_handlers (void)
{
gboolean
SIG_HANDLER_SIGNATURE (mono_chain_signal)
{
- mono_win_chained_exception_needs_run = TRUE;
+ MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+ jit_tls->mono_win_chained_exception_needs_run = TRUE;
return TRUE;
}
/* The index of the vret arg in the argument list */
int vret_arg_index;
int vret_arg_offset;
+ /* Argument space popped by the callee */
+ int callee_stack_pop;
ArgInfo ret;
ArgInfo sig_cookie;
ArgInfo args [1];
stack_size += cinfo->stack_align_amount;
}
+ if (cinfo->vtype_retaddr) {
+ /* if the function returns a struct on stack, the called method already does a ret $0x4 */
+ cinfo->callee_stack_pop = 4;
+ }
+
cinfo->stack_usage = stack_size;
cinfo->reg_usage = gr;
cinfo->freg_usage = fr;
cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
}
+#ifdef MONO_X86_NO_PUSHES
+ cfg->arch.no_pushes = TRUE;
+#endif
+
if (cfg->method->save_lmf) {
cfg->create_lmf_var = TRUE;
cfg->lmf_ir = TRUE;
if (cfg->compile_aot) {
sig_reg = mono_alloc_ireg (cfg);
MONO_EMIT_NEW_SIGNATURECONST (cfg, sig_reg, tmp_sig);
- MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, sig_reg);
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, cinfo->sig_cookie.offset, sig_reg);
+ } else {
+ MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, sig_reg);
+ }
} else {
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig);
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, X86_ESP, cinfo->sig_cookie.offset, tmp_sig);
+ } else {
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig);
+ }
}
}
if (cfg->compute_gc_maps) {
MonoInst *def;
+ /* Needs checking if the feature will be enabled again */
+ g_assert (!cfg->arch.no_pushes);
+
/* On x86, the offsets are from the sp value before the start of the call sequence */
if (t == NULL)
t = &mono_defaults.int_class->byval_arg;
sig_ret = mini_replace_type (sig->ret);
cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+ call->call_info = cinfo;
if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG))
sentinelpos = sig->sentinelpos + (sig->hasthis ? 1 : 0);
- if (cinfo->need_stack_align) {
+ if (cinfo->need_stack_align && !cfg->arch.no_pushes) {
MONO_INST_NEW (cfg, arg, OP_SUB_IMM);
arg->dreg = X86_ESP;
arg->sreg1 = X86_ESP;
/* Handle the case where there are no implicit arguments */
if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sentinelpos)) {
emit_sig_cookie (cfg, call, cinfo);
- sp_offset += 4;
+ sp_offset = (cfg->arch.no_pushes) ? cinfo->sig_cookie.offset : (sp_offset + 4);
emit_gc_param_slot_def (cfg, sp_offset, NULL);
}
int argsize;
if (cinfo->vtype_retaddr && cinfo->vret_arg_index == 1 && i == 0) {
- /* Push the vret arg before the first argument */
MonoInst *vtarg;
- MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH);
- vtarg->type = STACK_MP;
- vtarg->sreg1 = call->vret_var->dreg;
- MONO_ADD_INS (cfg->cbb, vtarg);
- sp_offset += 4;
+ /* Push the vret arg before the first argument */
+ if (cfg->arch.no_pushes) {
+ MONO_INST_NEW (cfg, vtarg, OP_STORE_MEMBASE_REG);
+ vtarg->type = STACK_MP;
+ vtarg->inst_destbasereg = X86_ESP;
+ vtarg->sreg1 = call->vret_var->dreg;
+ vtarg->inst_offset = cinfo->ret.offset;
+ MONO_ADD_INS (cfg->cbb, vtarg);
+ sp_offset = cinfo->ret.offset;
+ } else {
+ MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH);
+ vtarg->type = STACK_MP;
+ vtarg->sreg1 = call->vret_var->dreg;
+ MONO_ADD_INS (cfg->cbb, vtarg);
+ sp_offset += 4;
+ }
emit_gc_param_slot_def (cfg, sp_offset, NULL);
}
MONO_ADD_INS (cfg->cbb, arg);
if (ainfo->storage != ArgValuetypeInReg) {
- sp_offset += size;
+ sp_offset = (cfg->arch.no_pushes) ? ainfo->offset : (sp_offset + size);
emit_gc_param_slot_def (cfg, sp_offset, orig_type);
}
}
} else {
- argsize = 4;
-
switch (ainfo->storage) {
case ArgOnStack:
- arg->opcode = OP_X86_PUSH;
if (!t->byref) {
if (t->type == MONO_TYPE_R4) {
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 4);
- arg->opcode = OP_STORER4_MEMBASE_REG;
- arg->inst_destbasereg = X86_ESP;
- arg->inst_offset = 0;
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg);
+ } else {
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 4);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, X86_ESP, 0, in->dreg);
+ }
argsize = 4;
} else if (t->type == MONO_TYPE_R8) {
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 8);
- arg->opcode = OP_STORER8_MEMBASE_REG;
- arg->inst_destbasereg = X86_ESP;
- arg->inst_offset = 0;
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg);
+ } else {
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 8);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, X86_ESP, 0, in->dreg);
+ }
argsize = 8;
} else if (t->type == MONO_TYPE_I8 || t->type == MONO_TYPE_U8) {
- arg->sreg1 ++;
- MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, in->dreg + 2);
- sp_offset += 4;
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset + 4, in->dreg + 2);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg + 1);
+ } else {
+ MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, in->dreg + 2);
+ MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, in->dreg + 1);
+ sp_offset += 4;
+ }
+ argsize = 4;
+ } else {
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg);
+ } else {
+ arg->opcode = OP_X86_PUSH;
+ MONO_ADD_INS (cfg->cbb, arg);
+ }
+ argsize = 4;
}
+ } else {
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg);
+ } else {
+ arg->opcode = OP_X86_PUSH;
+ MONO_ADD_INS (cfg->cbb, arg);
+ }
+ argsize = 4;
}
break;
case ArgInIReg:
arg->opcode = OP_MOVE;
arg->dreg = ainfo->reg;
+ MONO_ADD_INS (cfg->cbb, arg);
argsize = 0;
break;
default:
g_assert_not_reached ();
}
-
- MONO_ADD_INS (cfg->cbb, arg);
- sp_offset += argsize;
+ sp_offset = (cfg->arch.no_pushes) ? ainfo->offset : (sp_offset + argsize);
if (cfg->compute_gc_maps) {
if (argsize == 4) {
}
} else {
/* i8/r8 */
- for (j = 0; j < argsize; j += 4)
- emit_gc_param_slot_def (cfg, sp_offset - j, NULL);
+ for (j = 0; j < argsize; j += 4) {
+ if (cfg->arch.no_pushes)
+ emit_gc_param_slot_def (cfg, sp_offset + j, NULL);
+ else
+ emit_gc_param_slot_def (cfg, sp_offset - j, NULL);
+ }
}
}
}
if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (i == sentinelpos)) {
/* Emit the signature cookie just before the implicit arguments */
emit_sig_cookie (cfg, call, cinfo);
- sp_offset += 4;
+ sp_offset = (cfg->arch.no_pushes) ? cinfo->sig_cookie.offset : (sp_offset + 4);
emit_gc_param_slot_def (cfg, sp_offset, NULL);
}
}
mono_call_inst_add_outarg_reg (cfg, call, vtarg->dreg, cinfo->ret.reg, FALSE);
} else if (cinfo->vtype_retaddr && cinfo->vret_arg_index == 0) {
- MonoInst *vtarg;
- MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH);
- vtarg->type = STACK_MP;
- vtarg->sreg1 = call->vret_var->dreg;
- MONO_ADD_INS (cfg->cbb, vtarg);
- sp_offset += 4;
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, cinfo->ret.offset, call->vret_var->dreg);
+ sp_offset = cinfo->ret.offset;
+ } else {
+ MonoInst *vtarg;
+ MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH);
+ vtarg->type = STACK_MP;
+ vtarg->sreg1 = call->vret_var->dreg;
+ MONO_ADD_INS (cfg->cbb, vtarg);
+ sp_offset += 4;
+ }
emit_gc_param_slot_def (cfg, sp_offset, NULL);
}
/* if the function returns a struct on stack, the called method already does a ret $0x4 */
- if (cinfo->ret.storage != ArgValuetypeInReg)
- cinfo->stack_usage -= 4;
+ if (!cfg->arch.no_pushes)
+ cinfo->stack_usage -= cinfo->callee_stack_pop;
}
call->stack_usage = cinfo->stack_usage;
call->stack_align_amount = cinfo->stack_align_amount;
- cfg->arch.param_area_size = MAX (cfg->arch.param_area_size, sp_offset);
+ if (!cfg->arch.no_pushes)
+ cfg->arch.param_area_size = MAX (cfg->arch.param_area_size, sp_offset);
}
void
else {
if (cfg->gsharedvt && mini_is_gsharedvt_klass (cfg, ins->klass)) {
/* Pass by addr */
- MONO_INST_NEW (cfg, arg, OP_X86_PUSH);
- arg->sreg1 = src->dreg;
- MONO_ADD_INS (cfg->cbb, arg);
+ if (cfg->arch.no_pushes) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, src->dreg);
+ } else {
+ MONO_INST_NEW (cfg, arg, OP_X86_PUSH);
+ arg->sreg1 = src->dreg;
+ MONO_ADD_INS (cfg->cbb, arg);
+ }
} else if (size <= 4) {
- MONO_INST_NEW (cfg, arg, OP_X86_PUSH_MEMBASE);
- arg->sreg1 = src->dreg;
-
- MONO_ADD_INS (cfg->cbb, arg);
- } else if (size <= 20) {
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, ALIGN_TO (size, 4));
- mini_emit_memcpy (cfg, X86_ESP, 0, src->dreg, 0, size, 4);
+ if (cfg->arch.no_pushes) {
+ int dreg = mono_alloc_ireg (cfg);
+ MONO_EMIT_NEW_LOAD_MEMBASE (cfg, dreg, src->dreg, 0);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, dreg);
+ } else {
+ MONO_INST_NEW (cfg, arg, OP_X86_PUSH_MEMBASE);
+ arg->sreg1 = src->dreg;
+ MONO_ADD_INS (cfg->cbb, arg);
+ }
+ } else if (size <= 20) {
+ if (cfg->arch.no_pushes) {
+ mini_emit_memcpy (cfg, X86_ESP, ainfo->offset, src->dreg, 0, size, 4);
+ } else {
+ MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, ALIGN_TO (size, 4));
+ mini_emit_memcpy (cfg, X86_ESP, 0, src->dreg, 0, size, 4);
+ }
} else {
- MONO_INST_NEW (cfg, arg, OP_X86_PUSH_OBJ);
- arg->inst_basereg = src->dreg;
- arg->inst_offset = 0;
- arg->inst_imm = size;
+ if (cfg->arch.no_pushes) {
+ // FIXME: Code growth
+ mini_emit_memcpy (cfg, X86_ESP, ainfo->offset, src->dreg, 0, size, 4);
+ } else {
+ MONO_INST_NEW (cfg, arg, OP_X86_PUSH_OBJ);
+ arg->inst_basereg = src->dreg;
+ arg->inst_offset = 0;
+ arg->inst_imm = size;
- MONO_ADD_INS (cfg->cbb, arg);
+ MONO_ADD_INS (cfg->cbb, arg);
+ }
}
}
}
}
static unsigned char*
-mono_emit_stack_alloc (guchar *code, MonoInst* tree)
+mono_emit_stack_alloc (MonoCompile *cfg, guchar *code, MonoInst* tree)
{
int sreg = tree->sreg1;
int need_touch = FALSE;
x86_push_reg (code, X86_EDI);
x86_mov_reg_imm (code, X86_ECX, (0x1000 >> 2));
x86_alu_reg_reg (code, X86_XOR, X86_EAX, X86_EAX);
- x86_lea_membase (code, X86_EDI, X86_ESP, 12);
+ if (cfg->param_area && cfg->arch.no_pushes)
+ x86_lea_membase (code, X86_EDI, X86_ESP, 12 + ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT));
+ else
+ x86_lea_membase (code, X86_EDI, X86_ESP, 12);
x86_cld (code);
x86_prefix (code, X86_REP_PREFIX);
x86_stosl (code);
x86_mov_reg_reg (code, X86_ECX, sreg, 4);
x86_alu_reg_reg (code, X86_XOR, X86_EAX, X86_EAX);
- x86_lea_membase (code, X86_EDI, X86_ESP, offset);
+ if (cfg->param_area && cfg->arch.no_pushes)
+ x86_lea_membase (code, X86_EDI, X86_ESP, offset + ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT));
+ else
+ x86_lea_membase (code, X86_EDI, X86_ESP, offset);
x86_cld (code);
x86_prefix (code, X86_REP_PREFIX);
x86_stosl (code);
case OP_VCALL2:
case OP_VOIDCALL:
case OP_CALL:
+ case OP_FCALL_REG:
+ case OP_LCALL_REG:
+ case OP_VCALL_REG:
+ case OP_VCALL2_REG:
+ case OP_VOIDCALL_REG:
+ case OP_CALL_REG:
+ case OP_FCALL_MEMBASE:
+ case OP_LCALL_MEMBASE:
+ case OP_VCALL_MEMBASE:
+ case OP_VCALL2_MEMBASE:
+ case OP_VOIDCALL_MEMBASE:
+ case OP_CALL_MEMBASE: {
+ CallInfo *cinfo;
+
call = (MonoCallInst*)ins;
- if (ins->flags & MONO_INST_HAS_METHOD)
- code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, call->method);
- else
- code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, call->fptr);
+ cinfo = (CallInfo*)call->call_info;
+
+ switch (ins->opcode) {
+ case OP_FCALL:
+ case OP_LCALL:
+ case OP_VCALL:
+ case OP_VCALL2:
+ case OP_VOIDCALL:
+ case OP_CALL:
+ if (ins->flags & MONO_INST_HAS_METHOD)
+ code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, call->method);
+ else
+ code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, call->fptr);
+ break;
+ case OP_FCALL_REG:
+ case OP_LCALL_REG:
+ case OP_VCALL_REG:
+ case OP_VCALL2_REG:
+ case OP_VOIDCALL_REG:
+ case OP_CALL_REG:
+ x86_call_reg (code, ins->sreg1);
+ break;
+ case OP_FCALL_MEMBASE:
+ case OP_LCALL_MEMBASE:
+ case OP_VCALL_MEMBASE:
+ case OP_VCALL2_MEMBASE:
+ case OP_VOIDCALL_MEMBASE:
+ case OP_CALL_MEMBASE:
+ x86_call_membase (code, ins->sreg1, ins->inst_offset);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
ins->flags |= MONO_INST_GC_CALLSITE;
ins->backend.pc_offset = code - cfg->native_code;
- if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature)) {
+ if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature) && !cfg->arch.no_pushes) {
/* a pop is one byte, while an add reg, imm is 3. So if there are 4 or 8
* bytes to pop, we want to use pops. GCC does this (note it won't happen
* for P4 or i686 because gcc will avoid using pop push at all. But we aren't
} else {
x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage);
}
+ } else if (cinfo->callee_stack_pop && cfg->arch.no_pushes) {
+ /* Have to compensate for the stack space popped by the callee */
+ x86_alu_reg_imm (code, X86_SUB, X86_ESP, cinfo->callee_stack_pop);
}
code = emit_move_return_value (cfg, ins, code);
break;
- case OP_FCALL_REG:
- case OP_LCALL_REG:
- case OP_VCALL_REG:
- case OP_VCALL2_REG:
- case OP_VOIDCALL_REG:
- case OP_CALL_REG:
- call = (MonoCallInst*)ins;
- x86_call_reg (code, ins->sreg1);
- ins->flags |= MONO_INST_GC_CALLSITE;
- ins->backend.pc_offset = code - cfg->native_code;
- if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature)) {
- if (call->stack_usage == 4)
- x86_pop_reg (code, X86_ECX);
- else
- x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage);
- }
- code = emit_move_return_value (cfg, ins, code);
- break;
- case OP_FCALL_MEMBASE:
- case OP_LCALL_MEMBASE:
- case OP_VCALL_MEMBASE:
- case OP_VCALL2_MEMBASE:
- case OP_VOIDCALL_MEMBASE:
- case OP_CALL_MEMBASE:
- call = (MonoCallInst*)ins;
-
- x86_call_membase (code, ins->sreg1, ins->inst_offset);
- ins->flags |= MONO_INST_GC_CALLSITE;
- ins->backend.pc_offset = code - cfg->native_code;
- if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature)) {
- if (call->stack_usage == 4)
- x86_pop_reg (code, X86_ECX);
- else
- x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage);
- }
- code = emit_move_return_value (cfg, ins, code);
- break;
+ }
case OP_X86_PUSH:
+ g_assert (!cfg->arch.no_pushes);
x86_push_reg (code, ins->sreg1);
break;
case OP_X86_PUSH_IMM:
+ g_assert (!cfg->arch.no_pushes);
x86_push_imm (code, ins->inst_imm);
break;
case OP_X86_PUSH_MEMBASE:
+ g_assert (!cfg->arch.no_pushes);
x86_push_membase (code, ins->inst_basereg, ins->inst_offset);
break;
case OP_X86_PUSH_OBJ:
+ g_assert (!cfg->arch.no_pushes);
x86_alu_reg_imm (code, X86_SUB, X86_ESP, ins->inst_imm);
x86_push_reg (code, X86_EDI);
x86_push_reg (code, X86_ESI);
/* keep alignment */
x86_alu_reg_imm (code, X86_ADD, ins->sreg1, MONO_ARCH_LOCALLOC_ALIGNMENT - 1);
x86_alu_reg_imm (code, X86_AND, ins->sreg1, ~(MONO_ARCH_LOCALLOC_ALIGNMENT - 1));
- code = mono_emit_stack_alloc (code, ins);
+ code = mono_emit_stack_alloc (cfg, code, ins);
x86_mov_reg_reg (code, ins->dreg, X86_ESP, 4);
+ if (cfg->param_area && cfg->arch.no_pushes)
+ x86_alu_reg_imm (code, X86_ADD, ins->dreg, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT));
break;
case OP_LOCALLOC_IMM: {
guint32 size = ins->inst_imm;
x86_mov_reg_imm (code, ins->dreg, size);
ins->sreg1 = ins->dreg;
- code = mono_emit_stack_alloc (code, ins);
+ code = mono_emit_stack_alloc (cfg, code, ins);
x86_mov_reg_reg (code, ins->dreg, X86_ESP, 4);
} else {
x86_alu_reg_imm (code, X86_SUB, X86_ESP, size);
x86_mov_reg_reg (code, ins->dreg, X86_ESP, 4);
}
+ if (cfg->param_area && cfg->arch.no_pushes)
+ x86_alu_reg_imm (code, X86_ADD, ins->dreg, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT));
break;
}
case OP_THROW: {
case OP_START_HANDLER: {
MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
x86_mov_membase_reg (code, spvar->inst_basereg, spvar->inst_offset, X86_ESP, 4);
+ if (cfg->param_area && cfg->arch.no_pushes) {
+ x86_alu_reg_imm (code, X86_SUB, X86_ESP, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT));
+ }
break;
}
case OP_ENDFINALLY: {
cfg->frame_reg = X86_ESP;
}
+ if (cfg->arch.no_pushes) {
+ cfg->stack_offset += cfg->param_area;
+ cfg->stack_offset = ALIGN_TO (cfg->stack_offset, MONO_ARCH_FRAME_ALIGNMENT);
+ }
+
alloc_size = cfg->stack_offset;
pos = 0;
MonoJitArgumentInfo *arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1));
stack_to_pop = mono_arch_get_argument_info (NULL, sig, sig->param_count, arg_info);
- } else if (cinfo->vtype_retaddr)
- stack_to_pop = 4;
+ } else if (cinfo->callee_stack_pop)
+ stack_to_pop = cinfo->callee_stack_pop;
else
stack_to_pop = 0;
#endif /* HAVE_WORKING_SIGALTSTACK */
#endif /* !HOST_WIN32 */
+/* #define MONO_X86_NO_PUSHES 1 */
+
#define MONO_ARCH_SUPPORT_TASKLETS 1
#ifndef DISABLE_SIMD
typedef struct {
gboolean need_stack_frame_inited;
gboolean need_stack_frame;
+ gboolean no_pushes;
int sp_fp_offset, param_area_size;
} MonoCompileArch;
guint8 *ip;
MonoCompile *cfg;
int dfn, i, code_size_ratio;
+#ifndef DISABLE_SSA
gboolean deadce_has_run = FALSE;
+#endif
gboolean try_generic_shared, try_llvm = FALSE;
MonoMethod *method_to_compile, *method_to_register;
gboolean method_is_gshared = FALSE;
*/
MonoContext orig_ex_ctx;
gboolean orig_ex_ctx_set;
+
+ /*
+ * Stores if we need to run a chained exception in Windows.
+ */
+ gboolean mono_win_chained_exception_needs_run;
} MonoJitTlsData;
/*
typedef struct {
FILE *file;
#if defined (HAVE_SYS_ZLIB)
- gzFile *gzfile;
+ gzFile gzfile;
#endif
unsigned char *buf;
int size;
#include <zlib.h>
#endif
-/* the architecture needs a memory fence */
-#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__) || defined(__arm__))
+#if defined(__linux__)
#include <unistd.h>
#include <sys/syscall.h>
#include "perf_event.h"
StatBuffer *stat_buffers;
FILE* file;
#if defined (HAVE_SYS_ZLIB)
- gzFile *gzfile;
+ gzFile gzfile;
#endif
uint64_t startup_time;
int pipe_output;
#include <glib.h>
#include <mono/utils/atomic.h>
+#include <mono/utils/mono-mutex.h>
#if defined (WAPI_NO_ATOMIC_ASM) || defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
#include <pthread.h>
-static pthread_mutex_t spin = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t spin G_GNUC_UNUSED = PTHREAD_MUTEX_INITIALIZER;
-#define NEED_64BIT_CMPXCHG_FALLBACK
-
-#endif
-
-#ifdef WAPI_NO_ATOMIC_ASM
-
-static mono_once_t spin_once=MONO_ONCE_INIT;
+static mono_once_t spin_once G_GNUC_UNUSED = MONO_ONCE_INIT;
static void spin_init(void)
{
g_warning("Using non-atomic functions! Expect race conditions when using process-shared handles!");
}
+#define NEED_64BIT_CMPXCHG_FALLBACK
+
+#endif
+
+#ifdef WAPI_NO_ATOMIC_ASM
+
gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch,
gint32 comp)
{
InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
{
gint64 old;
+ int ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ ret = pthread_mutex_lock(&spin);
+ g_assert (ret == 0);
+
+ old= *dest;
+ if(old==comp) {
+ *dest=exch;
+ }
+
+ ret = pthread_mutex_unlock(&spin);
+ g_assert (ret == 0);
+
+ pthread_cleanup_pop (0);
- pthread_mutex_lock (&spin);
-
- old = *dest;
- if(old == comp)
- *dest = exch;
-
- pthread_mutex_unlock (&spin);
- return old;
+ return(old);
}
#endif
continue;
/* The second CAS must happen before the first. */
mono_memory_write_barrier ();
- if (InterlockedCompareExchangePointer ((volatile gpointer*)prev, next, cur) == cur) {
+ if (InterlockedCompareExchangePointer ((volatile gpointer*)prev, mono_lls_pointer_unmask (next), cur) == cur) {
/* The CAS must happen before the hazard pointer clear. */
mono_memory_write_barrier ();
mono_hazard_pointer_clear (hp, 1);
}
#endif // HAVE_MMAP
+#if defined(HAVE_SHM_OPEN) && !defined (DISABLE_SHARED_PERFCOUNTERS)
+
static int use_shared_area;
static gboolean
return use_shared_area == -1;
}
-#if defined(HAVE_SHM_OPEN) && !defined (DISABLE_SHARED_PERFCOUNTERS)
-
static int
mono_shared_area_instances_slow (void **array, int count, gboolean cleanup)
{
}
#if HAVE_GETPWNAM_R
+int helper_Mono_Posix_getpwnamuid (int mode, char *in_name, int in_uid,
+ char **account,
+ char **password,
+ int *uid,
+ int *gid,
+ char **name,
+ char **home,
+ char **shell);
+
int helper_Mono_Posix_getpwnamuid (int mode, char *in_name, int in_uid,
char **account,
char **password,
ll->first_block = ll->last_block = NULL;
}
+/*
local void free_linkedlist(linkedlist_data *ll)
{
free_datablock(ll->first_block);
ll->first_block = ll->last_block = NULL;
}
-
+*/
local int add_data_in_datablock(linkedlist_data *ll, const void *buf, uLong len)
{
return func (hwndParent, hwndChildAfter, classw, window);
}
+int
+SetWindowPos (gpointer hwnd, gpointer hwndInsertAfter, int x, int y, int cx, int cy, unsigned int flags);
+
int
SetWindowPos (gpointer hwnd, gpointer hwndInsertAfter, int x, int y, int cx, int cy, unsigned int flags)
{
return 1;
}
+int
+SendMessageA (gpointer hwnd, unsigned int msg, gpointer wparam, gpointer lparam);
+
int
SendMessageA (gpointer hwnd, unsigned int msg, gpointer wparam, gpointer lparam)
{
return 0;
}
+int
+GetWindowLongA (gpointer hwnd, int a);
+
int
GetWindowLongA (gpointer hwnd, int a)
{
}
/* Remove this at some point in the future */
+gint32
+Mono_Posix_Syscall_utimes_bad (const char *filename,
+ struct Mono_Posix_Timeval *tv);
+
gint32
Mono_Posix_Syscall_utimes_bad (const char *filename,
struct Mono_Posix_Timeval *tv)
#endif
/* vararg version of syslog(3). */
+gint32
+Mono_Posix_Syscall_syslog2 (int priority, const char *format, ...);
+
gint32
Mono_Posix_Syscall_syslog2 (int priority, const char *format, ...)
{
: lstr_at(p, n) \
)
-char* MPH_INTERNAL
+char*
_mph_copy_structure_strings (
void *to, const mph_string_offset_t *to_offsets,
const void *from, const mph_string_offset_t *from_offsets,
static gint flush_internal (ZStream *stream, gboolean is_final);
static void *
-z_alloc (void *opaque, gsize nitems, gsize item_size)
+z_alloc (void *opaque, unsigned int nitems, unsigned int item_size)
{
return g_malloc0 (nitems * item_size);
}