[Rr]elease*/
Ankh.NoLoad
*.gpState
+.vscode/
# Tooling
_ReSharper*/
[submodule "external/nunit-lite"]
path = external/nunit-lite
url = git://github.com/mono/NUnitLite.git
+[submodule "external/nuget-buildtasks"]
+ path = external/nuget-buildtasks
+ url = git://github.com/mono/NuGet.BuildTasks
+[submodule "external/buildtools"]
+ path = external/buildtools
+ url = git://github.com/mono/buildtools.git
cd $(mcslib) && { (wget -O- $(monolite_url) || curl $(monolite_url)) | gzip -d | tar xf - ; }
cd $(mcslib) && mv -f monolite-* monolite
+if BITCODE
+BITCODE_CHECK=yes
+endif
+
.PHONY: check-ci
check-ci:
- MONO_LLVMONLY=$(MONO_LLVMONLY) $(srcdir)/scripts/ci/run-test-$(TEST_PROFILE).sh
+ MONO_LLVMONLY=$(BITCODE_CHECK) $(srcdir)/scripts/ci/run-test-$(TEST_PROFILE).sh
.PHONY: validate do-build-mono-mcs mcs-do-clean mcs-do-tests
validate: do-build-mono-mcs
sed -i -e 's/\\4.5-api"/\\4.5"/g' $$PREFIX/lib/mono/xbuild-frameworks/.NETFramework/v4.5/RedistList/FrameworkList.xml; \
export MSBuildExtensionsPath=$$PREFIX/lib/mono/xbuild; \
MONO_DOTNET_PORTABLE_DIR=$$PREFIX/lib/mono/xbuild-frameworks/.NETPortable/; \
- MONO_NUGET_TARGETS_DIR=$$PREFIX/lib/mono/xbuild/Microsoft/NuGet/; \
- MONO_PORTABLE_TARGETS_DIR=$$PREFIX/lib/mono/xbuild/Microsoft/Portable/v5.0; \
- if [ ! -d "$$MONO_DOTNET_PORTABLE_DIR/v5.0" ]; then \
+ if [ ! -d "$$MONO_DOTNET_PORTABLE_DIR/v4.6" ]; then \
mkdir -p $$MONO_DOTNET_PORTABLE_DIR; \
- mkdir -p $$MONO_NUGET_TARGETS_DIR; \
- mkdir -p $$MONO_PORTABLE_TARGETS_DIR; \
curl -SL "http://download.mono-project.com/third-party/RoslynBuildDependencies.zip" > /tmp/RoslynBuildDependencies.zip; \
unzip -o /tmp/RoslynBuildDependencies.zip -d /tmp/RoslynBuildDependencies; \
cp -r /tmp/RoslynBuildDependencies/PortableReferenceAssemblies/* $$MONO_DOTNET_PORTABLE_DIR; \
- cp /tmp/RoslynBuildDependencies/NuGetTargets/* $$MONO_NUGET_TARGETS_DIR; \
- cp /tmp/RoslynBuildDependencies/PortableTargets/* $$MONO_PORTABLE_TARGETS_DIR; \
fi; \
cd $(ROSLYN_PATH); \
sed -i -e 'N; s/bootstrapArg=".*\n.*"/bootstrapArg=""/g' cibuild.sh; \
.PHONY: validate-versions reset-versions
+SUBMODULES_CONFIG_FILE = $(top_srcdir)/acceptance-tests/SUBMODULES.json
include $(top_srcdir)/scripts/submodules/versions.mk
$(eval $(call ValidateVersionTemplate,roslyn,ROSLYN))
#AC_PREREQ([2.62])
# when bumping version number below, keep it in sync with man/mono.1 too
-AC_INIT(mono, [4.5.2],
+AC_INIT(mono, [4.7.0],
[http://bugzilla.xamarin.com/enter_bug.cgi?classification=Mono])
AC_CONFIG_SRCDIR([README.md])
AM_CONDITIONAL(PLATFORM_SIGPOSIX, test x$use_sigposix = xyes)
AM_CONDITIONAL(PLATFORM_ANDROID, test x$platform_android = xyes)
+if test -z "$PLATFORM_DARWIN_TRUE"; then :
+PLATFORM_AOT_SUFFIX=.dylib
+fi
+
+if test -z "$PLATFORM_LINUX_TRUE"; then :
+PLATFORM_AOT_SUFFIX=.so
+fi
+
+AC_SUBST(PLATFORM_AOT_SUFFIX)
+
+## PLATFORM_AOT_SUFFIX not so simple for windows :-)
+
AC_CHECK_TOOL(CC, gcc, gcc)
AC_PROG_CC
AC_CHECK_TOOL(CXX, g++, g++)
TEST_PROFILE=default
enable_llvm_default=no
+INVARIANT_AOT_OPTIONS=nimt-trampolines=900,ntrampolines=8000,nrgctx-fetch-trampolines=256,ngsharedvt-trampolines=2800
+
if test x$cross_compiling = xyes -o x$enable_mcs_build = xno; then
DISABLE_MCS_DOCS_default=yes
with_profile4_x_default=no
with_monotouch_watch_default=yes
with_monotouch_tv_default=yes
with_xammac_default=yes
- with_mobile_static_default=yes
+ with_mobile_static_default=no
with_bitcode_default=no
elif test x$with_runtime_preset = xmobile_static; then
DISABLE_MCS_DOCS_default=yes
with_bitcode_default=no
with_cooperative_gc_default=no
TEST_PROFILE=mobile_static
+
+ mono_feature_disable_com='yes'
+ mono_feature_disable_remoting='yes'
+ mono_feature_disable_reflection_emit_save='yes'
+ mono_feature_disable_reflection_emit='yes'
+ mono_feature_disable_appdomains='yes'
+
+ AOT_BUILD_FLAGS="-O=gsharedvt --aot=full,$INVARIANT_AOT_OPTIONS"
+ AOT_RUN_FLAGS="--full-aot"
elif test x$with_runtime_preset = xbitcode_mobile_static; then
DISABLE_MCS_DOCS_default=yes
with_profile4_x_default=no
with_cooperative_gc_default=yes
TEST_PROFILE=mobile_static
enable_llvm_default=yes
- MONO_LLVMONLY=yes
+
+ mono_feature_disable_com='yes'
+ mono_feature_disable_remoting='yes'
+ mono_feature_disable_reflection_emit_save='yes'
+ mono_feature_disable_reflection_emit='yes'
+ mono_feature_disable_appdomains='yes'
+
+ AOT_BUILD_FLAGS="--aot=llvmonly,$INVARIANT_AOT_OPTIONS"
+ AOT_RUN_FLAGS="--llvmonly"
else
with_profile4_x_default=yes
with_monodroid_default=no
with_cooperative_gc_default=no
fi
+if test "x$AOT_BUILD_FLAGS" != "x"; then :
+ AC_SUBST(AOT_BUILD_FLAGS)
+ AC_SUBST(AOT_RUN_FLAGS)
+fi
+
AC_SUBST(TEST_PROFILE)
if test "x$with_profile4_x" = "xdefault"; then
AM_CONDITIONAL(INSTALL_XAMMAC, [test "x$with_xammac" != "xno"])
AM_CONDITIONAL(INSTALL_MOBILE_STATIC, [test "x$with_mobile_static" != "xno"])
-AC_SUBST(MONO_LLVMONLY)
-
-AC_SUBST(BITCODE)
+AC_SUBST(INSTALL_MOBILE_STATIC)
default_profile=net_4_x
if test -z "$INSTALL_MONODROID_TRUE"; then :
echo "PLATFORM = darwin" >> $mcs_topdir/build/config.make
fi
+ if test "x$PLATFORM_AOT_SUFFIX" != "x"; then
+ echo "PLATFORM_AOT_SUFFIX = $PLATFORM_AOT_SUFFIX" >> $mcs_topdir/build/config.make
+ fi
+
if test x$AOT_SUPPORTED = xyes -a x$enable_system_aot = xdefault; then
enable_system_aot=yes
fi
echo "BCL_OPTIMIZE = 1" >> $srcdir/$mcsdir/build/config.make
fi
- if test "x$MONO_LLVMONLY" = "xyes" ; then
- echo "MONO_LLVMONLY = 1" >> $srcdir/$mcsdir/build/config.make
+ if test "x$AOT_BUILD_FLAGS" != "x" ; then
+ echo "AOT_RUN_FLAGS=$AOT_RUN_FLAGS" >> $srcdir/$mcsdir/build/config.make
+ echo "AOT_BUILD_FLAGS=$AOT_BUILD_FLAGS" >> $srcdir/$mcsdir/build/config.make
fi
fi
AC_CHECK_FUNCS(getrlimit)
AC_CHECK_FUNCS(fork execv execve)
+AC_ARG_WITH([overridable-allocators], [ --with-overridable-allocators allow g_*alloc/g_free to call custom allocators set via g_mem_set_vtable])
+
+if test x$with_overridable_allocators == xyes; then
+ AC_DEFINE(ENABLE_OVERRIDABLE_ALLOCATORS,1,[Overridable allocator support enabled])
+ AC_MSG_NOTICE([Overridable allocator support enabled])
+else
+ AC_MSG_NOTICE([Overridable allocator support disabled])
+fi
+
#
# Mono currently supports 10.6, but strndup is not available prior to 10.7; avoiding
# the detection of strndup on OS X so Mono built on 10.7+ still runs on 10.6. This can be
AC_CHECK_FUNCS(strndup getpwuid_r)
fi
-AM_CONDITIONAL(NEED_VASPRINTF, test x$ac_cv_func_vasprintf = xno )
+AM_CONDITIONAL(NEED_VASPRINTF, test x$ac_cv_func_vasprintf = xno || test x$with_overridable_allocators == xyes)
AM_ICONV()
AC_SEARCH_LIBS(sqrtf, m)
gdate-unix.c gdir-unix.c gfile-unix.c gmisc-unix.c \
gmodule-unix.c gtimer-unix.c
-# some unices and windows do not have an implementation of vasprintf
-# used by eglib, use provided implementation instead
-if NEED_VASPRINTF
-vasprintf_files = vasprintf.c
-else
-vaprinttf_files = foo.c
-endif
-
if HOST_WIN32
os_files = $(win_files)
else
garray.c \
gbytearray.c \
gerror.c \
- vasprintf.h \
ghashtable.c \
giconv.c \
gmem.c \
gutf8.c \
gunicode.c \
unicode-data.h \
- $(os_files) \
- $(vasprintf_files)
+ $(os_files)
libeglib_la_CFLAGS = -g -Wall -D_FORTIFY_SOURCE=2
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+#include <config.h>
#include <glib.h>
-
-#include "vasprintf.h"
-
GError *
g_error_new (gpointer domain, gint code, const char *format, ...)
{
err->code = code;
va_start (args, format);
- if (vasprintf (&err->message, format, args) == -1)
+ if (g_vasprintf (&err->message, format, args) == -1)
err->message = g_strdup_printf ("internal: invalid format string %s", format);
va_end (args);
err->domain = domain;
err->code = code;
- if (vasprintf (&err->message, format, ap) == -1)
+ if (g_vasprintf (&err->message, format, ap) == -1)
err->message = g_strdup_printf ("internal: invalid format string %s", format);
return err;
{
g_return_if_fail (error != NULL);
- free (error->message);
+ g_free (error->message);
g_free (error);
}
#ifndef __GLIB_H
#define __GLIB_H
-
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
+
#ifdef _MSC_VER
#pragma include_alias(<eglib-config.h>, <eglib-config.hw>)
#endif
gpointer g_realloc (gpointer obj, gsize size);
gpointer g_malloc (gsize x);
gpointer g_malloc0 (gsize x);
+gpointer g_calloc (gsize n, gsize x);
gpointer g_try_malloc (gsize x);
gpointer g_try_realloc (gpointer obj, gsize size);
#define g_alloca(size) alloca (size)
gpointer g_memdup (gconstpointer mem, guint byte_size);
-static inline gchar *g_strdup (const gchar *str) { if (str) {return strdup (str);} return NULL; }
+static inline gchar *g_strdup (const gchar *str) { if (str) { return (gchar*) g_memdup (str, (guint)strlen (str) + 1); } return NULL; }
gchar **g_strdupv (gchar **str_array);
typedef struct {
gpointer (*realloc) (gpointer mem, gsize n_bytes);
void (*free) (gpointer mem);
gpointer (*calloc) (gsize n_blocks, gsize n_block_bytes);
- gpointer (*try_malloc) (gsize n_bytes);
- gpointer (*try_realloc) (gpointer mem, gsize n_bytes);
} GMemVTable;
-#define g_mem_set_vtable(x)
+void g_mem_set_vtable (GMemVTable* vtable);
struct _GMemChunk {
guint alloc_size;
gint g_fprintf (FILE *file, gchar const *format, ...);
gint g_sprintf (gchar *string, gchar const *format, ...);
gint g_snprintf (gchar *string, gulong n, gchar const *format, ...);
+gint g_vasprintf (gchar **ret, const gchar *fmt, va_list ap);
#define g_vprintf vprintf
#define g_vfprintf vfprintf
#define g_vsprintf vsprintf
#define g_vsnprintf vsnprintf
-#define g_vasprintf vasprintf
gsize g_strlcpy (gchar *dest, const gchar *src, gsize dest_size);
gchar *g_stpcpy (gchar *dest, const char *src);
gchar *g_get_prgname (void);
void g_set_prgname (const gchar *prgname);
+gboolean g_ensure_directory_exists (const gchar *filename);
+
/*
* Shell
*/
if (context->parser.end_element != NULL && context->state == START_ELEMENT){
context->parser.end_element (context, ename, context->user_data, error);
if (error != NULL && *error != NULL){
- free (ename);
+ g_free (ename);
goto fail;
}
}
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <config.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
+#if defined (ENABLE_OVERRIDABLE_ALLOCATORS)
+
+static GMemVTable sGMemVTable = { malloc, realloc, free, calloc };
+
+void
+g_mem_set_vtable (GMemVTable* vtable)
+{
+ sGMemVTable.calloc = vtable->calloc ? vtable->calloc : calloc;
+ sGMemVTable.realloc = vtable->realloc ? vtable->realloc : realloc;
+ sGMemVTable.malloc = vtable->malloc ? vtable->malloc : malloc;
+ sGMemVTable.free = vtable->free ? vtable->free : free;
+}
+
+#define G_FREE_INTERNAL sGMemVTable.free
+#define G_REALLOC_INTERNAL sGMemVTable.realloc
+#define G_CALLOC_INTERNAL sGMemVTable.calloc
+#define G_MALLOC_INTERNAL sGMemVTable.malloc
+#else
+
+void
+g_mem_set_vtable (GMemVTable* vtable)
+{
+}
+
+#define G_FREE_INTERNAL free
+#define G_REALLOC_INTERNAL realloc
+#define G_CALLOC_INTERNAL calloc
+#define G_MALLOC_INTERNAL malloc
+#endif
void
g_free (void *ptr)
{
if (ptr != NULL)
- free (ptr);
+ G_FREE_INTERNAL (ptr);
}
gpointer
g_free (obj);
return 0;
}
- ptr = realloc (obj, size);
+ ptr = G_REALLOC_INTERNAL (obj, size);
if (ptr)
return ptr;
g_error ("Could not allocate %i bytes", size);
gpointer ptr;
if (!x)
return 0;
- ptr = malloc (x);
+ ptr = G_MALLOC_INTERNAL (x);
if (ptr)
return ptr;
g_error ("Could not allocate %i bytes", x);
}
+gpointer g_calloc (gsize n, gsize x)
+{
+ gpointer ptr;
+ if (!x || !n)
+ return 0;
+ ptr = G_CALLOC_INTERNAL (n, x);
+ if (ptr)
+ return ptr;
+ g_error ("Could not allocate %i (%i * %i) bytes", x*n, n, x);
+}
gpointer g_malloc0 (gsize x)
{
- gpointer ptr;
- if (!x)
- return 0;
- ptr = calloc(1,x);
- if (ptr)
- return ptr;
- g_error ("Could not allocate %i bytes", x);
+ return g_calloc (1,x);
}
gpointer g_try_malloc (gsize x)
{
if (x)
- return malloc (x);
+ return G_MALLOC_INTERNAL (x);
return 0;
}
gpointer g_try_realloc (gpointer obj, gsize size)
{
if (!size) {
- g_free (obj);
+ G_FREE_INTERNAL (obj);
return 0;
}
- return realloc (obj, size);
+ return G_REALLOC_INTERNAL (obj, size);
}
gint ccBuf = GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, buf, 9);
buf[ccBuf - 1] = '-';
ccBuf += GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, buf + ccBuf, 9);
- return strdup(buf);
+ return g_strdup (buf);
}
gboolean
}
}
+ g_free (drive);
+ g_free (path);
+
return home_dir;
}
#include <stdlib.h>
#include <glib.h>
-#include "vasprintf.h"
-
/* The current fatal levels, error is always fatal */
static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR;
static GLogFunc default_log_func;
va_list args;
va_start (args, format);
- if (vasprintf (&msg, format, args) < 0)
+ if (g_vasprintf (&msg, format, args) < 0)
return;
va_end (args);
stdout_handler = default_stdout_handler;
stdout_handler (msg);
- free (msg);
+ g_free (msg);
}
void
va_list args;
va_start (args, format);
- if (vasprintf (&msg, format, args) < 0)
+ if (g_vasprintf (&msg, format, args) < 0)
return;
va_end (args);
stderr_handler = default_stderr_handler;
stderr_handler (msg);
- free (msg);
+ g_free (msg);
}
GLogLevelFlags
if (!default_log_func)
default_log_func = g_log_default_handler;
- if (vasprintf (&msg, format, args) < 0)
+ if (g_vasprintf (&msg, format, args) < 0)
return;
default_log_func (log_domain, log_level, msg, default_log_func_user_data);
- free (msg);
+ g_free (msg);
}
void
#include <stdio.h>
#include <glib.h>
#include <errno.h>
+#include <sys/stat.h>
#ifdef G_OS_WIN32
#include <direct.h>
{
return name;
}
+
+gboolean
+g_ensure_directory_exists (const gchar *filename)
+{
+#ifdef G_OS_WIN32
+ gchar *dir_utf8 = g_path_get_dirname (filename);
+ gunichar2 *p;
+ gunichar2 *dir_utf16 = NULL;
+ int retval;
+
+ if (!dir_utf8 || !dir_utf8 [0])
+ return FALSE;
+
+ dir_utf16 = g_utf8_to_utf16 (dir_utf8, strlen (dir_utf8), NULL, NULL, NULL);
+ g_free (dir_utf8);
+
+ if (!dir_utf16)
+ return FALSE;
+
+ p = dir_utf16;
+
+ /* make life easy and only use one directory seperator */
+ while (*p != '\0')
+ {
+ if (*p == '/')
+ *p = '\\';
+ p++;
+ }
+
+ p = dir_utf16;
+
+ /* get past C:\ )*/
+ while (*p++ != '\\')
+ {
+ }
+
+ while (1) {
+ gboolean bRet = FALSE;
+ p = wcschr (p, '\\');
+ if (p)
+ *p = '\0';
+ retval = _wmkdir (dir_utf16);
+ if (retval != 0 && errno != EEXIST) {
+ g_free (dir_utf16);
+ return FALSE;
+ }
+ if (!p)
+ break;
+ *p++ = '\\';
+ }
+
+ g_free (dir_utf16);
+ return TRUE;
+#else
+ char *p;
+ gchar *dir = g_path_get_dirname (filename);
+ int retval;
+ struct stat sbuf;
+
+ if (!dir || !dir [0]) {
+ g_free (dir);
+ return FALSE;
+ }
+
+ if (stat (dir, &sbuf) == 0 && S_ISDIR (sbuf.st_mode)) {
+ g_free (dir);
+ return TRUE;
+ }
+
+ p = dir;
+ while (*p == '/')
+ p++;
+
+ while (1) {
+ p = strchr (p, '/');
+ if (p)
+ *p = '\0';
+ retval = mkdir (dir, 0777);
+ if (retval != 0 && errno != EEXIST) {
+ g_free (dir);
+ return FALSE;
+ }
+ if (!p)
+ break;
+ *p++ = '/';
+ }
+
+ g_free (dir);
+ return TRUE;
+#endif
+}
+
#include <ctype.h>
#include <glib.h>
-#include "vasprintf.h"
+/*
+ * g_strndup and g_vasprintf need to allocate memory with g_malloc if
+ * ENABLE_OVERRIDABLE_ALLOCATORS is defined so that it can be safely freed with g_free
+ * rather than free.
+ */
/* 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)
{
-#ifdef HAVE_STRNDUP
+#if defined (HAVE_STRNDUP) && !defined (ENABLE_OVERRIDABLE_ALLOCATORS)
return strndup (str, n);
#else
if (str) {
#endif
}
+gint g_vasprintf (gchar **ret, const gchar *fmt, va_list ap)
+{
+#if defined (HAVE_VASPRINTF) && !defined (ENABLE_OVERRIDABLE_ALLOCATORS)
+ return vasprintf (ret, fmt, ap);
+#else
+ char *buf;
+ int len;
+ size_t buflen;
+ va_list ap2;
+
+#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
+ ap2 = ap;
+ len = _vscprintf(fmt, ap2); // NOTE MS specific extension ( :-( )
+#else
+ va_copy(ap2, ap);
+ len = vsnprintf(NULL, 0, fmt, ap2);
+#endif
+
+ if (len >= 0 && (buf = g_malloc ((buflen = (size_t) (len + 1)))) != NULL) {
+ len = vsnprintf(buf, buflen, fmt, ap);
+ *ret = buf;
+ } else {
+ *ret = NULL;
+ len = -1;
+ }
+
+ va_end(ap2);
+ return len;
+#endif
+}
+
void
g_strfreev (gchar **str_array)
{
int n;
char *ret;
- n = vasprintf (&ret, format, args);
+ n = g_vasprintf (&ret, format, args);
if (n == -1)
return NULL;
int n;
va_start (args, format);
- n = vasprintf (&ret, format, args);
+ n = g_vasprintf (&ret, format, args);
va_end (args);
if (n == -1)
return NULL;
+++ /dev/null
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-int vasprintf(char **ret, const char *fmt, va_list ap)
-{
- char *buf;
- int len;
- size_t buflen;
- va_list ap2;
-
-#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
- ap2 = ap;
- len = _vscprintf(fmt, ap2); // NOTE MS specific extension ( :-( )
-#else
- va_copy(ap2, ap);
- len = vsnprintf(NULL, 0, fmt, ap2);
-#endif
-
- if (len >= 0 && (buf = malloc ((buflen = (size_t) (len + 1)))) != NULL) {
- len = vsnprintf(buf, buflen, fmt, ap);
- *ret = buf;
- } else {
- *ret = NULL;
- len = -1;
- }
-
- va_end(ap2);
- return len;
-}
-
+++ /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 */
#include "test.h"
extern gint global_passed, global_tests;
-
-#ifndef HAVE_VASPRINTF
- /* systen does not provide a vasprintf function, use the one
- provided within eglib itself */
-extern int vasprintf(char **ret, const char *format, va_list ap);
-#endif
-
static gchar *last_result = NULL;
gboolean
return NULL;
#else
va_start(args, format);
- n = vasprintf(&ret, format, args);
+ n = g_vasprintf(&ret, format, args);
va_end(args);
if(n == -1) {
--- /dev/null
+Subproject commit a7dbffc17d029f2d66f56ddc9f50349a1bc0dcfe
--- /dev/null
+Subproject commit 04bdab55d8de9edcf628694cfd2001561e8f8e60
LLVM_PATH=llvm
+SUBMODULES_CONFIG_FILE = $(top_srcdir)/llvm/SUBMODULES.json
include $(top_srcdir)/scripts/submodules/versions.mk
$(eval $(call ValidateVersionTemplate,llvm,LLVM))
mono-symbolicate \- Mono Symbolicate Tool
.SH SYNOPSIS
.PP
-.B mono-symbolicate exefile stacktracesfile [directories...]
+.B mono-symbolicate <msym dir> <input file>
+.PP
+.B mono-symbolicate store-symbols <msym dir> [<dir>]+
.SH DESCRIPTION
mono-symbolicate is a tool that converts a stack trace with <filename unknown>:0
into one with file names and line numbers.
.PP
-The output of calling this tool will be the provided
-.I stacktracesfile
-where <filename unknown>:0 parts are replaced by
-a file name and a line number.
+When mono-symbolicate is called with a symbol directory and a file containing a stacktrace:
+.P
+.B mono-symbolicate <msym dir> <input file>
.PP
-For the tool to work it needs to load referenced assemblies, it will first look
-in the same folder as
-.I exefile
-then from one of the provided
-.I directories.
+The tool writes into stdout the file contents while adding file location to stack frames when
+it is possible to symbolicate with the symbols available on the symbol directory.
.PP
-The tool assumes that the folder with a referenced assembly called for example
-name.dll will also include name.dll.mdb,
-if the referenced assembly is AOT compiled then the tool is also expecting to find
-name.dll.msym.
+Managed symbols .exe/.dll can be added to the symbol directory by doing:
+.P
+.B mono-symbolicate store-symbols <msym dir> [<dir>]+
.SH AUTHOR
Written by Marcos Henrich
.SH COPYRIGHT
.\" Author:
.\" Miguel de Icaza (miguel@gnu.org)
.\"
-.TH Mono "Mono 4.5.2"
+.TH Mono "Mono 4.7.0"
.SH NAME
mono \- Mono's ECMA-CLI native code generator (Just-in-Time and Ahead-of-Time)
.SH SYNOPSIS
.I llvm-path=<PREFIX>
Same for the llvm tools 'opt' and 'llc'.
.TP
-.I gen-seq-points-file=FILE.msym
+.I msym-dir=<PATH>
Instructs the AOT compiler to generate offline sequence points .msym files.
-The path is optional, if none is passed then a .msym file will be generated
-next to the input assembly.
+The generated .msym files will be stored into a subfolder of <PATH> named as the
+compilation AOTID.
.TP
.I mtriple=<TRIPLE>
Use the GNU style target triple <TRIPLE> to determine some code generation options, i.e.
IL stack is empty. These are places where the debugger can set a
breakpoint.
.TP
-\fBgen-compact-seq-points\fR
-This option generates sequence points data that maps native offsets to
-IL offsets. Sequence point data is used to display IL offset in
-stacktraces. Stacktraces with IL offsets can be symbolicated using
-mono-symbolicate tool.
+\fBno-compact-seq-points\fR
+Unless the option is used, the runtime generates sequence points data that
+maps native offsets to IL offsets. Sequence point data is used to
+display IL offset in stacktraces. Stacktraces with IL offsets can be
+symbolicated using mono-symbolicate tool.
.TP
\fBhandle-sigint\fR
Captures the interrupt signal (Control-C) and displays a stack trace
monotouch_tv_runtime_SUBDIRS := build class
xammac_SUBDIRS := build class
mobile_SUBDIRS := build class
-mobile_static_SUBDIRS := build class
+mobile_static_SUBDIRS := build class ilasm
binary_reference_assemblies_SUBDIRS := build class
net_4_x_SUBDIRS := build mcs class nunit24 ilasm tools tests errors docs
xammac_net_4_5_SUBDIRS := build class
# This is for changing / to \ on windows
PLATFORM_CHANGE_SEPARATOR_CMD = cat
-PLATFORM_AOT_SUFFIX = .dylib
-
hidden_prefix = .
hidden_suffix =
# This is for changing / to \ on windows
PLATFORM_CHANGE_SEPARATOR_CMD = cat
-PLATFORM_AOT_SUFFIX = .so
-
hidden_prefix = .
hidden_suffix =
override CURDIR:=$(shell cygpath -m $(CURDIR))
-## not so simple :-)
-#PLATFORM_AOT_SUFFIX = .dll
-
hidden_prefix =
hidden_suffix = .tmp
-d:NET_4_0 \
-d:NET_4_5 \
-d:MONO \
+ -d:NETSTANDARD \
-nowarn:1699 \
-nostdlib \
$(DEFAULT_REFERENCES) \
-d:NET_4_0 \
-d:NET_4_5 \
-d:MONO \
+ -d:NETSTANDARD \
-d:MOBILE,MOBILE_STATIC,MOBILE_LEGACY \
-d:FULL_AOT_RUNTIME \
-d:DISABLE_REMOTING \
# Note need for trailing comma. If you add, keep it
PROFILE_TEST_HARNESS_EXCLUDES = MobileNotWorking,PKITS,
-ifndef MONO_DISABLE_GSHAREDVT
-GSHAREDVT_FLAG = -O=gsharedvt
-endif
-
-ifneq ($(MONO_LLVMONLY),)
-AOT_BUILD_FLAGS_PREFIX = --aot=llvmonly,
-AOT_RUN_FLAGS = --llvmonly
-else
-AOT_BUILD_FLAGS_PREFIX = $(GSHAREDVT_FLAG) --aot=full,
-AOT_RUN_FLAGS = --full-aot
-endif
-
ALWAYS_AOT = yes
-d:MOBILE_DYNAMIC \
-d:MONODROID \
-d:ANDROID \
+ -d:NETSTANDARD \
-nowarn:1699 \
-nostdlib \
$(DEFAULT_REFERENCES) \
-d:DISABLE_REMOTING \
-d:DISABLE_COM \
-d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK \
+ -d:NETSTANDARD \
-nowarn:1699 \
-nostdlib \
$(DEFAULT_REFERENCES) \
DEFAULT_REFERENCES = -r:$(topdir)/class/lib/net_4_x/mscorlib.dll
PROFILE_MCS_FLAGS := $(PROFILE_MCS_FLAGS) -d:XBUILD_12
-RESGEN_EXE = $(topdir)/class/lib/net_4_x/resgen.exe
-
XBUILD_VERSION = 12.0
INTERNAL_ILASM = $(RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(PROFILE)/ilasm.exe
INTERNAL_CSC = $(RUNTIME) $(RUNTIME_FLAGS) $(CSC_LOCATION)
-RESGEN_EXE = $(topdir)/class/lib/$(PROFILE)/resgen.exe
+RESGEN_EXE = $(topdir)/class/lib/$(PROFILE)/$(PARENT_PROFILE)resgen.exe
INTERNAL_RESGEN = $(RUNTIME) $(RUNTIME_FLAGS) $(RESGEN_EXE)
-RESGEN = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_RESGEN)
+RESGEN = MONO_PATH="$(topdir)/class/lib/$(PROFILE)/$(PARENT_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_RESGEN)
STRING_REPLACER = MONO_PATH="$(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(BUILD_TOOLS_PROFILE)/cil-stringreplacer.exe
depsdir = $(topdir)/build/deps
# Make sure propagates
export TEST_HARNESS
-# start aot config
-
-# We set the prefix of the aot build flags
-# in the profile. This determines the aot type,
-# whether it be llvmonly or full. To this we append the
-# options which do not change between them, the INVARIANT_AOT_OPTIONS
-ifndef AOT_BUILD_FLAGS_PREFIX
-AOT_BUILD_FLAGS_PREFIX = --aot=
-endif
-
-# Set the options for building and running AOT
-# The trampoline numbers are provisional, they are what is required
-# to run the mcs/class test suites. They should be considered a lower bound.
-INVARIANT_AOT_OPTIONS=nimt-trampolines=900,ntrampolines=8000,nrgctx-fetch-trampolines=256
-
-ifndef MONO_DISABLE_GSHAREDVT
-INVARIANT_AOT_OPTIONS:=$(INVARIANT_AOT_OPTIONS),ngsharedvt-trampolines=2800
-endif
-
-AOT_BUILD_FLAGS = $(AOT_BUILD_FLAGS_PREFIX)$(INVARIANT_AOT_OPTIONS)
-
-# end AOT config
-
ifdef BCL_OPTIMIZE
PROFILE_MCS_FLAGS += -optimize
endif
$(topdir)/class/lib/$(PROFILE)/%$(PLATFORM_AOT_SUFFIX): $(topdir)/class/lib/$(PROFILE)/%
@ mkdir -p $(topdir)/class/lib/$(PROFILE)/$*_bitcode_tmp
- @echo "AOT [$(PROFILE)] AOT $* " && cd $(topdir)/class/lib/$(PROFILE)/ && MONO_PATH="." $(RUNTIME) $(RUNTIME_FLAGS) $(AOT_BUILD_FLAGS),temp-path=$*_bitcode $* >> $(PROFILE)-aot.log
+ @echo "AOT [$(PROFILE)] AOT $* " && cd $(topdir)/class/lib/$(PROFILE)/ && MONO_PATH="." $(RUNTIME) $(RUNTIME_FLAGS) $(AOT_BUILD_FLAGS),temp-path=$*_bitcode_tmp $* >> $(PROFILE)-aot.log
@ rm -rf $(topdir)/class/lib/$(PROFILE)/$*_bitcode_tmp
endif #ifneq ("$(wildcard $(topdir)/class/lib/$(PROFILE))","")
dist-local: dist-default
-DIST_SUBDIRS = $(net_4_x_PARALLEL_SUBDIRS)
+DIST_SUBDIRS = $(net_4_x_PARALLEL_SUBDIRS) $(net_4_x_SUBDIRS) $(mobile_only_SUBDIRS)
DISTFILES=subdirs.make
doc-update-local:
System System.Core System.ComponentModel.DataAnnotations System.Numerics System.Runtime.Serialization System.XML \
System.ComponentModel.Composition System.ServiceModel System.Xml.Linq System.Data System.IO.Compression.FileSystem \
-System.ServiceProcess System.Security System.Net.Http.WebRequest System.Net.Http:
+System.ServiceProcess System.Security System.Net.Http.WebRequest System.Net.Http System.ServiceProcess:
all-local-aot:
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+RegistryAclExtensions.cs
--- /dev/null
+//
+// RegistryAclExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Security;
+using System.Security.AccessControl;
+
+namespace Microsoft.Win32
+{
+ public static class RegistryAclExtensions
+ {
+ [MonoTODO]
+ public static RegistrySecurity GetAccessControl (this RegistryKey key)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static RegistrySecurity GetAccessControl (this RegistryKey key, AccessControlSections includeSections)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl (this RegistryKey key, RegistrySecurity registrySecurity)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.RegistryAccessRule))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.RegistryAuditRule))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.RegistrySecurity))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryAclExtensions))]
// THE SOFTWARE.
//
-#if !MOBILE
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.Registry))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryHive))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryKey))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryValueKind))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryValueOptions))]
-#endif
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryOptions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.RegistryView))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeRegistryHandle))]
// THE SOFTWARE.
//
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.BrowsableAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CategoryAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ComponentCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DescriptionAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DesignOnlyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DesignerCategoryAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DesignerSerializationVisibility))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DesignerSerializationVisibilityAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DisplayNameAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.EventHandlerList))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.IComponent))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.IContainer))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ISite))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ImmutableObjectAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.InitializationEventAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.LocalizableAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.MergablePropertyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.NotifyParentPropertyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ParenthesizePropertyNameAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ReadOnlyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.RefreshProperties))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.RefreshPropertiesAttribute))]
//
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ArrayConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.AttributeCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.AttributeProviderAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.BaseNumberConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.BooleanConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ByteConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CancelEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CharConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CollectionChangeAction))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CollectionChangeEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CollectionChangeEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CollectionConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.CustomTypeDescriptor))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DateTimeConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DateTimeOffsetConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DecimalConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DefaultEventAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DefaultPropertyAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.DoubleConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.EnumConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.EventDescriptor))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.EventDescriptorCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ExtenderProvidedPropertyAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.GuidConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.HandledEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.HandledEventHandler))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ICustomTypeDescriptor))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.IExtenderProvider))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.IListSource))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ITypeDescriptorContext))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ITypedList))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.Int16Converter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.Int32Converter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.Int64Converter))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ITypeDescriptorContext))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.InvalidAsynchronousStateException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.MemberDescriptor))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.MultilineStringConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.NullableConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.PropertyDescriptor))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.PropertyDescriptorCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.ProvidePropertyAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.RefreshEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.RefreshEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.SByteConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.SingleConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.StringConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TimeSpanConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeConverterAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeDescriptionProvider))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeDescriptionProviderAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeDescriptor))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.TypeListConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.UInt16Converter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.UInt32Converter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ComponentModel.UInt64Converter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.UriTypeConverter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleCancelEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleCancelEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleColor))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleSpecialKey))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleKey))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleKeyInfo))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleModifiers))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ConsoleSpecialKey))]
--- /dev/null
+//
+// DbColumn.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Collections.Generic;
+
+namespace System.Data.Common
+{
+ public abstract class DbColumn
+ {
+ public bool? AllowDBNull { get; protected set; }
+ public string BaseCatalogName { get; protected set; }
+ public string BaseColumnName { get; protected set; }
+ public string BaseSchemaName { get; protected set; }
+ public string BaseServerName { get; protected set; }
+ public string BaseTableName { get; protected set; }
+ public string ColumnName { get; protected set; }
+ public int? ColumnOrdinal { get; protected set; }
+ public int? ColumnSize { get; protected set; }
+ public bool? IsAliased { get; protected set; }
+ public bool? IsAutoIncrement { get; protected set; }
+ public bool? IsExpression { get; protected set; }
+ public bool? IsHidden { get; protected set; }
+ public bool? IsIdentity { get; protected set; }
+ public bool? IsKey { get; protected set; }
+ public bool? IsLong { get; protected set; }
+ public bool? IsReadOnly { get; protected set; }
+ public bool? IsUnique { get; protected set; }
+ public int? NumericPrecision { get; protected set; }
+ public int? NumericScale { get; protected set; }
+ public string UdtAssemblyQualifiedName { get; protected set; }
+ public Type DataType { get; protected set; }
+ public string DataTypeName { get; protected set; }
+ public virtual object this[string property] {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+
+namespace System.Data.Common
+{
+
+ internal class DataRowDbColumn : DbColumn
+ {
+ private DataColumnCollection schemaColumns;
+ private DataRow schemaRow;
+
+ public DataRowDbColumn(DataRow readerSchemaRow, DataColumnCollection readerSchemaColumns)
+ {
+ this.schemaRow = readerSchemaRow;
+ this.schemaColumns = readerSchemaColumns;
+ populateFields();
+ }
+
+ private void populateFields()
+ {
+ AllowDBNull = GetDbColumnValue<bool?>(SchemaTableColumn.AllowDBNull);
+ BaseCatalogName = GetDbColumnValue<string>(SchemaTableOptionalColumn.BaseCatalogName);
+ BaseColumnName = GetDbColumnValue<string>(SchemaTableColumn.BaseColumnName);
+ BaseSchemaName = GetDbColumnValue<string>(SchemaTableColumn.BaseSchemaName);
+ BaseServerName = GetDbColumnValue<string>(SchemaTableOptionalColumn.BaseServerName);
+ BaseTableName = GetDbColumnValue<string>(SchemaTableColumn.BaseTableName);
+ ColumnName = GetDbColumnValue<string>(SchemaTableColumn.ColumnName);
+ ColumnOrdinal = GetDbColumnValue<int?>(SchemaTableColumn.ColumnOrdinal);
+ ColumnSize = GetDbColumnValue<int?>(SchemaTableColumn.ColumnSize);
+ IsAliased = GetDbColumnValue<bool?>(SchemaTableColumn.IsAliased);
+ IsAutoIncrement = GetDbColumnValue<bool?>(SchemaTableOptionalColumn.IsAutoIncrement);
+ IsExpression = GetDbColumnValue<bool>(SchemaTableColumn.IsExpression);
+ IsHidden = GetDbColumnValue<bool?>(SchemaTableOptionalColumn.IsHidden);
+ IsIdentity = GetDbColumnValue<bool?>("IsIdentity");
+ IsKey = GetDbColumnValue<bool?>(SchemaTableColumn.IsKey);
+ IsLong = GetDbColumnValue<bool?>(SchemaTableColumn.IsLong);
+ IsReadOnly = GetDbColumnValue<bool?>(SchemaTableOptionalColumn.IsReadOnly);
+ IsUnique = GetDbColumnValue<bool?>(SchemaTableColumn.IsUnique);
+ NumericPrecision = GetDbColumnValue<int?>(SchemaTableColumn.NumericPrecision);
+ NumericScale = GetDbColumnValue<int?>(SchemaTableColumn.NumericScale);
+ UdtAssemblyQualifiedName = GetDbColumnValue<string>("UdtAssemblyQualifiedName");
+ DataType = GetDbColumnValue<Type>(SchemaTableColumn.DataType);
+ DataTypeName = GetDbColumnValue<string>("DataTypeName");
+ }
+
+ private T GetDbColumnValue<T>(string columnName)
+ {
+ if (!schemaColumns.Contains(columnName))
+ {
+ return default(T);
+ }
+ object schemaObject = schemaRow[columnName];
+ if (schemaObject is T)
+ {
+ return (T)schemaObject;
+ }
+ return default(T);
+ }
+ }
+
+ public static class DbDataReaderExtensions
+ {
+ public static System.Collections.ObjectModel.ReadOnlyCollection<DbColumn> GetColumnSchema(this DbDataReader reader)
+ {
+ IList<DbColumn> columnSchema = new List<DbColumn>();
+ DataTable schemaTable = reader.GetSchemaTable();
+ DataColumnCollection schemaTableColumns = schemaTable.Columns;
+ foreach (DataRow row in schemaTable.Rows)
+ {
+ DbColumn dbColumn = new DataRowDbColumn(row, schemaTableColumns);
+ columnSchema.Add(dbColumn);
+ }
+ System.Collections.ObjectModel.ReadOnlyCollection<DbColumn> readOnlyColumnSchema = new System.Collections.ObjectModel.ReadOnlyCollection<DbColumn>(columnSchema);
+ return readOnlyColumnSchema;
+ }
+
+ public static bool CanGetColumnSchema(this DbDataReader reader)
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// IDbColumnSchemaGenerator.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Data.Common
+{
+ public interface IDbColumnSchemaGenerator
+ {
+ System.Collections.ObjectModel.ReadOnlyCollection<DbColumn> GetColumnSchema();
+ }
+}
\ No newline at end of file
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System System.Data
+LIB_REFS = System System.Data System.Xml
LIB_MCS_FLAGS = $(SIGN_FLAGS)
PLATFORM_DEBUG_FLAGS =
TypeForwarders.cs
AssemblyInfo.cs
-
+IDbColumnSchemaGenerator.cs
+DbColumn.cs
+DbDataReaderExtensions.Facade.cs
// THE SOFTWARE.
//
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.DBNull))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.CommandBehavior))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.CommandType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbCommand))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbConnection))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbConnectionStringBuilder))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataReader))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbDataRecord))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbEnumerator))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbParameter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbParameterCollection))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbProviderFactory))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.Common.DbTransaction))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ConnectionState))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataRowVersion))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DataTable))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.DbType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataParameter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataParameterCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataReader))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDataRecord))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbCommand))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbConnection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbDataParameter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IDbTransaction))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.IsolationLevel))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.ParameterDirection))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StateChangeEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.StateChangeEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.UpdateRowSource))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.DBNull))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.SqlServer.Server.SqlMetaData))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.ApplicationIntent))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SortOrder))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlBulkCopy))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlBulkCopyColumnMapping))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlBulkCopyColumnMappingCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlBulkCopyOptions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlClientFactory))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlCommand))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlConnection))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlInfoMessageEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlParameter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlParameterCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlRowsCopiedEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlRowsCopiedEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlClient.SqlTransaction))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlDbType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Data.SqlTypes.INullable))]
// THE SOFTWARE.
//
-// TODO: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeProcessHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeProcessHandle))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.DataReceivedEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.DataReceivedEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Process))]
--- /dev/null
+//
+// StackFrameExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace System.Diagnostics
+{
+ public static class StackFrameExtensions
+ {
+ [MonoTODO]
+ public static bool HasNativeImage (this StackFrame stackFrame)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static bool HasMethod (this StackFrame stackFrame)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static bool HasILOffset (this StackFrame stackFrame)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static bool HasSource (this StackFrame stackFrame)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+StackFrameExtensions.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.StackFrame))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.StackTrace))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.StackFrameExtensions))]
--- /dev/null
+//
+// EventCounter.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Diagnostics.Tracing
+{
+ public class EventCounter
+ {
+ public EventCounter (string name, EventSource eventSource)
+ {
+ }
+
+ public void WriteMetric (float value)
+ {
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
-
+EventCounter.cs
// THE SOFTWARE.
//
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventActivityOptions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventChannel))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventCommand))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventCommandEventArgs))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventDataAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldFormat))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldTags))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventIgnoreAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventKeywords))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventLevel))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventListener))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventManifestOptions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventOpcode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSource))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceSettings))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceSettings))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventTags))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventTask))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventWrittenEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.NonEventAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventActivityOptions))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventChannel))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventDataAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldFormat))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventFieldTags))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventIgnoreAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventManifestOptions))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceOptions))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventTags))]
--- /dev/null
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Drawing.Primitives.dll")]
+[assembly: AssemblyDescription ("System.Drawing.Primitives.dll")]
+[assembly: AssemblyDefaultAlias ("System.Drawing.Primitives.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Drawing.Primitives
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Drawing.Primitives.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS) $(EXTRA_LIB_MCS_FLAGS)
+
+ifneq (2.1, $(FRAMEWORK_VERSION))
+ifndef XAMMAC_4_5
+LIB_REFS += System.Drawing
+endif
+endif
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.Point))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.PointF))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.Rectangle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.RectangleF))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.Size))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Drawing.SizeF))]
--- /dev/null
+AssemblyInfo.cs
+
+../../System.Drawing/System.Drawing/Point.cs
+../../System.Drawing/System.Drawing/PointF.cs
+../../System.Drawing/System.Drawing/Rectangle.cs
+../../System.Drawing/System.Drawing/RectangleF.cs
+../../System.Drawing/System.Drawing/Size.cs
+../../System.Drawing/System.Drawing/SizeF.cs
--- /dev/null
+#include embedded_System.Drawing.Primitives.dll.sources
--- /dev/null
+#include embedded_System.Drawing.Primitives.dll.sources
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ public static class GlobalizationExtensions
+ {
+ public static StringComparer GetStringComparer(this CompareInfo compareInfo, CompareOptions options)
+ {
+ if (compareInfo == null)
+ {
+ throw new ArgumentNullException(nameof(compareInfo));
+ }
+
+ if (options == CompareOptions.Ordinal)
+ {
+ return StringComparer.Ordinal;
+ }
+
+ if (options == CompareOptions.OrdinalIgnoreCase)
+ {
+ return StringComparer.OrdinalIgnoreCase;
+ }
+
+ if ((options & CultureAwareComparer.ValidCompareMaskOffFlags) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
+
+ return new CultureAwareComparer(compareInfo, options);
+ }
+ }
+
+ internal sealed class CultureAwareComparer : StringComparer
+ {
+ internal const CompareOptions ValidCompareMaskOffFlags =
+ ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
+ CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
+
+ private readonly CompareInfo _compareInfo;
+ private readonly CompareOptions _options;
+
+ internal CultureAwareComparer(CompareInfo compareInfo, CompareOptions options)
+ {
+ Debug.Assert((options & ValidCompareMaskOffFlags) == 0);
+ _compareInfo = compareInfo;
+ _options = options;
+ }
+
+ public override int Compare(string x, string y)
+ {
+ if (Object.ReferenceEquals(x, y)) return 0;
+ if (x == null) return -1;
+ if (y == null) return 1;
+ return _compareInfo.Compare(x, y, _options);
+ }
+
+ public override bool Equals(string x, string y)
+ {
+ if (Object.ReferenceEquals(x, y)) return true;
+ if (x == null || y == null) return false;
+
+ return (_compareInfo.Compare(x, y, _options) == 0);
+ }
+
+ public override int GetHashCode(string obj)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException(nameof(obj));
+ }
+ Contract.EndContractBlock();
+
+ // StringSort used in compare operation and not with the hashing
+ return _compareInfo.GetHashCode(obj, _options & (~CompareOptions.StringSort));
+ }
+
+ // Equals method for the comparer itself.
+ public override bool Equals(object obj)
+ {
+ CultureAwareComparer comparer = obj as CultureAwareComparer;
+ return
+ comparer != null &&
+ _options == comparer._options &&
+ _compareInfo.Equals(comparer._compareInfo);
+ }
+
+ public override int GetHashCode()
+ {
+ return _compareInfo.GetHashCode() ^ ((int)_options & 0x7FFFFFFF);
+ }
+ }
+}
--- /dev/null
+partial class SR
+{
+ public const string Argument_InvalidFlag = "Value of flags is invalid.";
+}
\ No newline at end of file
--- /dev/null
+//
+// StringNormalizationExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System.Text;
+
+namespace System
+{
+ public static class StringNormalizationExtensions
+ {
+ [MonoTODO]
+ public static bool IsNormalized(this string value)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static bool IsNormalized(this string value, NormalizationForm normalizationForm)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static String Normalize(this string value)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static String Normalize(this string value, NormalizationForm normalizationForm)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+SR.cs
+GlobalizationExtensions.cs
+StringNormalizationExtensions.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Globalization.IdnMapping))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Text.NormalizationForm))]
-// Missing: [assembly:System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Globalization.GlobalizationExtensions))]
-// Missing: [assembly:System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.StringNormalizationExtensions))]
--- /dev/null
+// This is stub only. The implementation should come from https://github.com/dotnet/corefx/tree/master/src/System.IO.Compression/src/System/IO/Compression
+
+namespace System.IO.Compression
+{
+ public class ZipArchive : System.IDisposable
+ {
+ public ZipArchive(System.IO.Stream stream) { }
+ public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode) { }
+ public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen) { }
+ public ZipArchive(System.IO.Stream stream, System.IO.Compression.ZipArchiveMode mode, bool leaveOpen, System.Text.Encoding entryNameEncoding) { }
+ public System.Collections.ObjectModel.ReadOnlyCollection<System.IO.Compression.ZipArchiveEntry> Entries { get { return default(System.Collections.ObjectModel.ReadOnlyCollection<System.IO.Compression.ZipArchiveEntry>); } }
+ public System.IO.Compression.ZipArchiveMode Mode { get { return default(System.IO.Compression.ZipArchiveMode); } }
+ public System.IO.Compression.ZipArchiveEntry CreateEntry(string entryName) { return default(System.IO.Compression.ZipArchiveEntry); }
+ public System.IO.Compression.ZipArchiveEntry CreateEntry(string entryName, System.IO.Compression.CompressionLevel compressionLevel) { return default(System.IO.Compression.ZipArchiveEntry); }
+ public void Dispose() { }
+ protected virtual void Dispose(bool disposing) { }
+ public System.IO.Compression.ZipArchiveEntry GetEntry(string entryName) { return default(System.IO.Compression.ZipArchiveEntry); }
+ }
+
+ public partial class ZipArchiveEntry
+ {
+ internal ZipArchiveEntry() { }
+ public System.IO.Compression.ZipArchive Archive { get { return default(System.IO.Compression.ZipArchive); } }
+ public long CompressedLength { get { return default(long); } }
+ public string FullName { get { return default(string); } }
+ public System.DateTimeOffset LastWriteTime { get { return default(System.DateTimeOffset); } set { } }
+ public long Length { get { return default(long); } }
+ public string Name { get { return default(string); } }
+ public void Delete() { }
+ public System.IO.Stream Open() { return default(System.IO.Stream); }
+ public override string ToString() { return default(string); }
+ }
+
+ public enum ZipArchiveMode
+ {
+ Create = 1,
+ Read = 0,
+ Update = 2,
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
-
+Missing.cs
--- /dev/null
+//
+// FileSystemAclExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.IO
+{
+ public static partial class FileSystemAclExtensions
+ {
+ [MonoTODO]
+ public static System.Security.AccessControl.DirectorySecurity GetAccessControl(this System.IO.DirectoryInfo directoryInfo)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static System.Security.AccessControl.DirectorySecurity GetAccessControl(this System.IO.DirectoryInfo directoryInfo, System.Security.AccessControl.AccessControlSections includeSections)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileInfo fileInfo)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileInfo fileInfo, System.Security.AccessControl.AccessControlSections includeSections)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static System.Security.AccessControl.FileSecurity GetAccessControl(this System.IO.FileStream fileStream)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl(this System.IO.DirectoryInfo directoryInfo, System.Security.AccessControl.DirectorySecurity directorySecurity)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl(this System.IO.FileInfo fileInfo, System.Security.AccessControl.FileSecurity fileSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl(this System.IO.FileStream fileStream, System.Security.AccessControl.FileSecurity fileSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+FileSystemAclExtensions.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.FileSystemAuditRule))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.FileSystemRights))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.FileSystemSecurity))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.FileSystemAclExtensions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.RenamedEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.RenamedEventHandler))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.WatcherChangeTypes))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.WaitForChangedResult))]
--- /dev/null
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.IO.Packaging.dll")]
+[assembly: AssemblyDescription ("System.IO.Packaging.dll")]
+[assembly: AssemblyDefaultAlias ("System.IO.Packaging.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.IO.Packaging
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.IO.Packaging.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System WindowsBase
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.FileFormatException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.CompressionOption))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.EncryptionOption))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackUriHelper))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.Package))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackagePart))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackagePartCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageProperties))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageRelationship))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageRelationshipCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageRelationshipSelector))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.PackageRelationshipSelectorType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.TargetMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.ZipPackage))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IO.Packaging.ZipPackagePart))]
--- /dev/null
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Net.Ping.dll")]
+[assembly: AssemblyDescription ("System.Net.Ping.dll")]
+[assembly: AssemblyDefaultAlias ("System.Net.Ping.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Net.Ping
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Net.Ping.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.IPStatus))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.Ping))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.PingException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.PingOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.NetworkInformation.PingReply))]
// THE SOFTWARE.
//
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.AuthenticatedStream))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.EncryptionPolicy))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.LocalCertificateSelectionCallback))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.NegotiateStream))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.ProtectionLevel))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.RemoteCertificateValidationCallback))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Net.Security.SslStream))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.AuthenticationException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.ExtendedProtection.PolicyEnforcement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.ExtendedProtection.ProtectionScenario))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.ExtendedProtection.ServiceNameCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Authentication.InvalidCredentialException))]
--- /dev/null
+//
+// SocketReceiveFromResult.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Net.Sockets
+{
+ public struct SocketReceiveFromResult
+ {
+ public int ReceivedBytes;
+ public EndPoint RemoteEndPoint;
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SocketReceiveMessageFromResult.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Net.Sockets
+{
+ public struct SocketReceiveMessageFromResult
+ {
+ public int ReceivedBytes;
+ public SocketFlags SocketFlags;
+ public EndPoint RemoteEndPoint;
+ public IPPacketInformation PacketInformation;
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Net.Sockets
+{
+ public static class SocketTaskExtensions
+ {
+ public static Task<Socket> AcceptAsync(this Socket socket)
+ {
+ return Task<Socket>.Factory.FromAsync(
+ (callback, state) => ((Socket)state).BeginAccept(callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndAccept(asyncResult),
+ state: socket);
+ }
+
+ public static Task<Socket> AcceptAsync(this Socket socket, Socket acceptSocket)
+ {
+ const int ReceiveSize = 0;
+ return Task<Socket>.Factory.FromAsync(
+ (socketForAccept, receiveSize, callback, state) => ((Socket)state).BeginAccept(socketForAccept, receiveSize, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndAccept(asyncResult),
+ acceptSocket,
+ ReceiveSize,
+ state: socket);
+ }
+
+ public static Task ConnectAsync(this Socket socket, EndPoint remoteEndPoint)
+ {
+ return Task.Factory.FromAsync(
+ (targetEndPoint, callback, state) => ((Socket)state).BeginConnect(targetEndPoint, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
+ remoteEndPoint,
+ state: socket);
+ }
+
+ public static Task ConnectAsync(this Socket socket, IPAddress address, int port)
+ {
+ return Task.Factory.FromAsync(
+ (targetAddress, targetPort, callback, state) => ((Socket)state).BeginConnect(targetAddress, targetPort, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
+ address,
+ port,
+ state: socket);
+ }
+
+ public static Task ConnectAsync(this Socket socket, IPAddress[] addresses, int port)
+ {
+ return Task.Factory.FromAsync(
+ (targetAddresses, targetPort, callback, state) => ((Socket)state).BeginConnect(targetAddresses, targetPort, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
+ addresses,
+ port,
+ state: socket);
+ }
+
+ public static Task ConnectAsync(this Socket socket, string host, int port)
+ {
+ return Task.Factory.FromAsync(
+ (targetHost, targetPort, callback, state) => ((Socket)state).BeginConnect(targetHost, targetPort, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndConnect(asyncResult),
+ host,
+ port,
+ state: socket);
+ }
+
+ public static Task<int> ReceiveAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffer, flags, callback, state) => ((Socket)state).BeginReceive(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ flags,
+ callback,
+ state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndReceive(asyncResult),
+ buffer,
+ socketFlags,
+ state: socket);
+ }
+
+ public static Task<int> ReceiveAsync(
+ this Socket socket,
+ IList<ArraySegment<byte>> buffers,
+ SocketFlags socketFlags)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffers, flags, callback, state) => ((Socket)state).BeginReceive(targetBuffers, flags, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndReceive(asyncResult),
+ buffers,
+ socketFlags,
+ state: socket);
+ }
+
+ public static Task<SocketReceiveFromResult> ReceiveFromAsync(
+ this Socket socket,
+ ArraySegment<byte> buffer,
+ SocketFlags socketFlags,
+ EndPoint remoteEndPoint)
+ {
+ object[] packedArguments = new object[] { socket, remoteEndPoint };
+
+ return Task<SocketReceiveFromResult>.Factory.FromAsync(
+ (targetBuffer, flags, callback, state) =>
+ {
+ var arguments = (object[])state;
+ var s = (Socket)arguments[0];
+ var e = (EndPoint)arguments[1];
+
+ IAsyncResult result = s.BeginReceiveFrom(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ flags,
+ ref e,
+ callback,
+ state);
+
+ arguments[1] = e;
+ return result;
+ },
+ asyncResult =>
+ {
+ var arguments = (object[])asyncResult.AsyncState;
+ var s = (Socket)arguments[0];
+ var e = (EndPoint)arguments[1];
+
+ int bytesReceived = s.EndReceiveFrom(asyncResult, ref e);
+
+ return new SocketReceiveFromResult()
+ {
+ ReceivedBytes = bytesReceived,
+ RemoteEndPoint = e
+ };
+ },
+ buffer,
+ socketFlags,
+ state: packedArguments);
+ }
+
+ public static Task<SocketReceiveMessageFromResult> ReceiveMessageFromAsync(
+ this Socket socket,
+ ArraySegment<byte> buffer,
+ SocketFlags socketFlags,
+ EndPoint remoteEndPoint)
+ {
+ object[] packedArguments = new object[] { socket, socketFlags, remoteEndPoint };
+
+ return Task<SocketReceiveMessageFromResult>.Factory.FromAsync(
+ (targetBuffer, callback, state) =>
+ {
+ var arguments = (object[])state;
+ var s = (Socket)arguments[0];
+ var f = (SocketFlags)arguments[1];
+ var e = (EndPoint)arguments[2];
+
+ IAsyncResult result = s.BeginReceiveMessageFrom(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ f,
+ ref e,
+ callback,
+ state);
+
+ arguments[2] = e;
+ return result;
+ },
+ asyncResult =>
+ {
+ var arguments = (object[])asyncResult.AsyncState;
+ var s = (Socket)arguments[0];
+ var f = (SocketFlags)arguments[1];
+ var e = (EndPoint)arguments[2];
+ IPPacketInformation ipPacket;
+
+ int bytesReceived = s.EndReceiveMessageFrom(
+ asyncResult,
+ ref f,
+ ref e,
+ out ipPacket);
+
+ return new SocketReceiveMessageFromResult()
+ {
+ PacketInformation = ipPacket,
+ ReceivedBytes = bytesReceived,
+ RemoteEndPoint = e,
+ SocketFlags = f
+ };
+ },
+ buffer,
+ state: packedArguments);
+ }
+
+ public static Task<int> SendAsync(this Socket socket, ArraySegment<byte> buffer, SocketFlags socketFlags)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffer, flags, callback, state) => ((Socket)state).BeginSend(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ flags,
+ callback,
+ state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndSend(asyncResult),
+ buffer,
+ socketFlags,
+ state: socket);
+ }
+
+ public static Task<int> SendAsync(
+ this Socket socket,
+ IList<ArraySegment<byte>> buffers,
+ SocketFlags socketFlags)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffers, flags, callback, state) => ((Socket)state).BeginSend(targetBuffers, flags, callback, state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndSend(asyncResult),
+ buffers,
+ socketFlags,
+ state: socket);
+ }
+
+ public static Task<int> SendToAsync(
+ this Socket socket,
+ ArraySegment<byte> buffer,
+ SocketFlags socketFlags,
+ EndPoint remoteEndPoint)
+ {
+ return Task<int>.Factory.FromAsync(
+ (targetBuffer, flags, endPoint, callback, state) => ((Socket)state).BeginSendTo(
+ targetBuffer.Array,
+ targetBuffer.Offset,
+ targetBuffer.Count,
+ flags,
+ endPoint,
+ callback,
+ state),
+ asyncResult => ((Socket)asyncResult.AsyncState).EndSendTo(asyncResult),
+ buffer,
+ socketFlags,
+ remoteEndPoint,
+ state: socket);
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
-
+SocketReceiveFromResult.cs
+SocketReceiveMessageFromResult.cs
+SocketTaskExtensions.cs
+++ /dev/null
-//
-// Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-[assembly: AssemblyTitle ("System.Private.CoreLib.Threading.dll")]
-[assembly: AssemblyDescription ("System.Private.CoreLib.Threading.dll")]
-[assembly: AssemblyDefaultAlias ("System.Private.CoreLib.Threading.dll")]
-[assembly: AssemblyCompany ("Xamarin, Inc.")]
-[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
-[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
-[assembly: AssemblyInformationalVersion ("4.0.0.0")]
-[assembly: AssemblyFileVersion ("4.0.0.0")]
-[assembly: AssemblyDelaySign (true)]
-[assembly: AssemblyKeyFile ("../../msfinal.pub")]
-
-[assembly: ReferenceAssembly]
-
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <PropertyGroup>\r
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
- <ProductVersion>9.0.30729</ProductVersion>\r
- <SchemaVersion>2.0</SchemaVersion>\r
- <ProjectGuid>{642A1B9E-1A2F-4C55-B184-E22F8C2E95B5}</ProjectGuid>\r
- <OutputType>Library</OutputType>\r
- <NoWarn>1699,1616,1699</NoWarn>\r
- <OutputPath>./../../../class/lib/net_4_x/Facades</OutputPath>\r
- <IntermediateOutputPath>obj-Facades</IntermediateOutputPath>\r
- <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>\r
- <NoStdLib>True</NoStdLib>\r
- \r
- <NoConfig>True</NoConfig>\r
- \r
- <AppDesignerFolder>Properties</AppDesignerFolder>\r
- <RootNamespace>\r
- </RootNamespace>\r
- <AssemblyName>System.Private.CoreLib.Threading</AssemblyName>\r
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
- <FileAlignment>512</FileAlignment>\r
- </PropertyGroup>\r
- <PropertyGroup>\r
- <SignAssembly>true</SignAssembly>\r
- <DelaySign>true</DelaySign>\r
- </PropertyGroup>\r
- <PropertyGroup>\r
- <AssemblyOriginatorKeyFile>../../msfinal.pub</AssemblyOriginatorKeyFile>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
- <DebugSymbols>true</DebugSymbols>\r
- <DebugType>full</DebugType>\r
- <NoWarn>1699,1616,1699</NoWarn>\r
- <Optimize>false</Optimize>\r
- <DefineConstants>TRACE;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
- <ErrorReport>prompt</ErrorReport>\r
- <WarningLevel>4</WarningLevel>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
- <DebugType>pdbonly</DebugType>\r
- <NoWarn>1699,1616,1699</NoWarn>\r
- <Optimize>true</Optimize>\r
- <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
- <ErrorReport>prompt</ErrorReport>\r
- <WarningLevel>4</WarningLevel>\r
- </PropertyGroup>\r
- <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
- Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
- is a problem to compile the Mono mscorlib.dll -->\r
- <PropertyGroup>\r
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
- </PropertyGroup>\r
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
- <ItemGroup>\r
- <Compile Include="AssemblyInfo.cs" />\r
- <Compile Include="TypeForwarders.cs" />\r </ItemGroup>\r
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
- Other similar extension points exist, see Microsoft.Common.targets.\r
- <Target Name="BeforeBuild">\r
- </Target>\r
- <Target Name="AfterBuild">\r
- </Target>\r
- -->\r
- <PropertyGroup>\r
- <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
-
- </PreBuildEvent>\r
- <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
- </PreBuildEvent>\r
- <PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
-
- </PostBuildEvent>\r
- <PostBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
- </PostBuildEvent>\r
- </PropertyGroup>\r
- <ItemGroup>\r
- <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
- <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
- <Name>corlib-net_4_x</Name>\r
- </ProjectReference>\r
- <ProjectReference Include="../../System/System-net_4_x.csproj">\r
- <Project>{2762E921-91A8-4C87-91E9-BA628013F753}</Project>\r
- <Name>System-net_4_x</Name>\r
- </ProjectReference>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Folder Include="Properties\" />\r
- </ItemGroup>\r
-</Project>\r
-
+++ /dev/null
-MCS_BUILD_DIR = ../../../build
-
-thisdir = class/Facades/System.Private.CoreLib.Threading
-SUBDIRS =
-include $(MCS_BUILD_DIR)/rules.make
-
-LIBRARY_SUBDIR = Facades
-LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
-
-LIBRARY = System.Private.CoreLib.Threading.dll
-
-KEY_FILE = ../../msfinal.pub
-SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System
-LIB_MCS_FLAGS = $(SIGN_FLAGS)
-
-PLATFORM_DEBUG_FLAGS =
-
-NO_TEST = yes
-
-include $(MCS_BUILD_DIR)/library.make
-
-
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <PropertyGroup>\r
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
- <ProductVersion>9.0.30729</ProductVersion>\r
- <SchemaVersion>2.0</SchemaVersion>\r
- <ProjectGuid>{A577B5A0-5038-4D8E-8C80-18ED9FEC8686}</ProjectGuid>\r
- <OutputType>Library</OutputType>\r
- <NoWarn>1699,1616,1699</NoWarn>\r
- <OutputPath>./../../../class/lib/net_4_x/Facades</OutputPath>\r
- <NoStdLib>True</NoStdLib>\r
- <NoConfig>True</NoConfig>\r
- \r
- <AppDesignerFolder>Properties</AppDesignerFolder>\r
- <RootNamespace>\r
- </RootNamespace>\r
- <AssemblyName>System.Private.CoreLib.Threading</AssemblyName>\r
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
- <FileAlignment>512</FileAlignment>\r
- </PropertyGroup>\r
- <PropertyGroup>\r
- <SignAssembly>true</SignAssembly>\r
- <DelaySign>true</DelaySign>\r
- </PropertyGroup>\r
- <PropertyGroup>\r
- <AssemblyOriginatorKeyFile>../../msfinal.pub</AssemblyOriginatorKeyFile>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
- <DebugSymbols>true</DebugSymbols>\r
- <DebugType>full</DebugType>\r
- <NoWarn>1699,1616,1699</NoWarn>\r
- <Optimize>false</Optimize>\r
- <DefineConstants>DEBUG;TRACE;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
- <ErrorReport>prompt</ErrorReport>\r
- <WarningLevel>4</WarningLevel>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
- <DebugType>pdbonly</DebugType>\r
- <NoWarn>1699,1616,1699</NoWarn>\r
- <Optimize>true</Optimize>\r
- <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
- <ErrorReport>prompt</ErrorReport>\r
- <WarningLevel>4</WarningLevel>\r
- </PropertyGroup>\r
- <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
- Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
- is a problem to compile the Mono mscorlib.dll -->\r
- <PropertyGroup>\r
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
- </PropertyGroup>\r
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
- <ItemGroup>\r
- <Compile Include="AssemblyInfo.cs" />\r
- <Compile Include="TypeForwarders.cs" />\r </ItemGroup>\r
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
- Other similar extension points exist, see Microsoft.Common.targets.\r
- <Target Name="BeforeBuild">\r
- </Target>\r
- <Target Name="AfterBuild">\r
- </Target>\r
- -->\r
- <PropertyGroup>\r
- <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">\r
-\r
- </PreBuildEvent>\r
- <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
- </PreBuildEvent>\r
-\r
- <PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">\r
-\r
- </PostBuildEvent>\r
- <PostBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
- </PostBuildEvent>\r
- </PropertyGroup>\r
- <ItemGroup>\r
- <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
- <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
- <Name>corlib-net_4_x</Name>\r
- </ProjectReference>\r
- <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
- <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
- <Name>corlib-net_4_x</Name>\r
- </ProjectReference>\r
- <ProjectReference Include="../../System/System-net_4_x.csproj">\r
- <Project>{2762E921-91A8-4C87-91E9-BA628013F753}</Project>\r
- <Name>System-net_4_x</Name>\r
- </ProjectReference>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Folder Include="Properties\" />\r
- </ItemGroup>\r
-</Project>\r
-
+++ /dev/null
-TypeForwarders.cs
-AssemblyInfo.cs
-
+++ /dev/null
-//
-// Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.AbandonedMutexException))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.AutoResetEvent))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.EventResetMode))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.EventWaitHandle))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.Interlocked))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.LazyInitializer))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.ManualResetEvent))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.Monitor))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.Mutex))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.Semaphore))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.SemaphoreFullException))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.SpinWait))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.SynchronizationLockException))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.Volatile))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.WaitHandleCannotBeOpenedException))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.Condition))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.Lock))]
// THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.FlowControl))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.OpCode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.OpCodes))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.OperandType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.PackingSize))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.StackBehaviour))]
-#endif
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.CallingConventions))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.EventAttributes))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.FieldAttributes))]
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Reflection
+{
+ internal static class Requires
+ {
+ internal static void NotNull(object obj, string name)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException(name);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+partial class SR
+{
+ public const string NoMetadataTokenAvailable = "There is no metadata token available for the given member.";
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+SR.cs
+Requires.cs
+TypeExtensions.CoreCLR.cs
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// NOTE: These are extension methods in the contract, but plain static methods
+// in this implementation. This is done to avoid confusion around what would
+// look like infinite recursion in the implementation. Callers compiled against
+// the contract will still be able to invoke them as extension methods and get
+// source compatibility with classic reflection code.
+//
+// However, this does not apply if there is no 1:1 correspondence with an instance
+// in mscorlib. New extension methods should be marked with 'this'.
+
+namespace System.Reflection
+{
+ public static class TypeExtensions
+ {
+ public static ConstructorInfo GetConstructor(Type type, Type[] types)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetConstructor(types);
+ }
+
+ public static ConstructorInfo[] GetConstructors(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetConstructors();
+ }
+
+ public static ConstructorInfo[] GetConstructors(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetConstructors(bindingAttr);
+ }
+
+ public static MemberInfo[] GetDefaultMembers(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetDefaultMembers();
+ }
+
+ public static EventInfo GetEvent(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetEvent(name);
+ }
+
+ public static EventInfo GetEvent(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetEvent(name, bindingAttr);
+ }
+
+ public static EventInfo[] GetEvents(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetEvents();
+ }
+
+ public static EventInfo[] GetEvents(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetEvents(bindingAttr);
+ }
+
+ public static FieldInfo GetField(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetField(name);
+ }
+
+ public static FieldInfo GetField(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetField(name, bindingAttr);
+ }
+
+ public static FieldInfo[] GetFields(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetFields();
+ }
+
+ public static FieldInfo[] GetFields(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetFields(bindingAttr);
+ }
+
+ public static Type[] GetGenericArguments(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetGenericArguments();
+ }
+
+ public static Type[] GetInterfaces(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetInterfaces();
+ }
+
+ public static MemberInfo[] GetMember(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMember(name);
+ }
+
+ public static MemberInfo[] GetMember(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMember(name, bindingAttr);
+ }
+
+ public static MemberInfo[] GetMembers(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMembers();
+ }
+
+ public static MemberInfo[] GetMembers(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMembers(bindingAttr);
+ }
+
+ public static MethodInfo GetMethod(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethod(name);
+ }
+
+ public static MethodInfo GetMethod(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethod(name, bindingAttr);
+ }
+
+ public static MethodInfo GetMethod(Type type, string name, Type[] types)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethod(name, types);
+ }
+
+ public static MethodInfo[] GetMethods(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethods();
+ }
+
+ public static MethodInfo[] GetMethods(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetMethods(bindingAttr);
+ }
+
+ public static Type GetNestedType(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetNestedType(name, bindingAttr);
+ }
+
+ public static Type[] GetNestedTypes(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetNestedTypes(bindingAttr);
+ }
+
+ public static PropertyInfo[] GetProperties(Type type)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperties();
+ }
+
+ public static PropertyInfo[] GetProperties(Type type, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperties(bindingAttr);
+ }
+
+ public static PropertyInfo GetProperty(Type type, string name)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperty(name);
+ }
+
+ public static PropertyInfo GetProperty(Type type, string name, BindingFlags bindingAttr)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperty(name, bindingAttr);
+ }
+
+ public static PropertyInfo GetProperty(Type type, string name, Type returnType)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperty(name, returnType);
+ }
+
+ public static PropertyInfo GetProperty(Type type, string name, Type returnType, Type[] types)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.GetProperty(name, returnType, types);
+ }
+
+ public static bool IsAssignableFrom(Type type, Type c)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.IsAssignableFrom(c);
+ }
+
+ public static bool IsInstanceOfType(Type type, object o)
+ {
+ Requires.NotNull(type, nameof(type));
+ return type.IsInstanceOfType(o);
+ }
+ }
+
+ public static class AssemblyExtensions
+ {
+ public static Type[] GetExportedTypes(Assembly assembly)
+ {
+ Requires.NotNull(assembly, nameof(assembly));
+ return assembly.GetExportedTypes();
+ }
+
+ public static Module[] GetModules(Assembly assembly)
+ {
+ Requires.NotNull(assembly, nameof(assembly));
+ return assembly.GetModules();
+ }
+
+ public static Type[] GetTypes(Assembly assembly)
+ {
+ Requires.NotNull(assembly, nameof(assembly));
+ return assembly.GetTypes();
+ }
+ }
+
+ public static class EventInfoExtensions
+ {
+ public static MethodInfo GetAddMethod(EventInfo eventInfo)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetAddMethod();
+ }
+
+ public static MethodInfo GetAddMethod(EventInfo eventInfo, bool nonPublic)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetAddMethod(nonPublic);
+ }
+
+ public static MethodInfo GetRaiseMethod(EventInfo eventInfo)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetRaiseMethod();
+ }
+
+ public static MethodInfo GetRaiseMethod(EventInfo eventInfo, bool nonPublic)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetRaiseMethod(nonPublic);
+ }
+
+ public static MethodInfo GetRemoveMethod(EventInfo eventInfo)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetRemoveMethod();
+ }
+
+ public static MethodInfo GetRemoveMethod(EventInfo eventInfo, bool nonPublic)
+ {
+ Requires.NotNull(eventInfo, nameof(eventInfo));
+ return eventInfo.GetRemoveMethod(nonPublic);
+ }
+ }
+
+ public static class MemberInfoExtensions
+ {
+
+ /// <summary>
+ /// Determines if there is a metadata token available for the given member.
+ /// <see cref="GetMetadataToken(MemberInfo)"/> throws <see cref="InvalidOperationException"/> otherwise.
+ /// </summary>
+ /// <remarks>This maybe</remarks>
+ public static bool HasMetadataToken(this MemberInfo member)
+ {
+ Requires.NotNull(member, nameof(member));
+
+ try
+ {
+ return GetMetadataTokenOrZeroOrThrow(member) != 0;
+ }
+ catch (InvalidOperationException)
+ {
+ // Thrown for unbaked ref-emit members/types.
+ // Other cases such as typeof(byte[]).MetadataToken will be handled by comparison to zero above.
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Gets a metadata token for the given member if available. The returned token is never nil.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">
+ /// There is no metadata token available. <see cref="HasMetadataToken(MemberInfo)"/> returns false in this case.
+ /// </exception>
+ public static int GetMetadataToken(this MemberInfo member)
+ {
+ Requires.NotNull(member, nameof(member));
+
+ int token = GetMetadataTokenOrZeroOrThrow(member);
+
+ if (token == 0)
+ {
+ throw new InvalidOperationException(SR.NoMetadataTokenAvailable);
+ }
+
+ return token;
+ }
+
+ private static int GetMetadataTokenOrZeroOrThrow(MemberInfo member)
+ {
+ int token = member.MetadataToken;
+
+ // Tokens have MSB = table index, 3 LSBs = row index
+ // row index of 0 is a nil token
+ const int rowMask = 0x00FFFFFF;
+ if ((token & rowMask) == 0)
+ {
+ // Nil token is returned for edge cases like typeof(byte[]).MetadataToken.
+ return 0;
+ }
+
+ return token;
+ }
+ }
+
+ public static class MethodInfoExtensions
+ {
+ public static MethodInfo GetBaseDefinition(MethodInfo method)
+ {
+ Requires.NotNull(method, nameof(method));
+ return method.GetBaseDefinition();
+ }
+ }
+
+ public static class ModuleExtensions
+ {
+ public static bool HasModuleVersionId(this Module module)
+ {
+ Requires.NotNull(module, nameof(module));
+ return true; // not expected to fail on platforms with Module.ModuleVersionId built-in.
+ }
+
+ public static Guid GetModuleVersionId(this Module module)
+ {
+ Requires.NotNull(module, nameof(module));
+ return module.ModuleVersionId;
+ }
+ }
+
+ public static class PropertyInfoExtensions
+ {
+ public static MethodInfo[] GetAccessors(PropertyInfo property)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetAccessors();
+ }
+
+ public static MethodInfo[] GetAccessors(PropertyInfo property, bool nonPublic)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetAccessors(nonPublic);
+ }
+
+ public static MethodInfo GetGetMethod(PropertyInfo property)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetGetMethod();
+ }
+
+ public static MethodInfo GetGetMethod(PropertyInfo property, bool nonPublic)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetGetMethod(nonPublic);
+ }
+
+ public static MethodInfo GetSetMethod(PropertyInfo property)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetSetMethod();
+ }
+
+ public static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic)
+ {
+ Requires.NotNull(property, nameof(property));
+ return property.GetSetMethod(nonPublic);
+ }
+ }
+}
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.BindingFlags))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.AssemblyExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.EventInfoExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.MethodInfoExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.PropertyInfoExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.TypeExtensions))]
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Runtime.Serialization.Formatters.dll")]
+[assembly: AssemblyDescription ("System.Runtime.Serialization.Formatters.dll")]
+[assembly: AssemblyDefaultAlias ("System.Runtime.Serialization.Formatters.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Runtime.Serialization.Formatters
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Runtime.Serialization.Formatters.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.NonSerializedAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.IDeserializationCallback))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.IFormatterConverter))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.ISerializable))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationEntry))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationInfoEnumerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.SerializableAttribute))]
+
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+namespace System.Runtime.Serialization
+{
+ public interface ISerializationSurrogateProvider
+ {
+ object GetDeserializedObject (object obj, Type targetType);
+ object GetObjectToSerialize (object obj, Type targetType);
+ Type GetSurrogateType (Type type);
+ }
+}
+
TypeForwarders.cs
AssemblyInfo.cs
-
+ISerializationSurrogateProvider.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.OnSerializingAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.SerializationException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.StreamingContext))]
-
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.Serialization.InvalidDataContractException))]
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#if !NO_CODEDOM
+using System.CodeDom;
+#endif
+using System.Collections.ObjectModel;
+using System.Reflection;
+
+namespace System.Runtime.Serialization
+{
+ public static class DataContractSerializerExtensions
+ {
+ public static ISerializationSurrogateProvider GetSerializationSurrogateProvider(this DataContractSerializer serializer)
+ {
+ SurrogateProviderAdapter adapter = serializer.DataContractSurrogate as SurrogateProviderAdapter;
+ return (adapter == null) ? null : adapter.Provider;
+ }
+
+ public static void SetSerializationSurrogateProvider(this DataContractSerializer serializer, ISerializationSurrogateProvider provider)
+ {
+ // allocate every time, expectation is that this won't happen enough to warrant maintaining a CondtionalWeakTable.
+ IDataContractSurrogate adapter = new SurrogateProviderAdapter(provider);
+
+ // DCS doesn't expose a setter, access the field directly as a workaround
+ typeof(DataContractSerializer)
+ .GetField("dataContractSurrogate", BindingFlags.Instance | BindingFlags.NonPublic)
+ .SetValue(serializer, adapter);
+ }
+
+ private class SurrogateProviderAdapter : IDataContractSurrogate
+ {
+ private ISerializationSurrogateProvider _provider;
+ public SurrogateProviderAdapter(ISerializationSurrogateProvider provider)
+ {
+ _provider = provider;
+ }
+
+ public ISerializationSurrogateProvider Provider { get { return _provider; } }
+ public object GetCustomDataToExport(Type clrType, Type dataContractType)
+ {
+ throw NotImplemented.ByDesign;
+ }
+
+ public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
+ {
+ throw NotImplemented.ByDesign;
+ }
+
+ public Type GetDataContractType(Type type)
+ {
+ return _provider.GetSurrogateType(type);
+ }
+
+ public object GetDeserializedObject(object obj, Type targetType)
+ {
+ return _provider.GetDeserializedObject(obj, targetType);
+ }
+
+ public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
+ {
+ throw NotImplemented.ByDesign;
+ }
+
+ public object GetObjectToSerialize(object obj, Type targetType)
+ {
+ return _provider.GetObjectToSerialize(obj, targetType);
+ }
+
+ public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
+ {
+ throw NotImplemented.ByDesign;
+ }
+
+#if !NO_CODEDOM
+ public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
+ {
+ throw NotImplemented.ByDesign;
+ }
+#endif
+ }
+ }
+}
\ No newline at end of file
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System.Runtime.Serialization System.Xml
+LIB_REFS = System System.Runtime.Serialization System.Xml Facades/System.Runtime.Serialization.Primitives
LIB_MCS_FLAGS = $(SIGN_FLAGS)
+ifeq (2.1, $(FRAMEWORK_VERSION))
+LIB_MCS_FLAGS += /d:NO_CODEDOM
+endif
+
PLATFORM_DEBUG_FLAGS =
NO_TEST = yes
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System
+{
+ //
+ // This class enables one to throw a NotImplementedException using the following idiom:
+ //
+ // throw NotImplemented.ByDesign;
+ //
+ // Used by methods whose intended implementation is to throw a NotImplementedException (typically
+ // virtual methods in public abstract classes that intended to be subclassed by third parties.)
+ //
+ // This makes it distinguishable both from human eyes and CCI from NYI's that truly represent undone work.
+ //
+ internal static class NotImplemented
+ {
+ internal static Exception ByDesign
+ {
+ get
+ {
+ return new NotImplementedException();
+ }
+ }
+
+ internal static Exception ByDesignWithMessage(String message)
+ {
+ return new NotImplementedException(message);
+ }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+
+DataContractSerializerExtensions.cs
+NotImplemented.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XmlDictionaryWriter))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.OnXmlDictionaryReaderClose))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XmlDictionaryReaderQuotaTypes))]
--- /dev/null
+//
+// ECCurve.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct ECCurve
+ {
+ public byte[] A;
+ public byte[] B;
+ public byte[] Cofactor;
+ public ECCurveType CurveType;
+ public ECPoint G;
+ public HashAlgorithmName? Hash;
+ public byte[] Order;
+ public byte[] Polynomial;
+ public byte[] Prime;
+ public byte[] Seed;
+ public bool IsCharacteristic2 { get { throw new NotImplementedException (); } }
+ public bool IsExplicit { get { throw new NotImplementedException (); } }
+ public bool IsNamed { get { throw new NotImplementedException (); } }
+ public bool IsPrime { get { throw new NotImplementedException (); } }
+ public Oid Oid { get { throw new NotImplementedException (); } }
+ public static ECCurve CreateFromFriendlyName (string oidFriendlyName) { throw new NotImplementedException (); }
+ public static ECCurve CreateFromOid (Oid curveOid) { throw new NotImplementedException (); }
+ public static ECCurve CreateFromValue (string oidValue) { throw new NotImplementedException (); }
+ public void Validate () { throw new NotImplementedException (); }
+
+ public enum ECCurveType
+ {
+ Implicit = 0,
+ PrimeShortWeierstrass = 1,
+ PrimeTwistedEdwards = 2,
+ PrimeMontgomery = 3,
+ Characteristic2 = 4,
+ Named = 5,
+ }
+
+ public static class NamedCurves
+ {
+ public static ECCurve brainpoolP160r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP160t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP192r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP192t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP224r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP224t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP256r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP256t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP320r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP320t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP384r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP384t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP512r1 { get { throw new NotImplementedException (); } }
+ public static ECCurve brainpoolP512t1 { get { throw new NotImplementedException (); } }
+ public static ECCurve nistP256 { get { throw new NotImplementedException (); } }
+ public static ECCurve nistP384 { get { throw new NotImplementedException (); } }
+ public static ECCurve nistP521 { get { throw new NotImplementedException (); } }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// ECPArameters.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public partial struct ECParameters
+ {
+ public ECCurve Curve;
+ public byte[] D;
+ public ECPoint Q;
+ public void Validate () { throw new NotImplementedException (); }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// ECPoint.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct ECPoint
+ {
+ public byte[] X;
+ public byte[] Y;
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// IncrementalHash.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class IncrementalHash : IDisposable
+ {
+ private IncrementalHash () { }
+ public HashAlgorithmName AlgorithmName { get { throw new NotImplementedException (); } }
+ public void AppendData (byte[] data) { }
+ public void AppendData (byte[] data, int offset, int count) { }
+ public static IncrementalHash CreateHash (HashAlgorithmName hashAlgorithm) { throw new NotImplementedException (); }
+ public static IncrementalHash CreateHMAC (HashAlgorithmName hashAlgorithm, byte[] key) { throw new NotImplementedException (); }
+ public void Dispose () { }
+ public byte[] GetHashAndReset () { throw new NotImplementedException (); }
+ }
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
-
+ECCurve.cs
+ECPoint.cs
+ECParameters.cs
+IncrementalHash.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Security.Cryptography.Cng.dll")]
+[assembly: AssemblyDescription ("System.Security.Cryptography.Cng.dll")]
+[assembly: AssemblyDefaultAlias ("System.Security.Cryptography.Cng.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Security.Cryptography.Cng
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Security.Cryptography.Cng.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System System.Core
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeNCryptHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeNCryptProviderHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.AesCng))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngAlgorithm))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngAlgorithmGroup))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngExportPolicies))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKey))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyBlobFormat))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyCreationOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyCreationParameters))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyHandleOpenOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyOpenOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngKeyUsages))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngProperty))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngPropertyCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngPropertyOptions))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngProvider))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngUIPolicy))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CngUIProtectionLevels))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ECDsaCng))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSACng))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.TripleDESCng))]
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Security.Cryptography.Csp.dll")]
+[assembly: AssemblyDescription ("System.Security.Cryptography.Csp.dll")]
+[assembly: AssemblyDefaultAlias ("System.Security.Cryptography.Csp.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Security.Cryptography.Csp
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Security.Cryptography.Csp.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CspKeyContainerInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CspParameters))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CspProviderFlags))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.ICspAsymmetricAlgorithm))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.KeyNumber))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.RSACryptoServiceProvider))]
+
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Security.Cryptography.OpenSsl.dll")]
+[assembly: AssemblyDescription ("System.Security.Cryptography.OpenSsl.dll")]
+[assembly: AssemblyDefaultAlias ("System.Security.Cryptography.OpenSsl.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+//
+// ECDsaOpenSsl.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class ECDsaOpenSsl : ECDsa
+ {
+ public override byte[] SignHash (byte[] hash)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool VerifyHash (byte[] hash, byte[] signature)
+ {
+ throw new NotImplementedException ();
+ }
+
+ // TODO: Implement full contract API
+ }
+}
\ No newline at end of file
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Security.Cryptography.OpenSsl
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Security.Cryptography.OpenSsl.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System.Core
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+//
+// RSAOpenSsl.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class RSAOpenSsl : RSA
+ {
+ public override RSAParameters ExportParameters (bool includePrivateParameters)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void ImportParameters (RSAParameters parameters)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override byte[] SignHash (byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool VerifyHash (byte[] hash, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
+ {
+ throw new NotImplementedException ();
+ }
+
+ // TODO: Implement full contract API
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SafeEvpPKeyHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class SafeEvpPKeyHandle : System.Runtime.InteropServices.SafeHandle
+ {
+ public SafeEvpPKeyHandle (IntPtr handle, bool ownsHandle)
+ : base (handle, ownsHandle)
+ {
+ }
+
+ public override bool IsInvalid { get { throw new NotImplementedException (); } }
+
+ public SafeEvpPKeyHandle DuplicateHandle ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected override bool ReleaseHandle ()
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+AssemblyInfo.cs
+ECDsaOpenSsl.cs
+RSAOpenSsl.cs
+SafeEvpPKeyHandle.cs
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Security.Cryptography.Pkcs.dll")]
+[assembly: AssemblyDescription ("System.Security.Cryptography.Pkcs.dll")]
+[assembly: AssemblyDefaultAlias ("System.Security.Cryptography.Pkcs.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Security.Cryptography.Pkcs
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Security.Cryptography.Pkcs.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System System.Security
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+TypeForwarders.cs
+AssemblyInfo.cs
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CryptographicAttributeObject))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CryptographicAttributeObjectCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.CryptographicAttributeObjectEnumerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.AlgorithmIdentifier))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.CmsRecipient))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.CmsRecipientCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.CmsRecipientEnumerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.ContentInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.EnvelopedCms))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.KeyAgreeRecipientInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.KeyTransRecipientInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9AttributeObject))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9ContentType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9DocumentDescription))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9DocumentName))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9MessageDigest))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.Pkcs9SigningTime))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.PublicKeyInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.RecipientInfo))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.RecipientInfoCollection))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.RecipientInfoEnumerator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.RecipientInfoType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.SubjectIdentifier))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.SubjectIdentifierOrKey))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.SubjectIdentifierOrKeyType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Pkcs.SubjectIdentifierType))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Cryptography.Xml.X509IssuerSerial))]
+
+
// THE SOFTWARE.
//
-//TODO:[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeAccessTokenHandle))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.Win32.SafeHandles.SafeAccessTokenHandle))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Principal.IdentityNotMappedException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Principal.IdentityReference))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.Principal.IdentityReferenceCollection))]
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+namespace System.Security
+{
+ public static class SecureStringMarshal
+ {
+ public static IntPtr SecureStringToCoTaskMemAnsi (SecureString s)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static IntPtr SecureStringToCoTaskMemUnicode (SecureString s)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static IntPtr SecureStringToGlobalAllocAnsi (SecureString s)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static IntPtr SecureStringToGlobalAllocUnicode (SecureString s)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
TypeForwarders.cs
AssemblyInfo.cs
-
+SecureStringMarshal.cs
//
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.SecureString))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.SecureStringMarshal))]
// THE SOFTWARE.
//
-#if !MOBILE && !XAMMAC_4_5
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.CallbackBehaviorAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DuplexChannelFactory<>))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DuplexClientBase<>))]
-#endif
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.InstanceContext))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpMessageCredentialType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpSecurity))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpSecurityMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpsBinding))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpsSecurity))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.BasicHttpsSecurityMode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.HttpRequestMessageProperty))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.HttpResponseMessageProperty))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.HttpsTransportBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.HttpClientCredentialType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.HttpTransportSecurity))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetHttpBinding))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetHttpsBinding))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetHttpMessageEncoding))]
// THE SOFTWARE.
//
-#if !MOBILE && !XAMMAC_4_5
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.ConnectionOrientedTransportBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.SslStreamSecurityBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.TcpConnectionPoolSettings))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetTcpBinding))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.NetTcpSecurity))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.TcpTransportSecurity))]
-#endif
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.TcpClientCredentialType))]
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System.ServiceModel System.Xml
+LIB_REFS = System System.ServiceModel System.Xml Facades/System.Security.Cryptography.X509Certificates
+
+ifneq (2.1, $(FRAMEWORK_VERSION))
+LIB_REFS += System.IdentityModel
+endif
+
LIB_MCS_FLAGS = $(SIGN_FLAGS)
PLATFORM_DEBUG_FLAGS =
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+X509ServiceCertificateAuthentication_mobile.cs
+X509CertificateValidator_mobile.cs
+X509CertificateValidationMode_mobile.cs
+X509CertificateRecipientClientCredential_mobile.cs
+X509CertificateInitiatorClientCredential_mobile.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageContractMemberAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageCredentialType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageHeader<>))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageHeaderAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageHeaderException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageParameterAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.OperationContext))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.UnknownMessageReceivedEventArgs))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.XmlSerializerFormatAttribute))]
+#if !MOBILE && !XAMMAC_4_5
+
+// TODO: These are implemented as stubs in the facade directly on mobile (contrary to Desktop where they're forwarded to System.ServiceModel.dll/System.IdentityModel.dll).
+// I'm not 100% sure this is the right approach, but Marek thinks it's fine so I'm sticking with it for now.
+// The problem on mobile is that types like X509CertificateValidator live in System.IdentityModel.dll which is not built for mobile.
+
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.IdentityModel.Selectors.X509CertificateValidator))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.X509CertificateValidationMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.X509ServiceCertificateAuthentication))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.X509CertificateInitiatorClientCredential))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.X509CertificateRecipientClientCredential))]
+
+#endif
--- /dev/null
+//
+// X509CertificateInitiatorClientCredential_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.ServiceModel.Security
+{
+ public sealed class X509CertificateInitiatorClientCredential
+ {
+ [MonoTODO]
+ public X509Certificate2 Certificate
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ internal X509CertificateInitiatorClientCredential()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetCertificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, object findValue)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetCertificate(string subjectName, StoreLocation storeLocation, StoreName storeName)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// X509CertificateRecipientClientCredential_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.ServiceModel.Security
+{
+ public sealed class X509CertificateRecipientClientCredential
+ {
+ [MonoTODO]
+ public X509ServiceCertificateAuthentication Authentication
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public X509Certificate2 DefaultCertificate
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public Dictionary<Uri, X509Certificate2> ScopedCertificates
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public X509ServiceCertificateAuthentication SslCertificateAuthentication
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ internal X509CertificateRecipientClientCredential ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetDefaultCertificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, object findValue)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetDefaultCertificate(string subjectName, StoreLocation storeLocation, StoreName storeName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetScopedCertificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, object findValue, Uri targetService)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void SetScopedCertificate(string subjectName, StoreLocation storeLocation, StoreName storeName, Uri targetService)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// X509CertificateValidationMode_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+namespace System.ServiceModel.Security
+{
+ public enum X509CertificateValidationMode
+ {
+ None,
+ PeerTrust,
+ ChainTrust,
+ PeerOrChainTrust,
+ Custom
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// X509CertificateValidator_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.IdentityModel.Selectors
+{
+ public abstract class X509CertificateValidator
+ {
+ public abstract void Validate (X509Certificate2 certificate);
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// X509ServiceCertificateAuthentication_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+using System.IdentityModel.Selectors;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.ServiceModel.Security
+{
+ public sealed class X509ServiceCertificateAuthentication
+ {
+ [MonoTODO]
+ public X509CertificateValidationMode CertificateValidationMode
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public X509CertificateValidator CustomCertificateValidator
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public X509RevocationMode RevocationMode
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public StoreLocation TrustedStoreLocation
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ set
+ {
+ throw new NotImplementedException ();
+ }
+ }
+ }
+}
+
+#endif
\ No newline at end of file
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.SecurityBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.SecurityHeaderLayout))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.TransportSecurityBindingElement))]
-#if !MOBILE
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DnsEndpointIdentity))]
-#if !XAMMAC_4_5
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.MessageSecurityVersion))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.SpnEndpointIdentity))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.UpnEndpointIdentity))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.BasicSecurityProfileVersion))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.SecureConversationVersion))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.SecurityPolicyVersion))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.SecurityVersion))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.TrustVersion))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.Tokens.SecureConversationSecurityTokenParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.Tokens.SecurityTokenParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.Tokens.SupportingTokenParameters))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.Tokens.UserNameSecurityTokenParameters))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Security.TrustVersion))]
-#endif
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.SpnEndpointIdentity))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.UpnEndpointIdentity))]
-#endif
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System System.ServiceProcess
+LIB_REFS = System
+
+ifneq (2.1, $(FRAMEWORK_VERSION))
+ifndef XAMMAC_4_5
+LIB_REFS += System.ServiceProcess
+endif
+endif
+
LIB_MCS_FLAGS = $(SIGN_FLAGS)
PLATFORM_DEBUG_FLAGS =
--- /dev/null
+//
+// ServiceControllerStatus_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+
+namespace System.ServiceProcess
+{
+ public enum ServiceControllerStatus
+ {
+ ContinuePending = 5,
+ Paused = 7,
+ PausePending = 6,
+ Running = 4,
+ StartPending = 2,
+ Stopped = 1,
+ StopPending = 3
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// ServiceController_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace System.ServiceProcess
+{
+ public class ServiceController : IDisposable
+ {
+ [MonoTODO]
+ public bool CanPauseAndContinue
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public bool CanShutdown
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public bool CanStop
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceController[] DependentServices
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public string DisplayName
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public string MachineName
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public SafeHandle ServiceHandle
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public string ServiceName
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceController[] ServicesDependedOn
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceType ServiceType
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceStartMode StartType
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceControllerStatus Status
+ {
+ get
+ {
+ throw new NotImplementedException ();
+ }
+ }
+
+ [MonoTODO]
+ public ServiceController (string name)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public ServiceController (string name, string machineName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Continue ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Dispose ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual void Dispose (bool disposing)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static ServiceController[] GetDevices ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static ServiceController[] GetDevices (string machineName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static ServiceController[] GetServices ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static ServiceController[] GetServices (string machineName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Pause ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Refresh ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Start ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Start (string[] args)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void Stop ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void WaitForStatus (ServiceControllerStatus desiredStatus)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public void WaitForStatus (ServiceControllerStatus desiredStatus, TimeSpan timeout)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// ServiceStartMode_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+
+namespace System.ServiceProcess
+{
+ public enum ServiceStartMode
+ {
+ Automatic = 2,
+ Boot = 0,
+ Disabled = 4,
+ Manual = 3,
+ System = 1
+ }
+}
+
+#endif
--- /dev/null
+//
+// ServiceType_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+
+namespace System.ServiceProcess
+{
+ [Flags]
+ public enum ServiceType
+ {
+ Adapter = 4,
+ FileSystemDriver = 2,
+ InteractiveProcess = 256,
+ KernelDriver = 1,
+ RecognizerDriver = 8,
+ Win32OwnProcess = 16,
+ Win32ShareProcess = 32
+ }
+}
+
+#endif
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+ServiceController_mobile.cs
+ServiceControllerStatus_mobile.cs
+ServiceStartMode_mobile.cs
+ServiceType_mobile.cs
+TimeoutException_mobile.cs
--- /dev/null
+//
+// TimeoutException_mobile.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if MOBILE || XAMMAC_4_5
+
+using System;
+
+namespace System.ServiceProcess
+{
+ public class TimeoutException : Exception
+ {
+ [MonoTODO]
+ public TimeoutException ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public TimeoutException (string message)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public TimeoutException (string message, Exception innerException)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
// THE SOFTWARE.
//
+#if !MOBILE && !XAMMAC_4_5
+
+// TODO: These are implemented as stubs in the facade directly on mobile
+
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.ServiceController))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.ServiceControllerStatus))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.ServiceStartMode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.ServiceType))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceProcess.TimeoutException))]
-
+#endif
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("System.Text.Encoding.CodePages.dll")]
+[assembly: AssemblyDescription ("System.Text.Encoding.CodePages.dll")]
+[assembly: AssemblyDefaultAlias ("System.Text.Encoding.CodePages.dll")]
+[assembly: AssemblyCompany ("Xamarin, Inc.")]
+[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
+[assembly: AssemblyCopyright ("Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)")]
+[assembly: AssemblyVersion ("4.0.0.0")]
+[assembly: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
--- /dev/null
+//
+// Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+namespace System.Text
+{
+ public sealed class CodePagesEncodingProvider : EncodingProvider
+ {
+ static readonly CodePagesEncodingProvider instance = new CodePagesEncodingProvider ();
+
+ private CodePagesEncodingProvider ()
+ {
+ }
+
+ public static EncodingProvider Instance {
+ get {
+ return instance;
+ }
+ }
+
+ public override Encoding GetEncoding (string name)
+ {
+ // MSDN: "if name is not the name of an encoding that you support, the method should return null."
+ // We do this here since all our encodings are already supported by the main Encoding class
+ return null;
+ }
+
+ public override Encoding GetEncoding (int codepage)
+ {
+ // MSDN: "if codepage is not the code page identifier of an encoding that you support, the method should return null."
+ // We do this here since all our encodings are already supported by the main Encoding class
+ return null;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Text.Encoding.CodePages
+SUBDIRS =
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Text.Encoding.CodePages.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_REFS = System
+LIB_MCS_FLAGS = $(SIGN_FLAGS)
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
--- /dev/null
+AssemblyInfo.cs
+CodePagesEncodingProvider.cs
TypeForwarders.cs
AssemblyInfo.cs
+../../../build/common/MonoTODOAttribute.cs
+ThreadingAclExtensions.cs
--- /dev/null
+//
+// ThreadingAclExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Security.AccessControl;
+using System.Diagnostics.Contracts;
+
+namespace System.Threading
+{
+ public static class ThreadingAclExtensions
+ {
+ [MonoTODO]
+ public static EventWaitHandleSecurity GetAccessControl (EventWaitHandle handle)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl (EventWaitHandle handle, EventWaitHandleSecurity eventSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static MutexSecurity GetAccessControl (Mutex mutex)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl (Mutex mutex, MutexSecurity mutexSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static SemaphoreSecurity GetAccessControl (Semaphore semaphore)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static void SetAccessControl (Semaphore semaphore, SemaphoreSecurity semaphoreSecurity)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.SemaphoreRights))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.AccessControl.SemaphoreSecurity))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.ThreadingAclExtensions))]
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace System.Threading
+{
+ //
+ // Implementation of ThreadPoolBoundHandle that sits on top of the CLR's ThreadPool and Overlapped infrastructure
+ //
+
+ /// <summary>
+ /// Represents an I/O handle that is bound to the system thread pool and enables low-level
+ /// components to receive notifications for asynchronous I/O operations.
+ /// </summary>
+ public sealed partial class ThreadPoolBoundHandle : IDisposable
+ {
+ private readonly SafeHandle _handle;
+ private bool _isDisposed;
+
+ private ThreadPoolBoundHandle(SafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Gets the bound operating system handle.
+ /// </summary>
+ /// <value>
+ /// A <see cref="SafeHandle"/> object that holds the bound operating system handle.
+ /// </value>
+ public SafeHandle Handle
+ {
+ get { return _handle; }
+ }
+
+ /// <summary>
+ /// Returns a <see cref="ThreadPoolBoundHandle"/> for the specific handle,
+ /// which is bound to the system thread pool.
+ /// </summary>
+ /// <param name="handle">
+ /// A <see cref="SafeHandle"/> object that holds the operating system handle. The
+ /// handle must have been opened for overlapped I/O on the unmanaged side.
+ /// </param>
+ /// <returns>
+ /// <see cref="ThreadPoolBoundHandle"/> for <paramref name="handle"/>, which
+ /// is bound to the system thread pool.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="handle"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="handle"/> has been disposed.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> does not refer to a valid I/O handle.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> refers to a handle that has not been opened
+ /// for overlapped I/O.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> refers to a handle that has already been bound.
+ /// </exception>
+ /// <remarks>
+ /// This method should be called once per handle.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <see cref="ThreadPoolBoundHandle"/> does not take ownership of <paramref name="handle"/>,
+ /// it remains the responsibility of the caller to call <see cref="SafeHandle.Dispose"/>.
+ /// </remarks>
+ public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
+ {
+ if (handle == null)
+ throw new ArgumentNullException(nameof(handle));
+
+ if (handle.IsClosed || handle.IsInvalid)
+ throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
+
+ try
+ {
+ // ThreadPool.BindHandle will always return true, otherwise, it throws. See the underlying FCall
+ // implementation in ThreadPoolNative::CorBindIoCompletionCallback to see the implementation.
+ bool succeeded = ThreadPool.BindHandle(handle);
+ Debug.Assert(succeeded);
+ }
+ catch (Exception ex)
+ { // BindHandle throws ApplicationException on full CLR and Exception on CoreCLR.
+ // We do not let either of these leak and convert them to ArgumentException to
+ // indicate that the specified handles are invalid.
+
+ if (ex.HResult == System.HResults.E_HANDLE) // Bad handle
+ throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
+
+ if (ex.HResult == System.HResults.E_INVALIDARG) // Handle already bound or sync handle
+ throw new ArgumentException(SR.Argument_AlreadyBoundOrSyncHandle, nameof(handle));
+
+ throw;
+ }
+
+ return new ThreadPoolBoundHandle(handle);
+ }
+
+ /// <summary>
+ /// Returns an unmanaged pointer to a <see cref="NativeOverlapped"/> structure, specifying
+ /// a delegate that is invoked when the asynchronous I/O operation is complete, a user-provided
+ /// object providing context, and managed objects that serve as buffers.
+ /// </summary>
+ /// <param name="callback">
+ /// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
+ /// invoked when the asynchronous I/O operation completes.
+ /// </param>
+ /// <param name="state">
+ /// A user-provided object that distinguishes this <see cref="NativeOverlapped"/> from other
+ /// <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
+ /// </param>
+ /// <param name="pinData">
+ /// An object or array of objects representing the input or output buffer for the operation. Each
+ /// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
+ /// </param>
+ /// <returns>
+ /// An unmanaged pointer to a <see cref="NativeOverlapped"/> structure.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The unmanaged pointer returned by this method can be passed to the operating system in
+ /// overlapped I/O operations. The <see cref="NativeOverlapped"/> structure is fixed in
+ /// physical memory until <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> is called.
+ /// </para>
+ /// <para>
+ /// The buffer or buffers specified in <paramref name="pinData"/> must be the same as those passed
+ /// to the unmanaged operating system function that performs the asynchronous I/O.
+ /// </para>
+ /// <note>
+ /// The buffers specified in <paramref name="pinData"/> are pinned for the duration of
+ /// the I/O operation.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="callback"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object state, object pinData)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ EnsureNotDisposed();
+
+ ThreadPoolBoundHandleOverlapped overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, preAllocated: null);
+ overlapped._boundHandle = this;
+ return overlapped._nativeOverlapped;
+ }
+
+ /// <summary>
+ /// Returns an unmanaged pointer to a <see cref="NativeOverlapped"/> structure, using the callback,
+ /// state, and buffers associated with the specified <see cref="PreAllocatedOverlapped"/> object.
+ /// </summary>
+ /// <param name="preAllocated">
+ /// A <see cref="PreAllocatedOverlapped"/> object from which to create the NativeOverlapped pointer.
+ /// </param>
+ /// <returns>
+ /// An unmanaged pointer to a <see cref="NativeOverlapped"/> structure.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The unmanaged pointer returned by this method can be passed to the operating system in
+ /// overlapped I/O operations. The <see cref="NativeOverlapped"/> structure is fixed in
+ /// physical memory until <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> is called.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="preAllocated"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="preAllocated"/> is currently in use for another I/O operation.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed, or
+ /// this method was called after <paramref name="preAllocated"/> was disposed.
+ /// </exception>
+ /// <seealso cref="PreAllocatedOverlapped"/>
+ public unsafe NativeOverlapped* AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated)
+ {
+ if (preAllocated == null)
+ throw new ArgumentNullException(nameof(preAllocated));
+
+ EnsureNotDisposed();
+
+ preAllocated.AddRef();
+ try
+ {
+ ThreadPoolBoundHandleOverlapped overlapped = preAllocated._overlapped;
+
+ if (overlapped._boundHandle != null)
+ throw new ArgumentException(SR.Argument_PreAllocatedAlreadyAllocated, nameof(preAllocated));
+
+ overlapped._boundHandle = this;
+
+ return overlapped._nativeOverlapped;
+ }
+ catch
+ {
+ preAllocated.Release();
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Frees the unmanaged memory associated with a <see cref="NativeOverlapped"/> structure
+ /// allocated by the <see cref="AllocateNativeOverlapped"/> method.
+ /// </summary>
+ /// <param name="overlapped">
+ /// An unmanaged pointer to the <see cref="NativeOverlapped"/> structure to be freed.
+ /// </param>
+ /// <remarks>
+ /// <note type="caution">
+ /// You must call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method exactly once
+ /// on every <see cref="NativeOverlapped"/> unmanaged pointer allocated using the
+ /// <see cref="AllocateNativeOverlapped"/> method.
+ /// If you do not call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method, you will
+ /// leak memory. If you call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method more
+ /// than once on the same <see cref="NativeOverlapped"/> unmanaged pointer, memory will be corrupted.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="overlapped"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ public unsafe void FreeNativeOverlapped(NativeOverlapped* overlapped)
+ {
+ if (overlapped == null)
+ throw new ArgumentNullException(nameof(overlapped));
+
+ // Note: we explicitly allow FreeNativeOverlapped calls after the ThreadPoolBoundHandle has been Disposed.
+
+ ThreadPoolBoundHandleOverlapped wrapper = GetOverlappedWrapper(overlapped, this);
+
+ if (wrapper._boundHandle != this)
+ throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, nameof(overlapped));
+
+ if (wrapper._preAllocated != null)
+ wrapper._preAllocated.Release();
+ else
+ Overlapped.Free(overlapped);
+ }
+
+ /// <summary>
+ /// Returns the user-provided object specified when the <see cref="NativeOverlapped"/> instance was
+ /// allocated using the <see cref="AllocateNativeOverlapped(IOCompletionCallback, object, byte[])"/>.
+ /// </summary>
+ /// <param name="overlapped">
+ /// An unmanaged pointer to the <see cref="NativeOverlapped"/> structure from which to return the
+ /// asscociated user-provided object.
+ /// </param>
+ /// <returns>
+ /// A user-provided object that distinguishes this <see cref="NativeOverlapped"/>
+ /// from other <see cref="NativeOverlapped"/> instances, otherwise, <see langword="null"/> if one was
+ /// not specified when the instance was allocated using <see cref="AllocateNativeOverlapped"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="overlapped"/> is <see langword="null"/>.
+ /// </exception>
+ public unsafe static object GetNativeOverlappedState(NativeOverlapped* overlapped)
+ {
+ if (overlapped == null)
+ throw new ArgumentNullException(nameof(overlapped));
+
+ ThreadPoolBoundHandleOverlapped wrapper = GetOverlappedWrapper(overlapped, null);
+ Debug.Assert(wrapper._boundHandle != null);
+ return wrapper._userState;
+ }
+
+ private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle)
+ {
+ ThreadPoolBoundHandleOverlapped wrapper;
+ try
+ {
+ wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
+ }
+ catch (NullReferenceException ex)
+ {
+ throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, nameof(overlapped), ex);
+ }
+
+ return wrapper;
+ }
+
+ public void Dispose()
+ {
+ // .NET Native's version of ThreadPoolBoundHandle that wraps the Win32 ThreadPool holds onto
+ // native resources so it needs to be disposable. To match the contract, we are also disposable.
+ // We also implement a disposable state to mimic behavior between this implementation and
+ // .NET Native's version (code written against us, will also work against .NET Native's version).
+ _isDisposed = true;
+ }
+
+
+ private void EnsureNotDisposed()
+ {
+ if (_isDisposed)
+ throw new ObjectDisposedException(GetType().ToString());
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Threading
+{
+ /// <summary>
+ /// Overlapped subclass adding data needed by ThreadPoolBoundHandle.
+ /// </summary>
+ internal sealed class ThreadPoolBoundHandleOverlapped : Overlapped
+ {
+ private readonly IOCompletionCallback _userCallback;
+ internal readonly object _userState;
+ internal PreAllocatedOverlapped _preAllocated;
+ internal unsafe NativeOverlapped* _nativeOverlapped;
+ internal ThreadPoolBoundHandle _boundHandle;
+ internal bool _completed;
+
+ public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated)
+ {
+ _userCallback = callback;
+ _userState = state;
+ _preAllocated = preAllocated;
+
+ _nativeOverlapped = Pack(CompletionCallback, pinData);
+ _nativeOverlapped->OffsetLow = 0; // CLR reuses NativeOverlapped instances and does not reset these
+ _nativeOverlapped->OffsetHigh = 0;
+ }
+
+ private unsafe static void CompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
+ {
+ ThreadPoolBoundHandleOverlapped overlapped = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(nativeOverlapped);
+
+ //
+ // The Win32 thread pool implementation of ThreadPoolBoundHandle does not permit reuse of NativeOverlapped
+ // pointers without freeing them and allocating new a new one. We need to ensure that code using the CLR
+ // ThreadPool implementation follows those rules.
+ //
+ if (overlapped._completed)
+ throw new InvalidOperationException(SR.InvalidOperation_NativeOverlappedReused);
+
+ overlapped._completed = true;
+
+ if (overlapped._boundHandle == null)
+ throw new InvalidOperationException(SR.Argument_NativeOverlappedAlreadyFree);
+
+ overlapped._userCallback(errorCode, numBytes, nativeOverlapped);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Threading
+{
+ /// <summary>
+ /// Represents pre-allocated state for native overlapped I/O operations.
+ /// </summary>
+ /// <seealso cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>
+ public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
+ {
+ internal readonly ThreadPoolBoundHandleOverlapped _overlapped;
+ private DeferredDisposableLifetime<PreAllocatedOverlapped> _lifetime;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PreAllocatedOverlapped"/> class, specifying
+ /// a delegate that is invoked when each asynchronous I/O operation is complete, a user-provided
+ /// object providing context, and managed objects that serve as buffers.
+ /// </summary>
+ /// <param name="callback">
+ /// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
+ /// invoked when each asynchronous I/O operation completes.
+ /// </param>
+ /// <param name="state">
+ /// A user-provided object that distinguishes <see cref="NativeOverlapped"/> instance produced from this
+ /// object from other <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
+ /// </param>
+ /// <param name="pinData">
+ /// An object or array of objects representing the input or output buffer for the operations. Each
+ /// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
+ /// </param>
+ /// <remarks>
+ /// The new <see cref="PreAllocatedOverlapped"/> instance can be passed to
+ /// <see cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>, to produce
+ /// a <see cref="NativeOverlapped"/> instance that can be passed to the operating system in overlapped
+ /// I/O operations. A single <see cref="PreAllocatedOverlapped"/> instance can only be used for
+ /// a single native I/O operation at a time. However, the state stored in the <see cref="PreAllocatedOverlapped"/>
+ /// instance can be reused for subsequent native operations.
+ /// <note>
+ /// The buffers specified in <paramref name="pinData"/> are pinned until <see cref="Dispose"/> is called.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="callback"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ _overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, this);
+ }
+
+ internal bool AddRef()
+ {
+ return _lifetime.AddRef(this);
+ }
+
+ internal void Release()
+ {
+ _lifetime.Release(this);
+ }
+
+ /// <summary>
+ /// Frees the resources associated with this <see cref="PreAllocatedOverlapped"/> instance.
+ /// </summary>
+ public unsafe void Dispose()
+ {
+ _lifetime.Dispose(this);
+ GC.SuppressFinalize(this);
+ }
+
+ ~PreAllocatedOverlapped()
+ {
+ //
+ // During shutdown, don't automatically clean up, because this instance may still be
+ // reachable/usable by other code.
+ //
+ if (!Environment.HasShutdownStarted)
+ Dispose();
+ }
+
+ unsafe void IDeferredDisposable.OnFinalRelease(bool disposed)
+ {
+ if (_overlapped != null)
+ {
+ if (disposed)
+ {
+ Overlapped.Free(_overlapped._nativeOverlapped);
+ }
+ else
+ {
+ _overlapped._boundHandle = null;
+ _overlapped._completed = false;
+ *_overlapped._nativeOverlapped = default(NativeOverlapped);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+
+namespace System.Threading
+{
+ /// <summary>
+ /// Provides callbacks to objects whose lifetime is managed by <see cref="DeferredDisposableLifetime{T}"/>.
+ /// </summary>
+ internal interface IDeferredDisposable
+ {
+ /// <summary>
+ /// Called when the object's refcount reaches zero.
+ /// </summary>
+ /// <param name="disposed">
+ /// Indicates whether the object has been disposed.
+ /// </param>
+ /// <remarks>
+ /// If the refount reaches zero before the object is disposed, this method will be called with
+ /// <paramref name="disposed"/> set to false. If the object is then disposed, this method will be
+ /// called again, with <paramref name="disposed"/> set to true. If the refcount reaches zero
+ /// after the object has already been disposed, this will be called a single time, with
+ /// <paramref name="disposed"/> set to true.
+ /// </remarks>
+ void OnFinalRelease(bool disposed);
+ }
+
+ /// <summary>
+ /// Manages the lifetime of an object which implements IDisposable, but which must defer the actual
+ /// cleanup of state until all existing uses of the object are complete.
+ /// </summary>
+ /// <typeparam name="T">The type of object whose lifetime will be managed.</typeparam>
+ /// <remarks>
+ /// This type maintains a reference count, and tracks whether the object has been disposed. When
+ /// Callbacks are made to <see cref="IDeferredDisposable.OnFinalRelease(bool)"/> when the refcount
+ /// reaches zero. Objects that need to defer cleanup until they have been disposed *and* they have
+ /// no more references can do so in <see cref="IDeferredDisposable.OnFinalRelease(bool)"/> when
+ /// 'disposed' is true.
+ /// </remarks>
+ internal struct DeferredDisposableLifetime<T> where T : class, IDeferredDisposable
+ {
+ //
+ // _count is positive until Dispose is called, after which it's (-1 - refcount).
+ //
+ private int _count;
+
+ public bool AddRef(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+
+ // Have we been disposed?
+ if (oldCount < 0)
+ throw new ObjectDisposedException(typeof(T).ToString());
+
+ int newCount = checked(oldCount + 1);
+
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ return true;
+ }
+ }
+
+ public void Release(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+ if (oldCount > 0)
+ {
+ // We haven't been disposed. Decrement _count.
+ int newCount = oldCount - 1;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == 0)
+ obj.OnFinalRelease(disposed: false);
+ return;
+ }
+ }
+ else
+ {
+ Debug.Assert(oldCount != 0 && oldCount != -1);
+
+ // We've been disposed. Increment _count.
+ int newCount = oldCount + 1;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == -1)
+ obj.OnFinalRelease(disposed: true);
+ return;
+ }
+ }
+ }
+ }
+
+ public void Dispose(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+ if (oldCount < 0)
+ return; // already disposed
+
+ int newCount = -1 - oldCount;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == -1)
+ obj.OnFinalRelease(disposed: true);
+ return;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// HResults.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System
+{
+ internal static class HResults
+ {
+ internal const int E_HANDLE = unchecked((int)0x80070006);
+ internal const int E_INVALIDARG = unchecked((int)0x80070057);
+ }
+}
\ No newline at end of file
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
LIB_REFS = System
-LIB_MCS_FLAGS = $(SIGN_FLAGS)
+LIB_MCS_FLAGS = $(SIGN_FLAGS) -unsafe
PLATFORM_DEBUG_FLAGS =
--- /dev/null
+// strings taken from corefx
+
+class SR
+{
+ public const string Argument_AlreadyBoundOrSyncHandle = "'handle' has already been bound to the thread pool, or was not opened for asynchronous I/O.";
+ public const string Argument_InvalidHandle = "'handle' has been disposed or is an invalid handle.";
+ public const string Argument_NativeOverlappedAlreadyFree = "'overlapped' has already been freed.";
+ public const string Argument_NativeOverlappedWrongBoundHandle = "'overlapped' was not allocated by this ThreadPoolBoundHandle instance.";
+ public const string Argument_PreAllocatedAlreadyAllocated = "'preAllocated' is already in use.";
+ public const string InvalidOperation_NativeOverlappedReused = "NativeOverlapped cannot be reused for multiple operations.";
+}
\ No newline at end of file
TypeForwarders.cs
AssemblyInfo.cs
+ClrThreadPoolBoundHandle.cs
+ClrThreadPoolBoundHandleOverlapped.cs
+ClrThreadPoolPreAllocatedOverlapped.cs
+DeferredDisposableLifetime.cs
+SR.cs
+HResults.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.IOCompletionCallback))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.NativeOverlapped))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.PreAllocatedOverlapped))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Threading.ThreadPoolBoundHandle))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.Serialization.IXmlSerializable))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XmlDateTimeSerializationMode))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.Serialization.XmlSchemaProviderAttribute))]
KEY_FILE = ../../msfinal.pub
SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System System.Xml.Linq
+LIB_REFS = System System.Xml System.Xml.Linq
LIB_MCS_FLAGS = $(SIGN_FLAGS)
PLATFORM_DEBUG_FLAGS =
TypeForwarders.cs
AssemblyInfo.cs
-
+XDocumentExtensions.cs
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XPath.Extensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XPath.XDocumentExtensions))]
--- /dev/null
+
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml.Linq;
+
+namespace System.Xml.XPath
+{
+ public static class XDocumentExtensions
+ {
+ private class XDocumentNavigable : IXPathNavigable
+ {
+ private XNode _node;
+ public XDocumentNavigable(XNode n)
+ {
+ _node = n;
+ }
+ public XPathNavigator CreateNavigator()
+ {
+ return _node.CreateNavigator();
+ }
+ }
+ public static IXPathNavigable ToXPathNavigable(this XNode node)
+ {
+ return new XDocumentNavigable(node);
+ }
+ }
+}
\ No newline at end of file
# Caution while renaming SUBDIRS variables as those are used outside mono repository.
# ie: macccore/builds/Makefile
-monotouch_PARALLEL_SUBDIRS = System.Collections.Concurrent System.Collections System.ComponentModel.Annotations System.ComponentModel.EventBasedAsync System.ComponentModel \
+common_SUBDIRS = System.Collections.Concurrent System.Collections System.ComponentModel.Annotations System.ComponentModel.EventBasedAsync System.ComponentModel \
System.Diagnostics.Contracts System.Diagnostics.Debug System.Diagnostics.Tracing System.Diagnostics.Tools System.Dynamic.Runtime System.Globalization System.IO System.Linq.Expressions \
System.Linq.Parallel System.Linq.Queryable System.Linq System.Net.NetworkInformation System.Net.Primitives System.Net.Requests System.ObjectModel \
System.Reflection.Extensions System.Reflection.Primitives System.Reflection System.Resources.ResourceManager System.Runtime.Extensions \
System.Runtime.InteropServices System.Runtime.InteropServices.WindowsRuntime System.Runtime.Numerics System.Runtime.Serialization.Json \
-System.Runtime.Serialization.Primitives System.Runtime.Serialization.Xml System.Runtime System.Security.Principal System.ServiceModel.Http \
-System.ServiceModel.Primitives System.ServiceModel.Security System.Text.Encoding.Extensions System.Text.Encoding System.Text.RegularExpressions System.Threading.Tasks.Parallel \
+System.Runtime System.Security.Principal System.ServiceModel.Http \
+System.ServiceModel.Security System.Text.Encoding.Extensions System.Text.Encoding System.Text.RegularExpressions System.Threading.Tasks.Parallel \
System.Threading.Tasks System.Threading.Timer System.Threading System.Xml.ReaderWriter System.Xml.XDocument System.Xml.XmlSerializer \
System.Runtime.Handles System.ServiceModel.Duplex System.ServiceModel.NetTcp \
Microsoft.Win32.Primitives Microsoft.Win32.Registry System.AppContext System.Collections.NonGeneric System.Collections.Specialized System.ComponentModel.Primitives \
System.Security.AccessControl System.Security.Claims System.Security.Cryptography.DeriveBytes System.Security.Cryptography.Encoding System.Security.Cryptography.Encryption \
System.Security.Cryptography.Encryption.Aes System.Security.Cryptography.Encryption.ECDiffieHellman System.Security.Cryptography.Encryption.ECDsa System.Security.Cryptography.Hashing \
System.Security.Cryptography.Hashing.Algorithms System.Security.Cryptography.RSA System.Security.Cryptography.RandomNumberGenerator \
-System.Security.Cryptography.X509Certificates System.Security.Principal.Windows System.Threading.Thread System.Threading.ThreadPool \
+System.Security.Principal.Windows System.Threading.Thread System.Threading.ThreadPool \
System.Xml.XPath System.Xml.XmlDocument System.Xml.Xsl.Primitives Microsoft.Win32.Registry.AccessControl System.Diagnostics.StackTrace System.Globalization.Extensions \
-System.IO.FileSystem.AccessControl System.Private.CoreLib.InteropServices System.Private.CoreLib.Threading System.Reflection.TypeExtensions \
+System.IO.FileSystem.AccessControl System.Private.CoreLib.InteropServices System.Reflection.TypeExtensions \
System.Security.SecureString System.Threading.AccessControl System.Threading.Overlapped System.Xml.XPath.XDocument System.IO.Compression \
-System.Security.Cryptography.Algorithms System.Security.Cryptography.Primitives
+System.Security.Cryptography.Algorithms System.Security.Cryptography.Primitives System.Text.Encoding.CodePages System.IO.FileSystem.Watcher \
+System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController System.IO.Pipes
+
+# common_SUBDIRS dependencies
+common_DEPS_SUBDIRS = System.Security.Cryptography.X509Certificates System.ServiceModel.Primitives System.Runtime.Serialization.Primitives System.Runtime.Serialization.Xml
+
+drawing_DEPS_SUBDIRS = System.Drawing.Primitives
reflection_PARALLEL_SUBDIRS = System.Reflection.Emit.ILGeneration System.Reflection.Emit.Lightweight System.Reflection.Emit
+monotouch_SUBDIRS = $(common_DEPS_SUBDIRS)
+monotouch_PARALLEL_SUBDIRS = $(common_SUBDIRS) $(mobile_only_SUBDIRS)
+
+mobile_static_SUBDIRS = $(monotouch_SUBDIRS)
mobile_static_PARALLEL_SUBDIRS = $(monotouch_PARALLEL_SUBDIRS)
-net_4_x_PARALLEL_SUBDIRS = $(monotouch_PARALLEL_SUBDIRS) $(reflection_PARALLEL_SUBDIRS) System.Diagnostics.PerformanceCounter \
-System.IO.FileSystem.Watcher System.IO.Pipes System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController System.Net.Http.WebRequestHandler
+net_4_x_SUBDIRS = $(common_DEPS_SUBDIRS) $(drawing_DEPS_SUBDIRS)
+net_4_x_PARALLEL_SUBDIRS = $(common_SUBDIRS) $(reflection_PARALLEL_SUBDIRS) System.Diagnostics.PerformanceCounter \
+System.Net.Http.WebRequestHandler
+monodroid_SUBDIRS = $(monotouch_SUBDIRS)
monodroid_PARALLEL_SUBDIRS = $(monotouch_PARALLEL_SUBDIRS) $(reflection_PARALLEL_SUBDIRS)
-xammac_PARALLEL_SUBDIRS = $(monotouch_PARALLEL_SUBDIRS) $(reflection_PARALLEL_SUBDIRS)
-xammac_net_4_5_PARALLEL_SUBDIRS = $(monotouch_PARALLEL_SUBDIRS) $(reflection_PARALLEL_SUBDIRS)
+xammac_SUBDIRS = $(monotouch_SUBDIRS)
+xammac_PARALLEL_SUBDIRS = $(monotouch_PARALLEL_SUBDIRS)
+xammac_net_4_5_SUBDIRS = $(net_4_x_SUBDIRS)
+xammac_net_4_5_PARALLEL_SUBDIRS = $(net_4_x_PARALLEL_SUBDIRS)
+
+monotouch_watch_SUBDIRS = $(monotouch_SUBDIRS) $(drawing_DEPS_SUBDIRS)
monotouch_watch_PARALLEL_SUBDIRS = $(monotouch_PARALLEL_SUBDIRS)
+
+monotouch_tv_SUBDIRS = $(monotouch_SUBDIRS)
monotouch_tv_PARALLEL_SUBDIRS = $(monotouch_PARALLEL_SUBDIRS)
+mobile_only_SUBDIRS = System.Net.Ping System.Runtime.Serialization.Formatters System.Security.Cryptography.Csp System.Security.Cryptography.Pkcs \
+System.Security.Cryptography.Cng System.Security.Cryptography.OpenSsl
+
PROFILE_PARALLEL_SUBDIRS = $(net_4_x_PARALLEL_SUBDIRS)
Mono.Security \
System \
System.Core \
+ System.Security \
System.XML \
I18N \
System.ServiceModel.Internals \
Mono.Data.Tds \
System.Transactions \
System.Numerics \
+ System.Numerics.Vectors \
System.Data \
Mono.Cairo \
Mono.Data.Sqlite \
System.ComponentModel.Composition.4.5 \
System.Net \
System.Net.Http \
- System.Net.Http.WebRequest \
System.Windows \
System.Xml.Serialization \
Mono.CSharp \
Mono.Security.Providers.DotNet \
Mono.Security.Providers.NewSystemSource \
Mono.Security.Providers.NewTls \
- System.Runtime.InteropServices.RuntimeInformation
+ System.Runtime.InteropServices.RuntimeInformation \
+ System.Reflection.DispatchProxy \
+ System.Xml.XPath.XmlDocument \
+ System.Reflection.Context \
+ System.Net.Http.WinHttpHandler
mobile_static_dirs := \
$(mobile_common_dirs) \
Mono.Dynamic.Interpreter \
+ PEAPI \
+ Mono.CompilerServices.SymbolWriter \
+ Mono.Simd \
$(pcl_facade_dirs)
mobile_dynamic_dirs := \
System \
Mono.Posix \
System.Core \
+ System.Security \
System.XML \
I18N \
System.ServiceModel.Internals \
Mono.CompilerServices.SymbolWriter \
System.Data.Linq \
System.Net.Http \
+ System.Net.Http.WebRequest \
Mono.Security.Providers.DotNet \
Mono.Security.Providers.OldTls \
Mono.Security.Providers.NewSystemSource \
Mono.Security.Providers.NewTls \
System.Runtime.InteropServices.RuntimeInformation \
+ System.Reflection.Context \
+ System.Net.Http.WinHttpHandler \
$(pcl_facade_dirs)
net_4_x_dirs := \
System.Workflow.Activities \
System.Workflow.ComponentModel \
System.Workflow.Runtime \
+ System.Reflection.Context \
$(pcl_facade_dirs)
xbuild_2_0_dirs := \
net_4_x_SUBDIRS := $(net_4_x_dirs) $(xbuild_4_0_dirs)
net_4_x_PARALLEL_SUBDIRS := $(net_4_x_parallel_dirs) aot-compiler
xbuild_12_SUBDIRS := $(xbuild_4_0_dirs)
-xbuild_14_SUBDIRS := $(xbuild_4_0_dirs)
+xbuild_14_SUBDIRS := $(xbuild_4_0_dirs) Microsoft.NuGet.Build.Tasks
include ../build/rules.make
SUBDIRS = $(mobile_static_dirs) $(mobile_dynamic_dirs) $(monotouch_dirs) $(monodroid_dirs) $(xammac_dirs) $(net_4_x_dirs) $(net_4_x_parallel_dirs) $(xammac_net_4_5_SUBDIRS)
-DIST_ONLY_SUBDIRS = dlr aot-compiler reference-assemblies $(xbuild_4_0_dirs)
+DIST_ONLY_SUBDIRS = dlr aot-compiler reference-assemblies $(xbuild_4_0_dirs) Microsoft.NuGet.Build.Tasks
# No new makefiles for: System.Messaging, System.Web.Mobile,
# System.ServiceProcess
framework_dir = Path.Combine (redistlist_dir, framework_dir);
var directories = new List<string> ();
- directories.Add (MSBuildUtils.FromMSBuildPath (framework_dir));
+
+ //MSBuild has a trailing slash on this value
+ directories.Add (MSBuildUtils.FromMSBuildPath (framework_dir) + Path.DirectorySeparatorChar);
string include = xr.GetAttribute ("IncludeFramework");
if (!String.IsNullOrEmpty (include)) {
else
return String.Empty;
case "identity":
- return Path.Combine (Path.GetDirectoryName (itemSpec), Path.GetFileName (itemSpec));
+ return itemSpec;
case "modifiedtime":
if (File.Exists (itemSpec))
return File.GetLastWriteTime (itemSpec).ToString ();
--- /dev/null
+thisdir = class/Microsoft.NuGet.Build.Tasks
+SUBDIRS =
+include ../../build/rules.make
+
+XBUILD_DIR=$(topdir)/tools/xbuild
+include $(XBUILD_DIR)/xbuild.make
+
+NUGET_BUILDTASKS_REPO_DIR=$(topdir)/../external/nuget-buildtasks
+NUGET_BUILDTASKS_TARGETS_DIR = $(mono_libdir)/mono/xbuild/Microsoft/NuGet
+
+LIBRARY = Microsoft.NuGet.Build.Tasks.dll
+LIBRARY_INSTALL_DIR = $(NUGET_BUILDTASKS_TARGETS_DIR)
+
+KEY_FILE = $(NUGET_BUILDTASKS_REPO_DIR)/build/PublicKey.snk
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE)
+
+RESOURCE_DEFS = Microsoft.NuGet.Build.Tasks.Strings,$(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/Strings.resx
+
+LIB_REFS = $(PARENT_PROFILE)System \
+ $(PARENT_PROFILE)System.Core \
+ $(PARENT_PROFILE)System.Data \
+ $(PARENT_PROFILE)System.Xml \
+ $(PARENT_PROFILE)System.Xml.Linq \
+ $(PARENT_PROFILE)System.Runtime.Serialization \
+ $(XBUILD_UTILITIES) \
+ $(XBUILD_FRAMEWORK)
+
+LIB_MCS_FLAGS = \
+ -nowarn:3021 \
+ $(SIGN_FLAGS)
+
+EXTRA_DISTFILES = \
+ $(NUGET_BUILDTASKS_REPO_DIR)/build/PublicKey.snk
+
+include ../../build/library.make
--- /dev/null
+../../../external/nuget-buildtasks/src/Microsoft.NuGet.Build.Tasks/Delegates.cs
+../../../external/nuget-buildtasks/src/Microsoft.NuGet.Build.Tasks/ExceptionFromResource.cs
+../../../external/nuget-buildtasks/src/Microsoft.NuGet.Build.Tasks/InternalsVisibleTo.cs
+../../../external/nuget-buildtasks/src/Microsoft.NuGet.Build.Tasks/NativeMethods.cs
+../../../external/nuget-buildtasks/src/Microsoft.NuGet.Build.Tasks/NuGetPackageObject.cs
+../../../external/nuget-buildtasks/src/Microsoft.NuGet.Build.Tasks/Preprocessor.cs
+../../../external/nuget-buildtasks/src/Microsoft.NuGet.Build.Tasks/ResolveNuGetPackageAssets.cs
+../../../external/nuget-buildtasks/src/Microsoft.NuGet.Build.Tasks/Strings.Designer.cs
+
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonToken.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonType.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonObjectId.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/RegexConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ConstructorHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/VersionConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DateFormatHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DateTimeZoneHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Formatting.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConstructorAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPosition.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPath.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JRaw.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Required.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/PreserveReferencesHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/IJsonLineInfo.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonArrayAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonContainerAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DefaultValueHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonObjectAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializerSettings.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonValidatingReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/IJEnumerable.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/MemberSerialization.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ObjectCreationHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPropertyAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriterException.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReaderException.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterCollection.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConvert.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializationException.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializer.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/Extensions.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JConstructor.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JContainer.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JEnumerable.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JObject.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JArray.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JToken.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JProperty.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenType.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JValue.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/Extensions.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorContext.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IContractResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IValueProvider.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonProperty.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/MissingMemberHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/NullValueHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ReferenceLoopHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchema.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MethodCall.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringReference.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/TypeNameHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValue.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValues.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonToken.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ListWrapper.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MathUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/WriteState.cs
Evaluator/EvaluatorTest.cs
Evaluator/ExpressionsTest.cs
Evaluator/TypesTest.cs
+Visit/ASTVisitorTest.cs
var stream = new MemoryStream (Encoding.UTF8.GetBytes (content));
- var ctx = new CompilerContext (new CompilerSettings (), new Report (new AssertReportPrinter ()));
+ var ctx = new CompilerContext (new CompilerSettings (), new AssertReportPrinter ());
ModuleContainer module = new ModuleContainer (ctx);
+ var file = new SourceFile ("test", "asdfas", 0);
CSharpParser parser = new CSharpParser (
new SeekableStreamReader (stream, Encoding.UTF8),
- new CompilationUnit ("name", "path", 0),
- module);
+ new CompilationSourceFile (module, file),
+ ctx.Report,
+ new ParserSession ());
RootContext.ToplevelTypes = module;
- Location.AddFile (ctx.Report, "asdfas");
- Location.Initialize ();
- parser.LocationsBag = new LocationsBag ();
+ Location.Initialize (new List<SourceFile> { file });
parser.parse ();
- var m = module.Types[0].Methods[0] as Method;
- var s = m.Block.FirstStatement;
- var o = s.loc.Column;
-
+ Assert.AreEqual (0, ctx.Report.Errors);
module.Accept (new TestVisitor ());
}
#include mobile_static_Mono.CSharp.dll.sources
-monotouch.cs
#include mobile_static_Mono.CSharp.dll.sources
-monotouch.cs
#include mobile_static_Mono.CSharp.dll.sources
-monotouch.cs
Hashtable documents = new Hashtable ();
-#if !CECIL
+#if !CECIL && !MOBILE
ModuleBuilder mb;
delegate Guid GetGuidFunc (ModuleBuilder mb);
GetGuidFunc get_guid_func;
# The test exe is not profile specific, and compiling a 2.0 will make the 4.5 tests fail
ifdef VALID_TEST_PROFILE
+TEST_HELPERS_SOURCES = \
+ ../test-helpers/NetworkHelpers.cs
+
test-local: dtest-app.exe dtest-excfilter.exe
-dtest-app.exe: Test/dtest-app.cs
- $(CSCOMPILE) -r:$(topdir)/class/lib/$(PROFILE)/System.Core.dll -r:$(topdir)/class/lib/$(PROFILE)/System.dll -out:$@ -unsafe $(PLATFORM_DEBUG_FLAGS) -optimize- Test/dtest-app.cs
+dtest-app.exe: Test/dtest-app.cs $(TEST_HELPERS_SOURCES)
+ $(CSCOMPILE) -r:$(topdir)/class/lib/$(PROFILE)/System.Core.dll -r:$(topdir)/class/lib/$(PROFILE)/System.dll -out:$@ -unsafe $(PLATFORM_DEBUG_FLAGS) -optimize- Test/dtest-app.cs $(TEST_HELPERS_SOURCES)
dtest-excfilter.exe: Test/dtest-excfilter.il
MONO_PATH=$(topdir)/class/lib/$(PROFILE) $(INTERNAL_ILASM) -out:$@ /exe /debug Test/dtest-excfilter.il
using System.Reflection.Emit;
using System.Diagnostics;
using System.Threading;
+using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Sockets;
+using MonoTests.Helpers;
public class TestsBase
{
wait_one ();
return 0;
}
+ if (args.Length >0 && args [0] == "threadpool-io") {
+ threadpool_io ();
+ return 0;
+ }
breakpoints ();
single_stepping ();
arguments ();
public override string virtual_method () {
return "V2";
}
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void threadpool_bp () { }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void threadpool_io () {
+ // Start a threadpool task that blocks on I/O.
+ // Regression test for #42625
+ const int nbytes = 16;
+ var bsOut = new byte[nbytes];
+ for (int i = 0; i < nbytes; i++) {
+ bsOut[i] = (byte)i;
+ }
+ var endPoint = NetworkHelpers.LocalEphemeralEndPoint ();
+ var l = new TcpListener (endPoint);
+ l.Start ();
+ Task<byte[]> t = Task.Run (async () => {
+ var c = new TcpClient ();
+ await c.ConnectAsync (endPoint.Address, endPoint.Port);
+ var streamIn = c.GetStream ();
+ var bs = new byte[nbytes];
+ int nread = 0;
+ while (nread < nbytes) {
+ nread += await streamIn.ReadAsync (bs, nread, nbytes);
+ }
+ streamIn.Close ();
+ return bs;
+ });
+ var s = l.AcceptTcpClient ();
+ l.Stop ();
+ // write bytes in two groups so that the task blocks on the ReadAsync
+ var streamOut = s.GetStream ();
+ var nbytesFirst = nbytes / 2;
+ var nbytesRest = nbytes - nbytesFirst;
+ streamOut.Write (bsOut, 0, nbytesFirst);
+ threadpool_bp ();
+ streamOut.Write (bsOut, nbytesFirst, nbytesRest);
+ streamOut.Close ();
+ var bsIn = t.Result;
+ }
}
class TypeLoadClass {
// Make sure we are still in the cctor
Assert.AreEqual (".cctor", e.Thread.GetFrames ()[0].Location.Method.Name);
}
+
+ [Test]
+ public void ThreadpoolIOsinglestep () {
+ TearDown ();
+ Start ("dtest-app.exe", "threadpool-io");
+ // This is a regression test for #42625. It tests the
+ // interaction (particularly in coop GC) of the
+ // threadpool I/O mechanism and the soft debugger.
+ Event e = run_until ("threadpool_io");
+ // run until we sent the task half the bytes it
+ // expects, so that it blocks waiting for the rest.
+ e = run_until ("threadpool_bp");
+ var req = create_step (e);
+ e = step_out (); // leave threadpool_bp
+ e = step_out (); // leave threadpool_io
+ }
}
}
include ../../build/rules.make
LIBRARY = Mono.Tasklets.dll
-NO_TEST = yes
+
+LIB_MCS_FLAGS =
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
include ../../build/library.make
--- /dev/null
+Mono.Tasklets/ContinuationsTest.cs
--- /dev/null
+using NUnit.Framework;
+
+using System;
+using Mono.Tasklets;
+
+namespace MonoTests.System
+{
+ [TestFixture]
+ public class ContinuationsTest
+ {
+ [TestFixtureSetUp]
+ public void FixtureSetUp ()
+ {
+ try {
+ var temp = new Continuation ();
+ } catch (NotImplementedException) {
+ Assert.Ignore ("This platform doesn't support Tasklets.");
+ }
+ }
+
+ int total = 0;
+
+ [Test]
+ public void TestContinuationsLoop()
+ {
+ Continuation _contA = new Continuation();
+
+ _contA.Mark();
+ int value = 0;
+ int ret = _contA.Store(0);
+ for (int i = ret; i < 10; i++) {
+ value += i;
+ }
+
+ if (value > 0) {
+ total += value;
+ _contA.Restore(ret + 1);
+ }
+
+ Assert.AreEqual(total, 330);
+ }
+
+ private int yields = 0;
+
+ [Test]
+ public void Yielding()
+ {
+ Continuation baseCont = new Continuation();
+ Continuation taskCont = new Continuation();
+
+ baseCont.Mark();
+ taskCont.Mark();
+
+ // Store the base continuation to start the task
+ if (baseCont.Store(0) == 0) {
+ bool done = false;
+ int count = 0;
+
+ while (!done) {
+ // Do stuff for the task.
+ ++count;
+
+ // This task is counting to 100.
+ if (count == 100) {
+ done = true;
+ }
+
+ // Yield every 10 loops
+ else if (count % 10 == 0) {
+
+ // To yield, store the task continuation then restore
+ // the base continuation.
+ if (taskCont.Store(0) == 0) {
+ baseCont.Restore(1);
+ }
+ }
+ }
+ }
+ // When restored, 'Store' will return what was passed to Restore, in this case 1 so fall here.
+ else {
+ // Count the yields, then go back to the task.
+ ++yields;
+ taskCont.Restore(1);
+ }
+
+ Assert.AreEqual(9, yields);
+ }
+
+
+ public class MicroThread
+ {
+
+ public void Yield()
+ {
+ if (MyThread.Store(0) == 0) {
+ MainThread.Restore(1);
+ }
+ }
+
+ public void Resume()
+ {
+ if (MainThread.Store(0) == 0) {
+ MyThread.Restore(1);
+ }
+ }
+
+ public void DoWork(Action action)
+ {
+ if (MainThread.Store(0) == 0) {
+ action();
+ Done = true;
+ MainThread.Restore(1);
+ }
+ }
+
+ public bool Done = false;
+ public Continuation MainThread = new Continuation();
+ public Continuation MyThread = new Continuation();
+ }
+
+ public class MicroBJob
+ {
+ private int _Count = 0;
+ public int Count
+ {
+ get { return _Count; }
+ set { _Count = value; }
+ }
+
+ public MicroThread MicroThread;
+ public void Work()
+ {
+ while (Count < 100) {
+ ++Count;
+ if (Count % 10 == 0) {
+ MicroThread.Yield();
+ }
+ }
+ }
+ }
+
+ [Test]
+ public void MicroThreadTest()
+ {
+ MicroThread microA = new MicroThread();
+ MicroThread microB = new MicroThread();
+
+ microA.MainThread.Mark();
+ microA.MyThread.Mark();
+ microB.MainThread.Mark();
+ microB.MyThread.Mark();
+
+ Assert.AreEqual(false, microA.Done);
+ Assert.AreEqual(false, microB.Done);
+
+ microA.DoWork(() =>
+ {
+ int count = 0;
+ while (count < 100) {
+ ++count;
+ if (count % 10 == 0) {
+ microA.Yield();
+ }
+ }
+ });
+
+ MicroBJob jobB = new MicroBJob();
+ jobB.MicroThread = microB;
+
+ microB.DoWork(jobB.Work);
+
+ Assert.AreEqual(false, microA.Done);
+ Assert.AreEqual(false, microB.Done);
+
+ int yields = 0;
+ while (yields < 20) {
+ if (!microA.Done) microA.Resume();
+ if (!microB.Done) microB.Resume();
+ if (microA.Done && microB.Done) break;
+ ++yields;
+ }
+
+ Assert.AreEqual(true, microA.Done);
+ Assert.AreEqual(true, microB.Done);
+ Assert.AreEqual(100, jobB.Count);
+ Assert.AreEqual(9, yields);
+ }
+ }
+}
--- /dev/null
+//
+// SafeNCryptHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public abstract class SafeNCryptHandle : System.Runtime.InteropServices.SafeHandle
+ {
+ protected SafeNCryptHandle ()
+ : base (IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid { get { throw new NotImplementedException (); } }
+
+ protected override bool ReleaseHandle ()
+ {
+ return false;
+ }
+
+ protected abstract bool ReleaseNativeHandle();
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SafeNCryptKeyHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public sealed class SafeNCryptKeyHandle : SafeNCryptHandle
+ {
+ public SafeNCryptKeyHandle ()
+ {
+ }
+
+ protected override bool ReleaseNativeHandle ()
+ {
+ return false;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SafeNCryptProviderHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public sealed class SafeNCryptProviderHandle : SafeNCryptHandle
+ {
+ public SafeNCryptProviderHandle ()
+ {
+ }
+
+ protected override bool ReleaseNativeHandle ()
+ {
+ return false;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// SafeNCryptSecretHandle.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public sealed class SafeNCryptSecretHandle : SafeNCryptHandle
+ {
+ public SafeNCryptSecretHandle ()
+ {
+ }
+
+ protected override bool ReleaseNativeHandle ()
+ {
+ return false;
+ }
+ }
+}
\ No newline at end of file
{
}
- public AnonymousPipeClientStream (PipeDirection direction,SafePipeHandle safePipeHandle)
+ public AnonymousPipeClientStream (PipeDirection direction, SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
/*
impl = new UnixAnonymousPipeClient (this, safePipeHandle);
*/
+#if MOBILE
+ throw new NotImplementedException ();
+#else
InitializeHandle (safePipeHandle, false, false);
+#endif
IsConnected = true;
}
}
public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability, int bufferSize)
+#if MOBILE
+ : base (direction, bufferSize)
+ {
+ throw new NotImplementedException ();
+ }
+#else
: this (direction, inheritability, bufferSize, null)
{
}
+#endif
+#if !MOBILE
public AnonymousPipeServerStream (PipeDirection direction, HandleInheritability inheritability, int bufferSize, PipeSecurity pipeSecurity)
: base (direction, bufferSize)
{
InitializeHandle (impl.Handle, false, false);
IsConnected = true;
}
+#endif
[MonoTODO]
public AnonymousPipeServerStream (PipeDirection direction, SafePipeHandle serverSafePipeHandle, SafePipeHandle clientSafePipeHandle)
if (direction == PipeDirection.InOut)
throw new NotSupportedException ("Anonymous pipe direction can only be either in or out.");
+#if MOBILE
+ throw new NotImplementedException ();
+#else
if (IsWindows)
impl = new Win32AnonymousPipeServer (this, serverSafePipeHandle, clientSafePipeHandle);
else
IsConnected = true;
ClientSafePipeHandle = clientSafePipeHandle;
+#endif
+ }
+
+ ~AnonymousPipeServerStream ()
+ {
+ // To be compatible with .net
}
IAnonymousPipeServer impl;
}
public NamedPipeClientStream (string serverName, string pipeName, PipeDirection direction, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability)
+#if MOBILE
+ : base (direction, DefaultBufferSize)
+ {
+ throw new NotImplementedException ();
+ }
+#else
: this (serverName, pipeName, ToAccessRights (direction), options, impersonationLevel, inheritability)
{
}
+#endif
public NamedPipeClientStream (PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
+#if MOBILE
+ throw new NotImplementedException ();
+#else
if (IsWindows)
impl = new Win32NamedPipeClient (this, safePipeHandle);
else
impl = new UnixNamedPipeClient (this, safePipeHandle);
IsConnected = isConnected;
InitializeHandle (safePipeHandle, true, isAsync);
+#endif
}
+#if !MOBILE
public NamedPipeClientStream (string serverName, string pipeName, PipeAccessRights desiredAccessRights, PipeOptions options, TokenImpersonationLevel impersonationLevel, HandleInheritability inheritability)
: base (ToDirection (desiredAccessRights), DefaultBufferSize)
{
else
impl = new UnixNamedPipeClient (this, serverName, pipeName, desiredAccessRights, options, inheritability);
}
+#endif
INamedPipeClient impl;
public void Connect ()
{
+#if MOBILE
+ throw new NotImplementedException ();
+#else
impl.Connect ();
InitializeHandle (impl.Handle, false, impl.IsAsync);
IsConnected = true;
+#endif
}
public void Connect (int timeout)
{
+#if MOBILE
+ throw new NotImplementedException ();
+#else
impl.Connect (timeout);
InitializeHandle (impl.Handle, false, impl.IsAsync);
IsConnected = true;
+#endif
}
public int NumberOfServerInstances {
}
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize)
+#if MOBILE
+ : base (direction, inBufferSize)
+ {
+ throw new NotImplementedException ();
+ }
+#else
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, null)
{
}
+#endif
+#if !MOBILE
public NamedPipeServerStream (string pipeName, PipeDirection direction, int maxNumberOfServerInstances, PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize, PipeSecurity pipeSecurity)
: this (pipeName, direction, maxNumberOfServerInstances, transmissionMode, options, inBufferSize, outBufferSize, pipeSecurity, HandleInheritability.None)
{
InitializeHandle (impl.Handle, false, (options & PipeOptions.Asynchronous) != PipeOptions.None);
}
+#endif
public NamedPipeServerStream (PipeDirection direction, bool isAsync, bool isConnected, SafePipeHandle safePipeHandle)
: base (direction, DefaultBufferSize)
{
+#if MOBILE
+ throw new NotImplementedException ();
+#else
if (IsWindows)
impl = new Win32NamedPipeServer (this, safePipeHandle);
else
impl = new UnixNamedPipeServer (this, safePipeHandle);
IsConnected = isConnected;
InitializeHandle (safePipeHandle, true, isAsync);
+#endif
+ }
+
+ ~NamedPipeServerStream ()
+ {
+ // To be compatible with .net
}
INamedPipeServer impl;
impl.Disconnect ();
}
+#if !MOBILE
[MonoTODO]
[SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal)]
public void RunAsClient (PipeStreamImpersonationWorker impersonationWorker)
{
throw new NotImplementedException ();
}
+#endif
public void WaitForConnection ()
{
throw new NotImplementedException ();
}
+#if !MOBILE
// async operations
Action wait_connect_delegate;
{
wait_connect_delegate.EndInvoke (asyncResult);
}
+#endif
}
}
// FIXME: not precise.
internal const int DefaultBufferSize = 0x400;
+#if !MOBILE
internal static bool IsWindows {
get { return Win32Marshal.IsWindows; }
}
+#endif
internal Exception ThrowACLException ()
{
return new NotImplementedException ("ACL is not supported in Mono");
}
+#if !MOBILE
internal static PipeAccessRights ToAccessRights (PipeDirection direction)
{
switch (direction) {
throw new ArgumentOutOfRangeException ();
}
}
+#endif
protected PipeStream (PipeDirection direction, int bufferSize)
: this (direction, PipeTransmissionMode.Byte, bufferSize)
set { stream = value; }
}
+#if !MOBILE
protected bool IsHandleExposed { get; private set; }
+#endif
[MonoTODO]
public bool IsMessageComplete { get; private set; }
}
// initialize/dispose/state check
+#if MOBILE
+ internal static void CheckPipePropertyOperations ()
+ {
+ }
+ static void CheckReadOperations ()
+ {
+ }
+
+ static void CheckWriteOperations ()
+ {
+ }
+#else
[MonoTODO]
protected internal virtual void CheckPipePropertyOperations ()
{
this.IsHandleExposed = isExposed;
this.IsAsync = isAsync;
}
+#endif
protected override void Dispose (bool disposing)
{
throw new NotSupportedException ();
}
+#if !MOBILE
public PipeSecurity GetAccessControl ()
{
return new PipeSecurity (SafePipeHandle,
public void WaitForPipeDrain ()
{
}
+#endif
[MonoTODO]
public override int Read ([In] byte [] buffer, int offset, int count)
// async
+#if !MOBILE
Func<byte [],int,int,int> read_delegate;
[HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
{
write_delegate.EndInvoke (asyncResult);
}
+#endif
}
}
--- /dev/null
+//
+// AesCng.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class AesCng : Aes
+ {
+ public AesCng ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public AesCng (string keyName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public AesCng (string keyName, CngProvider provider)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public AesCng (string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override Byte[] Key {
+ get {
+ throw new NotImplementedException ();
+ } set {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public override int KeySize {
+ get {
+ throw new NotImplementedException ();
+ }
+
+ set {
+ throw new NotImplementedException ();
+ }
+ }
+ public override ICryptoTransform CreateDecryptor ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateDecryptor (Byte[] rgbKey, Byte[] rgbIV)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateEncryptor ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateEncryptor (Byte[] rgbKey, Byte[] rgbIV)
+ {
+ return default(System.Security.Cryptography.ICryptoTransform);
+ }
+
+ protected override void Dispose (bool disposing) {
+ throw new NotImplementedException ();
+ }
+
+ public override void GenerateIV ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void GenerateKey ()
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// TripleDESCng.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Security.Cryptography
+{
+ public sealed class TripleDESCng : TripleDES
+ {
+ public TripleDESCng ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public TripleDESCng (string keyName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public TripleDESCng (string keyName, CngProvider provider)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public TripleDESCng (string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override Byte[] Key {
+ get {
+ throw new NotImplementedException ();
+ } set {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public override int KeySize {
+ get {
+ throw new NotImplementedException ();
+ }
+
+ set {
+ throw new NotImplementedException ();
+ }
+ }
+ public override ICryptoTransform CreateDecryptor ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateDecryptor (Byte[] rgbKey, Byte[] rgbIV)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateEncryptor ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override ICryptoTransform CreateEncryptor (Byte[] rgbKey, Byte[] rgbIV)
+ {
+ return default(System.Security.Cryptography.ICryptoTransform);
+ }
+
+ protected override void Dispose (bool disposing) {
+ throw new NotImplementedException ();
+ }
+
+ public override void GenerateIV ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void GenerateKey ()
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
\ No newline at end of file
System.IO.MemoryMappedFiles/MemoryMappedView.cs
Microsoft.Win32.SafeHandles/SafeMemoryMappedFileHandle.cs
Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs
+System.Security.Cryptography/AesCng.cs
+System.Security.Cryptography/TripleDESCng.cs
System.Security.Cryptography.X509Certificates/ECDsaCertificateExtensions.cs
System.Security.Cryptography.X509Certificates/RSACertificateExtensions.cs
+Microsoft.Win32.SafeHandles/SafeNCryptHandle.cs
+Microsoft.Win32.SafeHandles/SafeNCryptKeyHandle.cs
+Microsoft.Win32.SafeHandles/SafeNCryptProviderHandle.cs
+Microsoft.Win32.SafeHandles/SafeNCryptSecretHandle.cs
+Microsoft.Win32.SafeHandles/SafePipeHandle.cs
+
+System.IO.Pipes/AnonymousPipeClientStream.cs
+System.IO.Pipes/AnonymousPipeServerStream.cs
+System.IO.Pipes/NamedPipeClientStream.cs
+System.IO.Pipes/NamedPipeServerStream.cs
+System.IO.Pipes/PipeDirection.cs
+System.IO.Pipes/PipeInterfaces.cs
+System.IO.Pipes/PipeOptions.cs
+System.IO.Pipes/PipeStream.cs
+System.IO.Pipes/PipeTransmissionMode.cs
ReferenceSources/SR.cs
ReferenceSources/SR.missing.cs
../referencesource/System.Core/System/Runtime/CompilerServices/ExecutionScope.cs
../referencesource/System.Core/System/Security/Cryptography/Aes.cs
+../referencesource/System.Core/System/Security/Cryptography/BCryptNative.cs
+../referencesource/System.Core/System/Security/Cryptography/CngAlgorithm.cs
+../referencesource/System.Core/System/Security/Cryptography/CngAlgorithmGroup.cs
+../referencesource/System.Core/System/Security/Cryptography/CngKey.cs
../referencesource/System.Core/System/Security/Cryptography/CngKeyBlobFormat.cs
+../referencesource/System.Core/System/Security/Cryptography/CngKeyCreationParameters.cs
+../referencesource/System.Core/System/Security/Cryptography/CngProperty.cs
+../referencesource/System.Core/System/Security/Cryptography/CngProvider.cs
+../referencesource/System.Core/System/Security/Cryptography/CngUIPolicy.cs
../referencesource/System.Core/System/Security/Cryptography/ECDiffieHellmanPublicKey.cs
../referencesource/System.Core/System/Security/Cryptography/ECDsa.cs
+../referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs
+../referencesource/System.Core/System/Security/Cryptography/NCryptNative.cs
+../referencesource/System.Core/System/Security/Cryptography/RsaCng.cs
../referencesource/System.Core/System/threading/ReaderWriterLockSlim/ReaderWriterLockSlim.cs
System.Security.Cryptography/AesCryptoServiceProvider.cs
System.Security.Cryptography/AesTransform.cs
-System.Security.Cryptography/CngAlgorithm.cs
-System.Security.Cryptography/CngAlgorithmGroup.cs
System.Security.Cryptography/MD5Cng.cs
System.Security.Cryptography/SHA1Cng.cs
System.Security.Cryptography/SHA256Cng.cs
#include common_System.Core.dll.sources
#include dynamic_System.Core.dll.sources
-Microsoft.Win32.SafeHandles/SafePipeHandle.cs
-
-System.IO.Pipes/AnonymousPipeClientStream.cs
-System.IO.Pipes/AnonymousPipeServerStream.cs
-System.IO.Pipes/NamedPipeClientStream.cs
-System.IO.Pipes/NamedPipeServerStream.cs
System.IO.Pipes/PipeAccessRights.cs
System.IO.Pipes/PipeAccessRule.cs
System.IO.Pipes/PipeAuditRule.cs
-System.IO.Pipes/PipeDirection.cs
-System.IO.Pipes/PipeInterfaces.cs
-System.IO.Pipes/PipeOptions.cs
System.IO.Pipes/PipeSecurity.cs
-System.IO.Pipes/PipeStream.cs
System.IO.Pipes/PipeStreamImpersonationWorker.cs
-System.IO.Pipes/PipeTransmissionMode.cs
System.IO.Pipes/PipeUnix.cs
System.IO.Pipes/PipeWin32.cs
System.Security.Cryptography/AesCryptoServiceProvider.cs
System.Security.Cryptography/AesTransform.cs
-System.Security.Cryptography/CngAlgorithm.cs
-System.Security.Cryptography/CngAlgorithmGroup.cs
System.Security.Cryptography/MD5Cng.cs
System.Security.Cryptography/SHA1Cng.cs
System.Security.Cryptography/SHA256Cng.cs
namespace Microsoft.SqlServer.Server
{
- public sealed class SqlDataRecord : IDataRecord
+ public class SqlDataRecord : IDataRecord
{
- public bool GetBoolean (int i)
+ public SqlDataRecord (params SqlMetaData[] metaData)
+ {
+ }
+
+ public virtual bool GetBoolean (int ordinal)
{
throw new NotImplementedException ();
}
- public byte GetByte (int i)
+ public virtual byte GetByte (int ordinal)
{
throw new NotImplementedException ();
}
- public long GetBytes (int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
+ public virtual long GetBytes (int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length)
{
throw new NotImplementedException ();
}
- public char GetChar (int i)
+ public virtual char GetChar (int ordinal)
{
throw new NotImplementedException ();
}
- public long GetChars (int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
+ public virtual long GetChars (int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length)
{
throw new NotImplementedException ();
}
- public IDataReader GetData (int i)
+ public virtual IDataReader GetData (int ordinal)
{
throw new NotImplementedException ();
}
- public string GetDataTypeName (int i)
+ public virtual string GetDataTypeName (int ordinal)
{
throw new NotImplementedException ();
}
- public DateTime GetDateTime (int i)
+ public virtual DateTime GetDateTime (int ordinal)
{
throw new NotImplementedException ();
}
- public decimal GetDecimal (int i)
+ public virtual decimal GetDecimal (int ordinal)
{
throw new NotImplementedException ();
}
- public double GetDouble (int i)
+ public virtual double GetDouble (int ordinal)
{
throw new NotImplementedException ();
}
- public System.Type GetFieldType (int i)
+ public virtual System.Type GetFieldType (int ordinal)
{
throw new NotImplementedException ();
}
- public float GetFloat (int i)
+ public virtual float GetFloat (int ordinal)
{
throw new NotImplementedException ();
}
- public Guid GetGuid (int i)
+ public virtual Guid GetGuid (int ordinal)
{
throw new NotImplementedException ();
}
- public short GetInt16 (int i)
+ public virtual short GetInt16 (int ordinal)
{
throw new NotImplementedException ();
}
- public int GetInt32 (int i)
+ public virtual int GetInt32 (int ordinal)
{
throw new NotImplementedException ();
}
- public long GetInt64 (int i)
+ public virtual long GetInt64 (int ordinal)
{
throw new NotImplementedException ();
}
- public string GetName (int i)
+ public virtual string GetName (int ordinal)
{
throw new NotImplementedException ();
}
- public int GetOrdinal (string name)
+ public virtual int GetOrdinal (string name)
{
throw new NotImplementedException ();
}
- public string GetString (int i)
+ public virtual string GetString (int ordinal)
{
throw new NotImplementedException ();
}
- public object GetValue (int i)
+ public virtual object GetValue (int ordinal)
{
throw new NotImplementedException ();
}
- public int GetValues (object[] values)
+ public virtual int GetValues (object[] values)
{
throw new NotImplementedException ();
}
- public bool IsDBNull (int i)
+ public virtual bool IsDBNull (int ordinal)
{
throw new NotImplementedException ();
}
- public int FieldCount {
+ public virtual int FieldCount {
get {
throw new NotImplementedException ();
}
}
- public object this [string index] {
+ public virtual object this [string name] {
get {
throw new NotImplementedException ();
}
}
- public object this [int index] {
+ public virtual object this [int ordinal] {
get {
throw new NotImplementedException ();
}
LIBRARY = System.Drawing.dll
LIB_REFS = System
-LIB_MCS_FLAGS = /unsafe \
+LIB_MCS_FLAGS = /unsafe -d:FEATURE_TYPECONVERTER \
-resource:Assembly/Mono.ico,Mono.ico -resource:Assembly/Information.ico,Information.ico \
-resource:Assembly/Error.ico,Error.ico -resource:Assembly/Warning.ico,Warning.ico \
-resource:Assembly/Question.ico,Question.ico -resource:Assembly/Shield.ico,Shield.ico
{
[Serializable]
[ComVisible (true)]
-#if !MONOTOUCH && !MONOMAC
+#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER
[TypeConverter (typeof (PointConverter))]
#endif
public struct Point
{
[Serializable]
[ComVisible (true)]
-#if !MONOTOUCH && !MONOMAC
+#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER
[TypeConverter (typeof (RectangleConverter))]
#endif
public struct Rectangle
{
[Serializable]
[ComVisible (true)]
-#if !MONOTOUCH && !MONOMAC
+#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER
[TypeConverter (typeof (SizeConverter))]
#endif
public struct Size
{
[Serializable]
[ComVisible (true)]
-#if !MONOTOUCH && !MONOMAC
+#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER
[TypeConverter (typeof (SizeFConverter))]
#endif
public struct SizeF
--- /dev/null
+//
+// AssemblyInfo.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.Net.Http.WinHttpHandler.dll")]
+[assembly: AssemblyDescription ("System.Net.Http.WinHttpHandler.dll")]
+[assembly: AssemblyDefaultAlias ("System.Net.Http.WinHttpHandler.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile("../msfinal.pub")]
+
+[assembly: SecurityCritical]
+
+[assembly: ComVisible (false)]
\ No newline at end of file
--- /dev/null
+thisdir = class/System.Net.Http.WinHttpHandler
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.Net.Http.WinHttpHandler.dll
+LIB_REFS = System System.Net.Http
+LIB_MCS_FLAGS =
+
+NO_TEST = yes
+
+include ../../build/library.make
--- /dev/null
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+Assembly/AssemblyInfo.cs
+
+System.Net.Http/CookieUsePolicy.cs
+System.Net.Http/WindowsProxyUsePolicy.cs
+System.Net.Http/WinHttpHandler.cs
--- /dev/null
+//
+// CookieUsePolicy.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Net.Http
+{
+ public enum CookieUsePolicy
+ {
+ IgnoreCookies = 0,
+ UseInternalCookieStoreOnly = 1,
+ UseSpecifiedCookieContainer = 2,
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// WinHttpHandler.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Net.Security;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace System.Net.Http
+{
+ public class WinHttpHandler : HttpMessageHandler
+ {
+ public WinHttpHandler() { throw new PlatformNotSupportedException (); }
+
+ public DecompressionMethods AutomaticDecompression { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public bool AutomaticRedirection { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public bool CheckCertificateRevocationList { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public ClientCertificateOption ClientCertificateOption { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public X509Certificate2Collection ClientCertificates { get { throw new PlatformNotSupportedException (); } }
+
+ public CookieContainer CookieContainer { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public CookieUsePolicy CookieUsePolicy { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public ICredentials DefaultProxyCredentials { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public int MaxAutomaticRedirections { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public int MaxConnectionsPerServer { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public int MaxResponseDrainSize { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public int MaxResponseHeadersLength { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public bool PreAuthenticate { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public IDictionary<string, object> Properties { get { throw new PlatformNotSupportedException (); } }
+
+ public IWebProxy Proxy { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public TimeSpan ReceiveDataTimeout { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public TimeSpan ReceiveHeadersTimeout { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public TimeSpan SendTimeout { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> ServerCertificateValidationCallback { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public ICredentials ServerCredentials { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public SslProtocols SslProtocols { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ public WindowsProxyUsePolicy WindowsProxyUsePolicy { get { throw new PlatformNotSupportedException (); } set { throw new PlatformNotSupportedException (); } }
+
+ protected override void Dispose (bool disposing) { throw new PlatformNotSupportedException (); }
+
+ protected override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, Threading.CancellationToken cancellationToken) { throw new PlatformNotSupportedException (); }
+ }
+}
\ No newline at end of file
--- /dev/null
+//
+// WindowsProxyUsePolicy.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Net.Http
+{
+ public enum WindowsProxyUsePolicy
+ {
+ DoNotUseProxy = 0,
+ UseCustomProxy = 3,
+ UseWinHttpProxy = 1,
+ UseWinInetProxy = 2,
+ }
+}
\ No newline at end of file
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Proxy_Disabled ()
{
var pp = WebRequest.DefaultWebProxy;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_Default ()
{
bool? failed = null;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_Version_1_0 ()
{
bool? failed = null;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_ClientHandlerSettings ()
{
bool? failed = null;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_CustomHeaders ()
{
bool? failed = null;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_CustomHeaders_SpecialSeparators ()
{
bool? failed = null;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_CustomHeaders_Host ()
{
bool? failed = null;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Transfer_Encoding_Chunked ()
{
bool? failed = null;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Transfer_Encoding_Custom ()
{
bool? failed = null;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_Content ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_Content_MaxResponseContentBufferSize ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_Content_MaxResponseContentBufferSize_Error ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_NoContent ()
{
foreach (var method in new HttpMethod[] { HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete }) {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Complete_Error ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Content_Get ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Content_BomEncoding ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Content_Put ()
{
bool passed = false;
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Send_Content_Put_CustomStream ()
{
bool passed = false;
[Test]
[Category ("MobileNotWorking")] // Missing encoding
+ [Category ("RequiresBSDSockets")]
public void GetString_Many ()
{
Action<HttpListenerContext> context = (HttpListenerContext l) => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void GetByteArray_ServerError ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void DisallowAutoRedirect ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void RequestUriAfterRedirect ()
{
var listener = CreateListener (l => {
}
[Test]
+ [Category ("RequiresBSDSockets")]
/*
* Properties may only be modified before sending the first request.
*/
LIBRARY = System.Numerics.Vectors.dll
LIB_REFS = System System.Numerics
-LIB_MCS_FLAGS =
+LIB_MCS_FLAGS = -unsafe
EXTRA_DISTFILES =
--- /dev/null
+// generated from Strings.resx in corefx
+
+partial class SR
+{
+ public const string Arg_ArgumentOutOfRangeException="Index was out of bounds:";
+ public const string Arg_ElementsInSourceIsGreaterThanDestination="Number of elements in source vector is greater than the destination array";
+ public const string Arg_MultiDimArrayNotSupported="Only one-dimensional arrays are supported";
+ public const string Arg_NullArgumentNullRef="The method was called with a null array argument.";
+ public const string Arg_RegisterLengthOfRangeException="length must be less than";
+ public const string Arg_TypeNotSupported="Specified type is not supported";
+ public const string Reflection_MethodNotSupported="Vector<T>.Count cannot be called via reflection when intrinsics are enabled.";
+
+ public static string Format (string message, object data)
+ {
+ return string.Format (message, data);
+ }
+}
../../build/common/SR.cs
Assembly/AssemblyInfo.cs
Assembly/TypeForwarders.cs
+SR.cs
+System.Numerics/ConstantHelper.cs
+System.Numerics/HashCodeHelper.cs
+System.Numerics/JitIntrinsicAttribute.cs
+System.Numerics/Register.cs
+System.Numerics/Vector_Operations.cs
+System.Numerics/Vector.cs
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.CompilerServices;
+
+namespace System.Numerics
+{
+ internal class ConstantHelper
+ {
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Byte GetByteWithAllBitsSet()
+ {
+ Byte value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Byte*)&value) = (Byte)0xff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static SByte GetSByteWithAllBitsSet()
+ {
+ SByte value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((SByte*)&value) = (SByte)0xff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static UInt16 GetUInt16WithAllBitsSet()
+ {
+ UInt16 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((UInt16*)&value) = (UInt16)0xffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Int16 GetInt16WithAllBitsSet()
+ {
+ Int16 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int16*)&value) = (Int16)0xffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static UInt32 GetUInt32WithAllBitsSet()
+ {
+ UInt32 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((UInt32*)&value) = (UInt32)0xffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Int32 GetInt32WithAllBitsSet()
+ {
+ Int32 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int32*)&value) = (Int32)0xffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static UInt64 GetUInt64WithAllBitsSet()
+ {
+ UInt64 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((UInt64*)&value) = (UInt64)0xffffffffffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Int64 GetInt64WithAllBitsSet()
+ {
+ Int64 value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int64*)&value) = (Int64)0xffffffffffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Single GetSingleWithAllBitsSet()
+ {
+ Single value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int32*)&value) = (Int32)0xffffffff;
+ }
+ }
+ return value;
+ }
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Double GetDoubleWithAllBitsSet()
+ {
+ Double value = 0;
+ unsafe
+ {
+ unchecked
+ {
+ *((Int64*)&value) = (Int64)0xffffffffffffffff;
+ }
+ }
+ return value;
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Numerics
+{
+ internal static class HashCodeHelper
+ {
+ /// <summary>
+ /// Combines two hash codes, useful for combining hash codes of individual vector elements
+ /// </summary>
+ internal static int CombineHashCodes(int h1, int h2)
+ {
+ return (((h1 << 5) + h1) ^ h2);
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Numerics
+{
+ /// <summary>
+ /// An attribute that can be attached to JIT Intrinsic methods/properties
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)]
+ internal class JitIntrinsicAttribute : Attribute
+ {
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+namespace System.Numerics
+{
+ /// <summary>
+ /// A structure describing the layout of an SSE2-sized register.
+ /// Contains overlapping fields representing the set of valid numeric types.
+ /// Allows the generic Vector'T struct to contain an explicit field layout.
+ /// </summary>
+ [StructLayout(LayoutKind.Explicit)]
+ internal struct Register
+ {
+ #region Internal Storage Fields
+ // Internal System.Byte Fields
+ [FieldOffset(0)]
+ internal Byte byte_0;
+ [FieldOffset(1)]
+ internal Byte byte_1;
+ [FieldOffset(2)]
+ internal Byte byte_2;
+ [FieldOffset(3)]
+ internal Byte byte_3;
+ [FieldOffset(4)]
+ internal Byte byte_4;
+ [FieldOffset(5)]
+ internal Byte byte_5;
+ [FieldOffset(6)]
+ internal Byte byte_6;
+ [FieldOffset(7)]
+ internal Byte byte_7;
+ [FieldOffset(8)]
+ internal Byte byte_8;
+ [FieldOffset(9)]
+ internal Byte byte_9;
+ [FieldOffset(10)]
+ internal Byte byte_10;
+ [FieldOffset(11)]
+ internal Byte byte_11;
+ [FieldOffset(12)]
+ internal Byte byte_12;
+ [FieldOffset(13)]
+ internal Byte byte_13;
+ [FieldOffset(14)]
+ internal Byte byte_14;
+ [FieldOffset(15)]
+ internal Byte byte_15;
+
+ // Internal System.SByte Fields
+ [FieldOffset(0)]
+ internal SByte sbyte_0;
+ [FieldOffset(1)]
+ internal SByte sbyte_1;
+ [FieldOffset(2)]
+ internal SByte sbyte_2;
+ [FieldOffset(3)]
+ internal SByte sbyte_3;
+ [FieldOffset(4)]
+ internal SByte sbyte_4;
+ [FieldOffset(5)]
+ internal SByte sbyte_5;
+ [FieldOffset(6)]
+ internal SByte sbyte_6;
+ [FieldOffset(7)]
+ internal SByte sbyte_7;
+ [FieldOffset(8)]
+ internal SByte sbyte_8;
+ [FieldOffset(9)]
+ internal SByte sbyte_9;
+ [FieldOffset(10)]
+ internal SByte sbyte_10;
+ [FieldOffset(11)]
+ internal SByte sbyte_11;
+ [FieldOffset(12)]
+ internal SByte sbyte_12;
+ [FieldOffset(13)]
+ internal SByte sbyte_13;
+ [FieldOffset(14)]
+ internal SByte sbyte_14;
+ [FieldOffset(15)]
+ internal SByte sbyte_15;
+
+ // Internal System.UInt16 Fields
+ [FieldOffset(0)]
+ internal UInt16 uint16_0;
+ [FieldOffset(2)]
+ internal UInt16 uint16_1;
+ [FieldOffset(4)]
+ internal UInt16 uint16_2;
+ [FieldOffset(6)]
+ internal UInt16 uint16_3;
+ [FieldOffset(8)]
+ internal UInt16 uint16_4;
+ [FieldOffset(10)]
+ internal UInt16 uint16_5;
+ [FieldOffset(12)]
+ internal UInt16 uint16_6;
+ [FieldOffset(14)]
+ internal UInt16 uint16_7;
+
+ // Internal System.Int16 Fields
+ [FieldOffset(0)]
+ internal Int16 int16_0;
+ [FieldOffset(2)]
+ internal Int16 int16_1;
+ [FieldOffset(4)]
+ internal Int16 int16_2;
+ [FieldOffset(6)]
+ internal Int16 int16_3;
+ [FieldOffset(8)]
+ internal Int16 int16_4;
+ [FieldOffset(10)]
+ internal Int16 int16_5;
+ [FieldOffset(12)]
+ internal Int16 int16_6;
+ [FieldOffset(14)]
+ internal Int16 int16_7;
+
+ // Internal System.UInt32 Fields
+ [FieldOffset(0)]
+ internal UInt32 uint32_0;
+ [FieldOffset(4)]
+ internal UInt32 uint32_1;
+ [FieldOffset(8)]
+ internal UInt32 uint32_2;
+ [FieldOffset(12)]
+ internal UInt32 uint32_3;
+
+ // Internal System.Int32 Fields
+ [FieldOffset(0)]
+ internal Int32 int32_0;
+ [FieldOffset(4)]
+ internal Int32 int32_1;
+ [FieldOffset(8)]
+ internal Int32 int32_2;
+ [FieldOffset(12)]
+ internal Int32 int32_3;
+
+ // Internal System.UInt64 Fields
+ [FieldOffset(0)]
+ internal UInt64 uint64_0;
+ [FieldOffset(8)]
+ internal UInt64 uint64_1;
+
+ // Internal System.Int64 Fields
+ [FieldOffset(0)]
+ internal Int64 int64_0;
+ [FieldOffset(8)]
+ internal Int64 int64_1;
+
+ // Internal System.Single Fields
+ [FieldOffset(0)]
+ internal Single single_0;
+ [FieldOffset(4)]
+ internal Single single_1;
+ [FieldOffset(8)]
+ internal Single single_2;
+ [FieldOffset(12)]
+ internal Single single_3;
+
+ // Internal System.Double Fields
+ [FieldOffset(0)]
+ internal Double double_0;
+ [FieldOffset(8)]
+ internal Double double_1;
+
+ #endregion Internal Storage Fields
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace System.Numerics
+{
+ /* Note: The following patterns are used throughout the code here and are described here
+ *
+ * PATTERN:
+ * if (typeof(T) == typeof(Int32)) { ... }
+ * else if (typeof(T) == typeof(Single)) { ... }
+ * EXPLANATION:
+ * At runtime, each instantiation of Vector<T> will be type-specific, and each of these typeof blocks will be eliminated,
+ * as typeof(T) is a (JIT) compile-time constant for each instantiation. This design was chosen to eliminate any overhead from
+ * delegates and other patterns.
+ *
+ * PATTERN:
+ * if (Vector.IsHardwareAccelerated) { ... }
+ * else { ... }
+ * EXPLANATION
+ * This pattern solves two problems:
+ * 1. Allows us to unroll loops when we know the size (when no hardware acceleration is present)
+ * 2. Allows reflection to work:
+ * - If a method is called via reflection, it will not be "intrinsified", which would cause issues if we did
+ * not provide an implementation for that case (i.e. if it only included a case which assumed 16-byte registers)
+ * (NOTE: It is assumed that Vector.IsHardwareAccelerated will be a compile-time constant, eliminating these checks
+ * from the JIT'd code.)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /// <summary>
+ /// A structure that represents a single Vector. The count of this Vector is fixed but CPU register dependent.
+ /// This struct only supports numerical types. This type is intended to be used as a building block for vectorizing
+ /// large algorithms. This type is immutable, individual elements cannot be modified.
+ /// </summary>
+ public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
+ {
+ #region Fields
+ private Register register;
+ #endregion Fields
+
+ #region Static Members
+ /// <summary>
+ /// Returns the number of elements stored in the vector. This value is hardware dependent.
+ /// </summary>
+ [JitIntrinsic]
+ public static int Count
+ {
+ get
+ {
+ return s_count;
+ }
+ }
+ private static readonly int s_count = InitializeCount();
+
+ /// <summary>
+ /// Returns a vector containing all zeroes.
+ /// </summary>
+ [JitIntrinsic]
+ public static Vector<T> Zero { get { return zero; } }
+ private static readonly Vector<T> zero = new Vector<T>(GetZeroValue());
+
+ /// <summary>
+ /// Returns a vector containing all ones.
+ /// </summary>
+ [JitIntrinsic]
+ public static Vector<T> One { get { return one; } }
+ private static readonly Vector<T> one = new Vector<T>(GetOneValue());
+
+ internal static Vector<T> AllOnes { get { return allOnes; } }
+ private static readonly Vector<T> allOnes = new Vector<T>(GetAllBitsSetValue());
+ #endregion Static Members
+
+ #region Static Initialization
+ private struct VectorSizeHelper
+ {
+ internal Vector<T> _placeholder;
+ internal byte _byte;
+ }
+
+ // Calculates the size of this struct in bytes, by computing the offset of a field in a structure
+ private static unsafe int InitializeCount()
+ {
+ VectorSizeHelper vsh;
+ byte* vectorBase = &vsh._placeholder.register.byte_0;
+ byte* byteBase = &vsh._byte;
+ int vectorSizeInBytes = (int)(byteBase - vectorBase);
+
+ int typeSizeInBytes = -1;
+ if (typeof(T) == typeof(Byte))
+ {
+ typeSizeInBytes = sizeof(Byte);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ typeSizeInBytes = sizeof(SByte);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ typeSizeInBytes = sizeof(UInt16);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ typeSizeInBytes = sizeof(Int16);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ typeSizeInBytes = sizeof(UInt32);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ typeSizeInBytes = sizeof(Int32);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ typeSizeInBytes = sizeof(UInt64);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ typeSizeInBytes = sizeof(Int64);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ typeSizeInBytes = sizeof(Single);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ typeSizeInBytes = sizeof(Double);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+
+ return vectorSizeInBytes / typeSizeInBytes;
+ }
+ #endregion Static Initialization
+
+ #region Constructors
+ /// <summary>
+ /// Constructs a vector whose components are all <code>value</code>
+ /// </summary>
+ [JitIntrinsic]
+ public unsafe Vector(T value)
+ : this()
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ fixed (Byte* basePtr = &this.register.byte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Byte)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ fixed (SByte* basePtr = &this.register.sbyte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (SByte)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ fixed (UInt16* basePtr = &this.register.uint16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt16)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ fixed (Int16* basePtr = &this.register.int16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int16)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ fixed (UInt32* basePtr = &this.register.uint32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt32)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ fixed (Int32* basePtr = &this.register.int32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int32)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ fixed (UInt64* basePtr = &this.register.uint64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt64)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ fixed (Int64* basePtr = &this.register.int64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int64)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ fixed (Single* basePtr = &this.register.single_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Single)(object)value;
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ fixed (Double* basePtr = &this.register.double_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Double)(object)value;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ register.byte_0 = (Byte)(object)value;
+ register.byte_1 = (Byte)(object)value;
+ register.byte_2 = (Byte)(object)value;
+ register.byte_3 = (Byte)(object)value;
+ register.byte_4 = (Byte)(object)value;
+ register.byte_5 = (Byte)(object)value;
+ register.byte_6 = (Byte)(object)value;
+ register.byte_7 = (Byte)(object)value;
+ register.byte_8 = (Byte)(object)value;
+ register.byte_9 = (Byte)(object)value;
+ register.byte_10 = (Byte)(object)value;
+ register.byte_11 = (Byte)(object)value;
+ register.byte_12 = (Byte)(object)value;
+ register.byte_13 = (Byte)(object)value;
+ register.byte_14 = (Byte)(object)value;
+ register.byte_15 = (Byte)(object)value;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ register.sbyte_0 = (SByte)(object)value;
+ register.sbyte_1 = (SByte)(object)value;
+ register.sbyte_2 = (SByte)(object)value;
+ register.sbyte_3 = (SByte)(object)value;
+ register.sbyte_4 = (SByte)(object)value;
+ register.sbyte_5 = (SByte)(object)value;
+ register.sbyte_6 = (SByte)(object)value;
+ register.sbyte_7 = (SByte)(object)value;
+ register.sbyte_8 = (SByte)(object)value;
+ register.sbyte_9 = (SByte)(object)value;
+ register.sbyte_10 = (SByte)(object)value;
+ register.sbyte_11 = (SByte)(object)value;
+ register.sbyte_12 = (SByte)(object)value;
+ register.sbyte_13 = (SByte)(object)value;
+ register.sbyte_14 = (SByte)(object)value;
+ register.sbyte_15 = (SByte)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ register.uint16_0 = (UInt16)(object)value;
+ register.uint16_1 = (UInt16)(object)value;
+ register.uint16_2 = (UInt16)(object)value;
+ register.uint16_3 = (UInt16)(object)value;
+ register.uint16_4 = (UInt16)(object)value;
+ register.uint16_5 = (UInt16)(object)value;
+ register.uint16_6 = (UInt16)(object)value;
+ register.uint16_7 = (UInt16)(object)value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ register.int16_0 = (Int16)(object)value;
+ register.int16_1 = (Int16)(object)value;
+ register.int16_2 = (Int16)(object)value;
+ register.int16_3 = (Int16)(object)value;
+ register.int16_4 = (Int16)(object)value;
+ register.int16_5 = (Int16)(object)value;
+ register.int16_6 = (Int16)(object)value;
+ register.int16_7 = (Int16)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ register.uint32_0 = (UInt32)(object)value;
+ register.uint32_1 = (UInt32)(object)value;
+ register.uint32_2 = (UInt32)(object)value;
+ register.uint32_3 = (UInt32)(object)value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ register.int32_0 = (Int32)(object)value;
+ register.int32_1 = (Int32)(object)value;
+ register.int32_2 = (Int32)(object)value;
+ register.int32_3 = (Int32)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ register.uint64_0 = (UInt64)(object)value;
+ register.uint64_1 = (UInt64)(object)value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ register.int64_0 = (Int64)(object)value;
+ register.int64_1 = (Int64)(object)value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ register.single_0 = (Single)(object)value;
+ register.single_1 = (Single)(object)value;
+ register.single_2 = (Single)(object)value;
+ register.single_3 = (Single)(object)value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ register.double_0 = (Double)(object)value;
+ register.double_1 = (Double)(object)value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Constructs a vector from the given array. The size of the given array must be at least Vector'T.Count.
+ /// </summary>
+ [JitIntrinsic]
+ public unsafe Vector(T[] values) : this(values, 0) { }
+
+ /// <summary>
+ /// Constructs a vector from the given array, starting from the given index.
+ /// The array must contain at least Vector'T.Count from the given index.
+ /// </summary>
+ public unsafe Vector(T[] values, int index)
+ : this()
+ {
+ if (values == null)
+ {
+ // Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
+ throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
+ }
+ if (index < 0 || (values.Length - index) < Count)
+ {
+ throw new IndexOutOfRangeException();
+ }
+
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ fixed (Byte* basePtr = &this.register.byte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Byte)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ fixed (SByte* basePtr = &this.register.sbyte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (SByte)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ fixed (UInt16* basePtr = &this.register.uint16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt16)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ fixed (Int16* basePtr = &this.register.int16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int16)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ fixed (UInt32* basePtr = &this.register.uint32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt32)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ fixed (Int32* basePtr = &this.register.int32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int32)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ fixed (UInt64* basePtr = &this.register.uint64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (UInt64)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ fixed (Int64* basePtr = &this.register.int64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Int64)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ fixed (Single* basePtr = &this.register.single_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Single)(object)values[g + index];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ fixed (Double* basePtr = &this.register.double_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ *(basePtr + g) = (Double)(object)values[g + index];
+ }
+ }
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ fixed (Byte* basePtr = &this.register.byte_0)
+ {
+ *(basePtr + 0) = (Byte)(object)values[0 + index];
+ *(basePtr + 1) = (Byte)(object)values[1 + index];
+ *(basePtr + 2) = (Byte)(object)values[2 + index];
+ *(basePtr + 3) = (Byte)(object)values[3 + index];
+ *(basePtr + 4) = (Byte)(object)values[4 + index];
+ *(basePtr + 5) = (Byte)(object)values[5 + index];
+ *(basePtr + 6) = (Byte)(object)values[6 + index];
+ *(basePtr + 7) = (Byte)(object)values[7 + index];
+ *(basePtr + 8) = (Byte)(object)values[8 + index];
+ *(basePtr + 9) = (Byte)(object)values[9 + index];
+ *(basePtr + 10) = (Byte)(object)values[10 + index];
+ *(basePtr + 11) = (Byte)(object)values[11 + index];
+ *(basePtr + 12) = (Byte)(object)values[12 + index];
+ *(basePtr + 13) = (Byte)(object)values[13 + index];
+ *(basePtr + 14) = (Byte)(object)values[14 + index];
+ *(basePtr + 15) = (Byte)(object)values[15 + index];
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ fixed (SByte* basePtr = &this.register.sbyte_0)
+ {
+ *(basePtr + 0) = (SByte)(object)values[0 + index];
+ *(basePtr + 1) = (SByte)(object)values[1 + index];
+ *(basePtr + 2) = (SByte)(object)values[2 + index];
+ *(basePtr + 3) = (SByte)(object)values[3 + index];
+ *(basePtr + 4) = (SByte)(object)values[4 + index];
+ *(basePtr + 5) = (SByte)(object)values[5 + index];
+ *(basePtr + 6) = (SByte)(object)values[6 + index];
+ *(basePtr + 7) = (SByte)(object)values[7 + index];
+ *(basePtr + 8) = (SByte)(object)values[8 + index];
+ *(basePtr + 9) = (SByte)(object)values[9 + index];
+ *(basePtr + 10) = (SByte)(object)values[10 + index];
+ *(basePtr + 11) = (SByte)(object)values[11 + index];
+ *(basePtr + 12) = (SByte)(object)values[12 + index];
+ *(basePtr + 13) = (SByte)(object)values[13 + index];
+ *(basePtr + 14) = (SByte)(object)values[14 + index];
+ *(basePtr + 15) = (SByte)(object)values[15 + index];
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ fixed (UInt16* basePtr = &this.register.uint16_0)
+ {
+ *(basePtr + 0) = (UInt16)(object)values[0 + index];
+ *(basePtr + 1) = (UInt16)(object)values[1 + index];
+ *(basePtr + 2) = (UInt16)(object)values[2 + index];
+ *(basePtr + 3) = (UInt16)(object)values[3 + index];
+ *(basePtr + 4) = (UInt16)(object)values[4 + index];
+ *(basePtr + 5) = (UInt16)(object)values[5 + index];
+ *(basePtr + 6) = (UInt16)(object)values[6 + index];
+ *(basePtr + 7) = (UInt16)(object)values[7 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ fixed (Int16* basePtr = &this.register.int16_0)
+ {
+ *(basePtr + 0) = (Int16)(object)values[0 + index];
+ *(basePtr + 1) = (Int16)(object)values[1 + index];
+ *(basePtr + 2) = (Int16)(object)values[2 + index];
+ *(basePtr + 3) = (Int16)(object)values[3 + index];
+ *(basePtr + 4) = (Int16)(object)values[4 + index];
+ *(basePtr + 5) = (Int16)(object)values[5 + index];
+ *(basePtr + 6) = (Int16)(object)values[6 + index];
+ *(basePtr + 7) = (Int16)(object)values[7 + index];
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ fixed (UInt32* basePtr = &this.register.uint32_0)
+ {
+ *(basePtr + 0) = (UInt32)(object)values[0 + index];
+ *(basePtr + 1) = (UInt32)(object)values[1 + index];
+ *(basePtr + 2) = (UInt32)(object)values[2 + index];
+ *(basePtr + 3) = (UInt32)(object)values[3 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ fixed (Int32* basePtr = &this.register.int32_0)
+ {
+ *(basePtr + 0) = (Int32)(object)values[0 + index];
+ *(basePtr + 1) = (Int32)(object)values[1 + index];
+ *(basePtr + 2) = (Int32)(object)values[2 + index];
+ *(basePtr + 3) = (Int32)(object)values[3 + index];
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ fixed (UInt64* basePtr = &this.register.uint64_0)
+ {
+ *(basePtr + 0) = (UInt64)(object)values[0 + index];
+ *(basePtr + 1) = (UInt64)(object)values[1 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ fixed (Int64* basePtr = &this.register.int64_0)
+ {
+ *(basePtr + 0) = (Int64)(object)values[0 + index];
+ *(basePtr + 1) = (Int64)(object)values[1 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ fixed (Single* basePtr = &this.register.single_0)
+ {
+ *(basePtr + 0) = (Single)(object)values[0 + index];
+ *(basePtr + 1) = (Single)(object)values[1 + index];
+ *(basePtr + 2) = (Single)(object)values[2 + index];
+ *(basePtr + 3) = (Single)(object)values[3 + index];
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ fixed (Double* basePtr = &this.register.double_0)
+ {
+ *(basePtr + 0) = (Double)(object)values[0 + index];
+ *(basePtr + 1) = (Double)(object)values[1 + index];
+ }
+ }
+ }
+ }
+
+#pragma warning disable 3001 // void* is not a CLS-Compliant argument type
+ private unsafe Vector(void* dataPointer) : this(dataPointer, 0) { }
+#pragma warning restore 3001 // void* is not a CLS-Compliant argument type
+
+#pragma warning disable 3001 // void* is not a CLS-Compliant argument type
+ // Implemented with offset if this API ever becomes public; an offset of 0 is used internally.
+ private unsafe Vector(void* dataPointer, int offset)
+ : this()
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* castedPtr = (Byte*)dataPointer;
+ castedPtr += offset;
+ fixed (Byte* registerBase = &this.register.byte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* castedPtr = (SByte*)dataPointer;
+ castedPtr += offset;
+ fixed (SByte* registerBase = &this.register.sbyte_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* castedPtr = (UInt16*)dataPointer;
+ castedPtr += offset;
+ fixed (UInt16* registerBase = &this.register.uint16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* castedPtr = (Int16*)dataPointer;
+ castedPtr += offset;
+ fixed (Int16* registerBase = &this.register.int16_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* castedPtr = (UInt32*)dataPointer;
+ castedPtr += offset;
+ fixed (UInt32* registerBase = &this.register.uint32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* castedPtr = (Int32*)dataPointer;
+ castedPtr += offset;
+ fixed (Int32* registerBase = &this.register.int32_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* castedPtr = (UInt64*)dataPointer;
+ castedPtr += offset;
+ fixed (UInt64* registerBase = &this.register.uint64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* castedPtr = (Int64*)dataPointer;
+ castedPtr += offset;
+ fixed (Int64* registerBase = &this.register.int64_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* castedPtr = (Single*)dataPointer;
+ castedPtr += offset;
+ fixed (Single* registerBase = &this.register.single_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* castedPtr = (Double*)dataPointer;
+ castedPtr += offset;
+ fixed (Double* registerBase = &this.register.double_0)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ registerBase[g] = castedPtr[g];
+ }
+ }
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+#pragma warning restore 3001 // void* is not a CLS-Compliant argument type
+
+ private Vector(ref Register existingRegister)
+ {
+ this.register = existingRegister;
+ }
+ #endregion Constructors
+
+ #region Public Instance Methods
+ /// <summary>
+ /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
+ /// </summary>
+ /// <param name="destination">The destination array which the values are copied into</param>
+ /// <exception cref="ArgumentNullException">If the destination array is null</exception>
+ /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination array</exception>
+ [JitIntrinsic]
+ public unsafe void CopyTo(T[] destination)
+ {
+ CopyTo(destination, 0);
+ }
+
+ /// <summary>
+ /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count.
+ /// </summary>
+ /// <param name="destination">The destination array which the values are copied into</param>
+ /// <param name="startIndex">The index to start copying to</param>
+ /// <exception cref="ArgumentNullException">If the destination array is null</exception>
+ /// <exception cref="ArgumentOutOfRangeException">If index is greater than end of the array or index is less than zero</exception>
+ /// <exception cref="ArgumentException">If number of elements in source vector is greater than those available in destination array</exception>
+ [JitIntrinsic]
+ public unsafe void CopyTo(T[] destination, int startIndex)
+ {
+ if (destination == null)
+ {
+ // Match the JIT's exception type here. For perf, a NullReference is thrown instead of an ArgumentNull.
+ throw new NullReferenceException(SR.Arg_NullArgumentNullRef);
+ }
+ if (startIndex < 0 || startIndex >= destination.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.Format(SR.Arg_ArgumentOutOfRangeException, startIndex));
+ }
+ if ((destination.Length - startIndex) < Count)
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex));
+ }
+
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte[] byteArray = (Byte[])(object)destination;
+ fixed (Byte* destinationBase = byteArray)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Byte)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte[] sbyteArray = (SByte[])(object)destination;
+ fixed (SByte* destinationBase = sbyteArray)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (SByte)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16[] uint16Array = (UInt16[])(object)destination;
+ fixed (UInt16* destinationBase = uint16Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (UInt16)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16[] int16Array = (Int16[])(object)destination;
+ fixed (Int16* destinationBase = int16Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Int16)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32[] uint32Array = (UInt32[])(object)destination;
+ fixed (UInt32* destinationBase = uint32Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (UInt32)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32[] int32Array = (Int32[])(object)destination;
+ fixed (Int32* destinationBase = int32Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Int32)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64[] uint64Array = (UInt64[])(object)destination;
+ fixed (UInt64* destinationBase = uint64Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (UInt64)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64[] int64Array = (Int64[])(object)destination;
+ fixed (Int64* destinationBase = int64Array)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Int64)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single[] singleArray = (Single[])(object)destination;
+ fixed (Single* destinationBase = singleArray)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Single)(object)this[g];
+ }
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double[] doubleArray = (Double[])(object)destination;
+ fixed (Double* destinationBase = doubleArray)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ destinationBase[startIndex + g] = (Double)(object)this[g];
+ }
+ }
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte[] byteArray = (Byte[])(object)destination;
+ fixed (Byte* destinationBase = byteArray)
+ {
+ destinationBase[startIndex + 0] = this.register.byte_0;
+ destinationBase[startIndex + 1] = this.register.byte_1;
+ destinationBase[startIndex + 2] = this.register.byte_2;
+ destinationBase[startIndex + 3] = this.register.byte_3;
+ destinationBase[startIndex + 4] = this.register.byte_4;
+ destinationBase[startIndex + 5] = this.register.byte_5;
+ destinationBase[startIndex + 6] = this.register.byte_6;
+ destinationBase[startIndex + 7] = this.register.byte_7;
+ destinationBase[startIndex + 8] = this.register.byte_8;
+ destinationBase[startIndex + 9] = this.register.byte_9;
+ destinationBase[startIndex + 10] = this.register.byte_10;
+ destinationBase[startIndex + 11] = this.register.byte_11;
+ destinationBase[startIndex + 12] = this.register.byte_12;
+ destinationBase[startIndex + 13] = this.register.byte_13;
+ destinationBase[startIndex + 14] = this.register.byte_14;
+ destinationBase[startIndex + 15] = this.register.byte_15;
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte[] sbyteArray = (SByte[])(object)destination;
+ fixed (SByte* destinationBase = sbyteArray)
+ {
+ destinationBase[startIndex + 0] = this.register.sbyte_0;
+ destinationBase[startIndex + 1] = this.register.sbyte_1;
+ destinationBase[startIndex + 2] = this.register.sbyte_2;
+ destinationBase[startIndex + 3] = this.register.sbyte_3;
+ destinationBase[startIndex + 4] = this.register.sbyte_4;
+ destinationBase[startIndex + 5] = this.register.sbyte_5;
+ destinationBase[startIndex + 6] = this.register.sbyte_6;
+ destinationBase[startIndex + 7] = this.register.sbyte_7;
+ destinationBase[startIndex + 8] = this.register.sbyte_8;
+ destinationBase[startIndex + 9] = this.register.sbyte_9;
+ destinationBase[startIndex + 10] = this.register.sbyte_10;
+ destinationBase[startIndex + 11] = this.register.sbyte_11;
+ destinationBase[startIndex + 12] = this.register.sbyte_12;
+ destinationBase[startIndex + 13] = this.register.sbyte_13;
+ destinationBase[startIndex + 14] = this.register.sbyte_14;
+ destinationBase[startIndex + 15] = this.register.sbyte_15;
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16[] uint16Array = (UInt16[])(object)destination;
+ fixed (UInt16* destinationBase = uint16Array)
+ {
+ destinationBase[startIndex + 0] = this.register.uint16_0;
+ destinationBase[startIndex + 1] = this.register.uint16_1;
+ destinationBase[startIndex + 2] = this.register.uint16_2;
+ destinationBase[startIndex + 3] = this.register.uint16_3;
+ destinationBase[startIndex + 4] = this.register.uint16_4;
+ destinationBase[startIndex + 5] = this.register.uint16_5;
+ destinationBase[startIndex + 6] = this.register.uint16_6;
+ destinationBase[startIndex + 7] = this.register.uint16_7;
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16[] int16Array = (Int16[])(object)destination;
+ fixed (Int16* destinationBase = int16Array)
+ {
+ destinationBase[startIndex + 0] = this.register.int16_0;
+ destinationBase[startIndex + 1] = this.register.int16_1;
+ destinationBase[startIndex + 2] = this.register.int16_2;
+ destinationBase[startIndex + 3] = this.register.int16_3;
+ destinationBase[startIndex + 4] = this.register.int16_4;
+ destinationBase[startIndex + 5] = this.register.int16_5;
+ destinationBase[startIndex + 6] = this.register.int16_6;
+ destinationBase[startIndex + 7] = this.register.int16_7;
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32[] uint32Array = (UInt32[])(object)destination;
+ fixed (UInt32* destinationBase = uint32Array)
+ {
+ destinationBase[startIndex + 0] = this.register.uint32_0;
+ destinationBase[startIndex + 1] = this.register.uint32_1;
+ destinationBase[startIndex + 2] = this.register.uint32_2;
+ destinationBase[startIndex + 3] = this.register.uint32_3;
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32[] int32Array = (Int32[])(object)destination;
+ fixed (Int32* destinationBase = int32Array)
+ {
+ destinationBase[startIndex + 0] = this.register.int32_0;
+ destinationBase[startIndex + 1] = this.register.int32_1;
+ destinationBase[startIndex + 2] = this.register.int32_2;
+ destinationBase[startIndex + 3] = this.register.int32_3;
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64[] uint64Array = (UInt64[])(object)destination;
+ fixed (UInt64* destinationBase = uint64Array)
+ {
+ destinationBase[startIndex + 0] = this.register.uint64_0;
+ destinationBase[startIndex + 1] = this.register.uint64_1;
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64[] int64Array = (Int64[])(object)destination;
+ fixed (Int64* destinationBase = int64Array)
+ {
+ destinationBase[startIndex + 0] = this.register.int64_0;
+ destinationBase[startIndex + 1] = this.register.int64_1;
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single[] singleArray = (Single[])(object)destination;
+ fixed (Single* destinationBase = singleArray)
+ {
+ destinationBase[startIndex + 0] = this.register.single_0;
+ destinationBase[startIndex + 1] = this.register.single_1;
+ destinationBase[startIndex + 2] = this.register.single_2;
+ destinationBase[startIndex + 3] = this.register.single_3;
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double[] doubleArray = (Double[])(object)destination;
+ fixed (Double* destinationBase = doubleArray)
+ {
+ destinationBase[startIndex + 0] = this.register.double_0;
+ destinationBase[startIndex + 1] = this.register.double_1;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns the element at the given index.
+ /// </summary>
+ [JitIntrinsic]
+ public unsafe T this[int index]
+ {
+ get
+ {
+ if (index >= Count || index < 0)
+ {
+ throw new IndexOutOfRangeException(SR.Format(SR.Arg_ArgumentOutOfRangeException, index));
+ }
+ if (typeof(T) == typeof(Byte))
+ {
+ fixed (Byte* basePtr = &this.register.byte_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ fixed (SByte* basePtr = &this.register.sbyte_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ fixed (UInt16* basePtr = &this.register.uint16_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ fixed (Int16* basePtr = &this.register.int16_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ fixed (UInt32* basePtr = &this.register.uint32_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ fixed (Int32* basePtr = &this.register.int32_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ fixed (UInt64* basePtr = &this.register.uint64_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ fixed (Int64* basePtr = &this.register.int64_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ fixed (Single* basePtr = &this.register.single_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ fixed (Double* basePtr = &this.register.double_0)
+ {
+ return (T)(object)*(basePtr + index);
+ }
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether the given Object is equal to this vector instance.
+ /// </summary>
+ /// <param name="obj">The Object to compare against.</param>
+ /// <returns>True if the Object is equal to this vector; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public override bool Equals(object obj)
+ {
+ if (!(obj is Vector<T>))
+ {
+ return false;
+ }
+ return Equals((Vector<T>)obj);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether the given vector is equal to this vector instance.
+ /// </summary>
+ /// <param name="other">The vector to compare this instance to.</param>
+ /// <returns>True if the other vector is equal to this instance; False otherwise.</returns>
+ [JitIntrinsic]
+ public bool Equals(Vector<T> other)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ if (!ScalarEquals(this[g], other[g]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return
+ this.register.byte_0 == other.register.byte_0
+ && this.register.byte_1 == other.register.byte_1
+ && this.register.byte_2 == other.register.byte_2
+ && this.register.byte_3 == other.register.byte_3
+ && this.register.byte_4 == other.register.byte_4
+ && this.register.byte_5 == other.register.byte_5
+ && this.register.byte_6 == other.register.byte_6
+ && this.register.byte_7 == other.register.byte_7
+ && this.register.byte_8 == other.register.byte_8
+ && this.register.byte_9 == other.register.byte_9
+ && this.register.byte_10 == other.register.byte_10
+ && this.register.byte_11 == other.register.byte_11
+ && this.register.byte_12 == other.register.byte_12
+ && this.register.byte_13 == other.register.byte_13
+ && this.register.byte_14 == other.register.byte_14
+ && this.register.byte_15 == other.register.byte_15;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return
+ this.register.sbyte_0 == other.register.sbyte_0
+ && this.register.sbyte_1 == other.register.sbyte_1
+ && this.register.sbyte_2 == other.register.sbyte_2
+ && this.register.sbyte_3 == other.register.sbyte_3
+ && this.register.sbyte_4 == other.register.sbyte_4
+ && this.register.sbyte_5 == other.register.sbyte_5
+ && this.register.sbyte_6 == other.register.sbyte_6
+ && this.register.sbyte_7 == other.register.sbyte_7
+ && this.register.sbyte_8 == other.register.sbyte_8
+ && this.register.sbyte_9 == other.register.sbyte_9
+ && this.register.sbyte_10 == other.register.sbyte_10
+ && this.register.sbyte_11 == other.register.sbyte_11
+ && this.register.sbyte_12 == other.register.sbyte_12
+ && this.register.sbyte_13 == other.register.sbyte_13
+ && this.register.sbyte_14 == other.register.sbyte_14
+ && this.register.sbyte_15 == other.register.sbyte_15;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return
+ this.register.uint16_0 == other.register.uint16_0
+ && this.register.uint16_1 == other.register.uint16_1
+ && this.register.uint16_2 == other.register.uint16_2
+ && this.register.uint16_3 == other.register.uint16_3
+ && this.register.uint16_4 == other.register.uint16_4
+ && this.register.uint16_5 == other.register.uint16_5
+ && this.register.uint16_6 == other.register.uint16_6
+ && this.register.uint16_7 == other.register.uint16_7;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return
+ this.register.int16_0 == other.register.int16_0
+ && this.register.int16_1 == other.register.int16_1
+ && this.register.int16_2 == other.register.int16_2
+ && this.register.int16_3 == other.register.int16_3
+ && this.register.int16_4 == other.register.int16_4
+ && this.register.int16_5 == other.register.int16_5
+ && this.register.int16_6 == other.register.int16_6
+ && this.register.int16_7 == other.register.int16_7;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return
+ this.register.uint32_0 == other.register.uint32_0
+ && this.register.uint32_1 == other.register.uint32_1
+ && this.register.uint32_2 == other.register.uint32_2
+ && this.register.uint32_3 == other.register.uint32_3;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return
+ this.register.int32_0 == other.register.int32_0
+ && this.register.int32_1 == other.register.int32_1
+ && this.register.int32_2 == other.register.int32_2
+ && this.register.int32_3 == other.register.int32_3;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return
+ this.register.uint64_0 == other.register.uint64_0
+ && this.register.uint64_1 == other.register.uint64_1;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return
+ this.register.int64_0 == other.register.int64_0
+ && this.register.int64_1 == other.register.int64_1;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return
+ this.register.single_0 == other.register.single_0
+ && this.register.single_1 == other.register.single_1
+ && this.register.single_2 == other.register.single_2
+ && this.register.single_3 == other.register.single_3;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return
+ this.register.double_0 == other.register.double_0
+ && this.register.double_1 == other.register.double_1;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns the hash code for this instance.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode()
+ {
+ int hash = 0;
+
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Byte)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((SByte)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((UInt16)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Int16)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((UInt32)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Int32)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((UInt64)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Int64)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Single)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ for (int g = 0; g < Count; g++)
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, ((Double)(object)this[g]).GetHashCode());
+ }
+ return hash;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_3.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_4.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_5.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_6.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_7.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_8.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_9.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_10.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_11.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_12.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_13.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_14.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.byte_15.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_3.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_4.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_5.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_6.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_7.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_8.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_9.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_10.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_11.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_12.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_13.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_14.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.sbyte_15.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_3.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_4.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_5.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_6.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint16_7.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_3.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_4.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_5.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_6.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int16_7.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint32_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint32_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint32_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint32_3.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int32_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int32_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int32_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int32_3.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint64_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.uint64_1.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int64_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.int64_1.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.single_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.single_1.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.single_2.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.single_3.GetHashCode());
+ return hash;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.double_0.GetHashCode());
+ hash = HashCodeHelper.CombineHashCodes(hash, this.register.double_1.GetHashCode());
+ return hash;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns a String representing this vector.
+ /// </summary>
+ /// <returns>The string representation.</returns>
+ public override string ToString()
+ {
+ return ToString("G", CultureInfo.CurrentCulture);
+ }
+
+ /// <summary>
+ /// Returns a String representing this vector, using the specified format string to format individual elements.
+ /// </summary>
+ /// <param name="format">The format of individual elements.</param>
+ /// <returns>The string representation.</returns>
+ public string ToString(string format)
+ {
+ return ToString(format, CultureInfo.CurrentCulture);
+ }
+
+ /// <summary>
+ /// Returns a String representing this vector, using the specified format string to format individual elements
+ /// and the given IFormatProvider.
+ /// </summary>
+ /// <param name="format">The format of individual elements.</param>
+ /// <param name="formatProvider">The format provider to use when formatting elements.</param>
+ /// <returns>The string representation.</returns>
+ public string ToString(string format, IFormatProvider formatProvider)
+ {
+ StringBuilder sb = new StringBuilder();
+ string separator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
+ sb.Append('<');
+ for (int g = 0; g < Count - 1; g++)
+ {
+ sb.Append(((IFormattable)this[g]).ToString(format, formatProvider));
+ sb.Append(separator);
+ sb.Append(' ');
+ }
+ // Append last element w/out separator
+ sb.Append(((IFormattable)this[Count - 1]).ToString(format, formatProvider));
+ sb.Append('>');
+ return sb.ToString();
+ }
+ #endregion Public Instance Methods
+
+ #region Arithmetic Operators
+ /// <summary>
+ /// Adds two vectors together.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The summed vector.</returns>
+ public static unsafe Vector<T> operator +(Vector<T> left, Vector<T> right)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)ScalarAdd(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> sum = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ sum.register.byte_0 = (Byte)(left.register.byte_0 + right.register.byte_0);
+ sum.register.byte_1 = (Byte)(left.register.byte_1 + right.register.byte_1);
+ sum.register.byte_2 = (Byte)(left.register.byte_2 + right.register.byte_2);
+ sum.register.byte_3 = (Byte)(left.register.byte_3 + right.register.byte_3);
+ sum.register.byte_4 = (Byte)(left.register.byte_4 + right.register.byte_4);
+ sum.register.byte_5 = (Byte)(left.register.byte_5 + right.register.byte_5);
+ sum.register.byte_6 = (Byte)(left.register.byte_6 + right.register.byte_6);
+ sum.register.byte_7 = (Byte)(left.register.byte_7 + right.register.byte_7);
+ sum.register.byte_8 = (Byte)(left.register.byte_8 + right.register.byte_8);
+ sum.register.byte_9 = (Byte)(left.register.byte_9 + right.register.byte_9);
+ sum.register.byte_10 = (Byte)(left.register.byte_10 + right.register.byte_10);
+ sum.register.byte_11 = (Byte)(left.register.byte_11 + right.register.byte_11);
+ sum.register.byte_12 = (Byte)(left.register.byte_12 + right.register.byte_12);
+ sum.register.byte_13 = (Byte)(left.register.byte_13 + right.register.byte_13);
+ sum.register.byte_14 = (Byte)(left.register.byte_14 + right.register.byte_14);
+ sum.register.byte_15 = (Byte)(left.register.byte_15 + right.register.byte_15);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ sum.register.sbyte_0 = (SByte)(left.register.sbyte_0 + right.register.sbyte_0);
+ sum.register.sbyte_1 = (SByte)(left.register.sbyte_1 + right.register.sbyte_1);
+ sum.register.sbyte_2 = (SByte)(left.register.sbyte_2 + right.register.sbyte_2);
+ sum.register.sbyte_3 = (SByte)(left.register.sbyte_3 + right.register.sbyte_3);
+ sum.register.sbyte_4 = (SByte)(left.register.sbyte_4 + right.register.sbyte_4);
+ sum.register.sbyte_5 = (SByte)(left.register.sbyte_5 + right.register.sbyte_5);
+ sum.register.sbyte_6 = (SByte)(left.register.sbyte_6 + right.register.sbyte_6);
+ sum.register.sbyte_7 = (SByte)(left.register.sbyte_7 + right.register.sbyte_7);
+ sum.register.sbyte_8 = (SByte)(left.register.sbyte_8 + right.register.sbyte_8);
+ sum.register.sbyte_9 = (SByte)(left.register.sbyte_9 + right.register.sbyte_9);
+ sum.register.sbyte_10 = (SByte)(left.register.sbyte_10 + right.register.sbyte_10);
+ sum.register.sbyte_11 = (SByte)(left.register.sbyte_11 + right.register.sbyte_11);
+ sum.register.sbyte_12 = (SByte)(left.register.sbyte_12 + right.register.sbyte_12);
+ sum.register.sbyte_13 = (SByte)(left.register.sbyte_13 + right.register.sbyte_13);
+ sum.register.sbyte_14 = (SByte)(left.register.sbyte_14 + right.register.sbyte_14);
+ sum.register.sbyte_15 = (SByte)(left.register.sbyte_15 + right.register.sbyte_15);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ sum.register.uint16_0 = (UInt16)(left.register.uint16_0 + right.register.uint16_0);
+ sum.register.uint16_1 = (UInt16)(left.register.uint16_1 + right.register.uint16_1);
+ sum.register.uint16_2 = (UInt16)(left.register.uint16_2 + right.register.uint16_2);
+ sum.register.uint16_3 = (UInt16)(left.register.uint16_3 + right.register.uint16_3);
+ sum.register.uint16_4 = (UInt16)(left.register.uint16_4 + right.register.uint16_4);
+ sum.register.uint16_5 = (UInt16)(left.register.uint16_5 + right.register.uint16_5);
+ sum.register.uint16_6 = (UInt16)(left.register.uint16_6 + right.register.uint16_6);
+ sum.register.uint16_7 = (UInt16)(left.register.uint16_7 + right.register.uint16_7);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ sum.register.int16_0 = (Int16)(left.register.int16_0 + right.register.int16_0);
+ sum.register.int16_1 = (Int16)(left.register.int16_1 + right.register.int16_1);
+ sum.register.int16_2 = (Int16)(left.register.int16_2 + right.register.int16_2);
+ sum.register.int16_3 = (Int16)(left.register.int16_3 + right.register.int16_3);
+ sum.register.int16_4 = (Int16)(left.register.int16_4 + right.register.int16_4);
+ sum.register.int16_5 = (Int16)(left.register.int16_5 + right.register.int16_5);
+ sum.register.int16_6 = (Int16)(left.register.int16_6 + right.register.int16_6);
+ sum.register.int16_7 = (Int16)(left.register.int16_7 + right.register.int16_7);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ sum.register.uint32_0 = (UInt32)(left.register.uint32_0 + right.register.uint32_0);
+ sum.register.uint32_1 = (UInt32)(left.register.uint32_1 + right.register.uint32_1);
+ sum.register.uint32_2 = (UInt32)(left.register.uint32_2 + right.register.uint32_2);
+ sum.register.uint32_3 = (UInt32)(left.register.uint32_3 + right.register.uint32_3);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ sum.register.int32_0 = (Int32)(left.register.int32_0 + right.register.int32_0);
+ sum.register.int32_1 = (Int32)(left.register.int32_1 + right.register.int32_1);
+ sum.register.int32_2 = (Int32)(left.register.int32_2 + right.register.int32_2);
+ sum.register.int32_3 = (Int32)(left.register.int32_3 + right.register.int32_3);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ sum.register.uint64_0 = (UInt64)(left.register.uint64_0 + right.register.uint64_0);
+ sum.register.uint64_1 = (UInt64)(left.register.uint64_1 + right.register.uint64_1);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ sum.register.int64_0 = (Int64)(left.register.int64_0 + right.register.int64_0);
+ sum.register.int64_1 = (Int64)(left.register.int64_1 + right.register.int64_1);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ sum.register.single_0 = (Single)(left.register.single_0 + right.register.single_0);
+ sum.register.single_1 = (Single)(left.register.single_1 + right.register.single_1);
+ sum.register.single_2 = (Single)(left.register.single_2 + right.register.single_2);
+ sum.register.single_3 = (Single)(left.register.single_3 + right.register.single_3);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ sum.register.double_0 = (Double)(left.register.double_0 + right.register.double_0);
+ sum.register.double_1 = (Double)(left.register.double_1 + right.register.double_1);
+ }
+ return sum;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Subtracts the second vector from the first.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The difference vector.</returns>
+ public static unsafe Vector<T> operator -(Vector<T> left, Vector<T> right)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)ScalarSubtract(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> difference = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ difference.register.byte_0 = (Byte)(left.register.byte_0 - right.register.byte_0);
+ difference.register.byte_1 = (Byte)(left.register.byte_1 - right.register.byte_1);
+ difference.register.byte_2 = (Byte)(left.register.byte_2 - right.register.byte_2);
+ difference.register.byte_3 = (Byte)(left.register.byte_3 - right.register.byte_3);
+ difference.register.byte_4 = (Byte)(left.register.byte_4 - right.register.byte_4);
+ difference.register.byte_5 = (Byte)(left.register.byte_5 - right.register.byte_5);
+ difference.register.byte_6 = (Byte)(left.register.byte_6 - right.register.byte_6);
+ difference.register.byte_7 = (Byte)(left.register.byte_7 - right.register.byte_7);
+ difference.register.byte_8 = (Byte)(left.register.byte_8 - right.register.byte_8);
+ difference.register.byte_9 = (Byte)(left.register.byte_9 - right.register.byte_9);
+ difference.register.byte_10 = (Byte)(left.register.byte_10 - right.register.byte_10);
+ difference.register.byte_11 = (Byte)(left.register.byte_11 - right.register.byte_11);
+ difference.register.byte_12 = (Byte)(left.register.byte_12 - right.register.byte_12);
+ difference.register.byte_13 = (Byte)(left.register.byte_13 - right.register.byte_13);
+ difference.register.byte_14 = (Byte)(left.register.byte_14 - right.register.byte_14);
+ difference.register.byte_15 = (Byte)(left.register.byte_15 - right.register.byte_15);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ difference.register.sbyte_0 = (SByte)(left.register.sbyte_0 - right.register.sbyte_0);
+ difference.register.sbyte_1 = (SByte)(left.register.sbyte_1 - right.register.sbyte_1);
+ difference.register.sbyte_2 = (SByte)(left.register.sbyte_2 - right.register.sbyte_2);
+ difference.register.sbyte_3 = (SByte)(left.register.sbyte_3 - right.register.sbyte_3);
+ difference.register.sbyte_4 = (SByte)(left.register.sbyte_4 - right.register.sbyte_4);
+ difference.register.sbyte_5 = (SByte)(left.register.sbyte_5 - right.register.sbyte_5);
+ difference.register.sbyte_6 = (SByte)(left.register.sbyte_6 - right.register.sbyte_6);
+ difference.register.sbyte_7 = (SByte)(left.register.sbyte_7 - right.register.sbyte_7);
+ difference.register.sbyte_8 = (SByte)(left.register.sbyte_8 - right.register.sbyte_8);
+ difference.register.sbyte_9 = (SByte)(left.register.sbyte_9 - right.register.sbyte_9);
+ difference.register.sbyte_10 = (SByte)(left.register.sbyte_10 - right.register.sbyte_10);
+ difference.register.sbyte_11 = (SByte)(left.register.sbyte_11 - right.register.sbyte_11);
+ difference.register.sbyte_12 = (SByte)(left.register.sbyte_12 - right.register.sbyte_12);
+ difference.register.sbyte_13 = (SByte)(left.register.sbyte_13 - right.register.sbyte_13);
+ difference.register.sbyte_14 = (SByte)(left.register.sbyte_14 - right.register.sbyte_14);
+ difference.register.sbyte_15 = (SByte)(left.register.sbyte_15 - right.register.sbyte_15);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ difference.register.uint16_0 = (UInt16)(left.register.uint16_0 - right.register.uint16_0);
+ difference.register.uint16_1 = (UInt16)(left.register.uint16_1 - right.register.uint16_1);
+ difference.register.uint16_2 = (UInt16)(left.register.uint16_2 - right.register.uint16_2);
+ difference.register.uint16_3 = (UInt16)(left.register.uint16_3 - right.register.uint16_3);
+ difference.register.uint16_4 = (UInt16)(left.register.uint16_4 - right.register.uint16_4);
+ difference.register.uint16_5 = (UInt16)(left.register.uint16_5 - right.register.uint16_5);
+ difference.register.uint16_6 = (UInt16)(left.register.uint16_6 - right.register.uint16_6);
+ difference.register.uint16_7 = (UInt16)(left.register.uint16_7 - right.register.uint16_7);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ difference.register.int16_0 = (Int16)(left.register.int16_0 - right.register.int16_0);
+ difference.register.int16_1 = (Int16)(left.register.int16_1 - right.register.int16_1);
+ difference.register.int16_2 = (Int16)(left.register.int16_2 - right.register.int16_2);
+ difference.register.int16_3 = (Int16)(left.register.int16_3 - right.register.int16_3);
+ difference.register.int16_4 = (Int16)(left.register.int16_4 - right.register.int16_4);
+ difference.register.int16_5 = (Int16)(left.register.int16_5 - right.register.int16_5);
+ difference.register.int16_6 = (Int16)(left.register.int16_6 - right.register.int16_6);
+ difference.register.int16_7 = (Int16)(left.register.int16_7 - right.register.int16_7);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ difference.register.uint32_0 = (UInt32)(left.register.uint32_0 - right.register.uint32_0);
+ difference.register.uint32_1 = (UInt32)(left.register.uint32_1 - right.register.uint32_1);
+ difference.register.uint32_2 = (UInt32)(left.register.uint32_2 - right.register.uint32_2);
+ difference.register.uint32_3 = (UInt32)(left.register.uint32_3 - right.register.uint32_3);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ difference.register.int32_0 = (Int32)(left.register.int32_0 - right.register.int32_0);
+ difference.register.int32_1 = (Int32)(left.register.int32_1 - right.register.int32_1);
+ difference.register.int32_2 = (Int32)(left.register.int32_2 - right.register.int32_2);
+ difference.register.int32_3 = (Int32)(left.register.int32_3 - right.register.int32_3);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ difference.register.uint64_0 = (UInt64)(left.register.uint64_0 - right.register.uint64_0);
+ difference.register.uint64_1 = (UInt64)(left.register.uint64_1 - right.register.uint64_1);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ difference.register.int64_0 = (Int64)(left.register.int64_0 - right.register.int64_0);
+ difference.register.int64_1 = (Int64)(left.register.int64_1 - right.register.int64_1);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ difference.register.single_0 = (Single)(left.register.single_0 - right.register.single_0);
+ difference.register.single_1 = (Single)(left.register.single_1 - right.register.single_1);
+ difference.register.single_2 = (Single)(left.register.single_2 - right.register.single_2);
+ difference.register.single_3 = (Single)(left.register.single_3 - right.register.single_3);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ difference.register.double_0 = (Double)(left.register.double_0 - right.register.double_0);
+ difference.register.double_1 = (Double)(left.register.double_1 - right.register.double_1);
+ }
+ return difference;
+ }
+ }
+ }
+
+ // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
+ /// <summary>
+ /// Multiplies two vectors together.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The product vector.</returns>
+ public static unsafe Vector<T> operator *(Vector<T> left, Vector<T> right)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)ScalarMultiply(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> product = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ product.register.byte_0 = (Byte)(left.register.byte_0 * right.register.byte_0);
+ product.register.byte_1 = (Byte)(left.register.byte_1 * right.register.byte_1);
+ product.register.byte_2 = (Byte)(left.register.byte_2 * right.register.byte_2);
+ product.register.byte_3 = (Byte)(left.register.byte_3 * right.register.byte_3);
+ product.register.byte_4 = (Byte)(left.register.byte_4 * right.register.byte_4);
+ product.register.byte_5 = (Byte)(left.register.byte_5 * right.register.byte_5);
+ product.register.byte_6 = (Byte)(left.register.byte_6 * right.register.byte_6);
+ product.register.byte_7 = (Byte)(left.register.byte_7 * right.register.byte_7);
+ product.register.byte_8 = (Byte)(left.register.byte_8 * right.register.byte_8);
+ product.register.byte_9 = (Byte)(left.register.byte_9 * right.register.byte_9);
+ product.register.byte_10 = (Byte)(left.register.byte_10 * right.register.byte_10);
+ product.register.byte_11 = (Byte)(left.register.byte_11 * right.register.byte_11);
+ product.register.byte_12 = (Byte)(left.register.byte_12 * right.register.byte_12);
+ product.register.byte_13 = (Byte)(left.register.byte_13 * right.register.byte_13);
+ product.register.byte_14 = (Byte)(left.register.byte_14 * right.register.byte_14);
+ product.register.byte_15 = (Byte)(left.register.byte_15 * right.register.byte_15);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ product.register.sbyte_0 = (SByte)(left.register.sbyte_0 * right.register.sbyte_0);
+ product.register.sbyte_1 = (SByte)(left.register.sbyte_1 * right.register.sbyte_1);
+ product.register.sbyte_2 = (SByte)(left.register.sbyte_2 * right.register.sbyte_2);
+ product.register.sbyte_3 = (SByte)(left.register.sbyte_3 * right.register.sbyte_3);
+ product.register.sbyte_4 = (SByte)(left.register.sbyte_4 * right.register.sbyte_4);
+ product.register.sbyte_5 = (SByte)(left.register.sbyte_5 * right.register.sbyte_5);
+ product.register.sbyte_6 = (SByte)(left.register.sbyte_6 * right.register.sbyte_6);
+ product.register.sbyte_7 = (SByte)(left.register.sbyte_7 * right.register.sbyte_7);
+ product.register.sbyte_8 = (SByte)(left.register.sbyte_8 * right.register.sbyte_8);
+ product.register.sbyte_9 = (SByte)(left.register.sbyte_9 * right.register.sbyte_9);
+ product.register.sbyte_10 = (SByte)(left.register.sbyte_10 * right.register.sbyte_10);
+ product.register.sbyte_11 = (SByte)(left.register.sbyte_11 * right.register.sbyte_11);
+ product.register.sbyte_12 = (SByte)(left.register.sbyte_12 * right.register.sbyte_12);
+ product.register.sbyte_13 = (SByte)(left.register.sbyte_13 * right.register.sbyte_13);
+ product.register.sbyte_14 = (SByte)(left.register.sbyte_14 * right.register.sbyte_14);
+ product.register.sbyte_15 = (SByte)(left.register.sbyte_15 * right.register.sbyte_15);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ product.register.uint16_0 = (UInt16)(left.register.uint16_0 * right.register.uint16_0);
+ product.register.uint16_1 = (UInt16)(left.register.uint16_1 * right.register.uint16_1);
+ product.register.uint16_2 = (UInt16)(left.register.uint16_2 * right.register.uint16_2);
+ product.register.uint16_3 = (UInt16)(left.register.uint16_3 * right.register.uint16_3);
+ product.register.uint16_4 = (UInt16)(left.register.uint16_4 * right.register.uint16_4);
+ product.register.uint16_5 = (UInt16)(left.register.uint16_5 * right.register.uint16_5);
+ product.register.uint16_6 = (UInt16)(left.register.uint16_6 * right.register.uint16_6);
+ product.register.uint16_7 = (UInt16)(left.register.uint16_7 * right.register.uint16_7);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ product.register.int16_0 = (Int16)(left.register.int16_0 * right.register.int16_0);
+ product.register.int16_1 = (Int16)(left.register.int16_1 * right.register.int16_1);
+ product.register.int16_2 = (Int16)(left.register.int16_2 * right.register.int16_2);
+ product.register.int16_3 = (Int16)(left.register.int16_3 * right.register.int16_3);
+ product.register.int16_4 = (Int16)(left.register.int16_4 * right.register.int16_4);
+ product.register.int16_5 = (Int16)(left.register.int16_5 * right.register.int16_5);
+ product.register.int16_6 = (Int16)(left.register.int16_6 * right.register.int16_6);
+ product.register.int16_7 = (Int16)(left.register.int16_7 * right.register.int16_7);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ product.register.uint32_0 = (UInt32)(left.register.uint32_0 * right.register.uint32_0);
+ product.register.uint32_1 = (UInt32)(left.register.uint32_1 * right.register.uint32_1);
+ product.register.uint32_2 = (UInt32)(left.register.uint32_2 * right.register.uint32_2);
+ product.register.uint32_3 = (UInt32)(left.register.uint32_3 * right.register.uint32_3);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ product.register.int32_0 = (Int32)(left.register.int32_0 * right.register.int32_0);
+ product.register.int32_1 = (Int32)(left.register.int32_1 * right.register.int32_1);
+ product.register.int32_2 = (Int32)(left.register.int32_2 * right.register.int32_2);
+ product.register.int32_3 = (Int32)(left.register.int32_3 * right.register.int32_3);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ product.register.uint64_0 = (UInt64)(left.register.uint64_0 * right.register.uint64_0);
+ product.register.uint64_1 = (UInt64)(left.register.uint64_1 * right.register.uint64_1);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ product.register.int64_0 = (Int64)(left.register.int64_0 * right.register.int64_0);
+ product.register.int64_1 = (Int64)(left.register.int64_1 * right.register.int64_1);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ product.register.single_0 = (Single)(left.register.single_0 * right.register.single_0);
+ product.register.single_1 = (Single)(left.register.single_1 * right.register.single_1);
+ product.register.single_2 = (Single)(left.register.single_2 * right.register.single_2);
+ product.register.single_3 = (Single)(left.register.single_3 * right.register.single_3);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ product.register.double_0 = (Double)(left.register.double_0 * right.register.double_0);
+ product.register.double_1 = (Double)(left.register.double_1 * right.register.double_1);
+ }
+ return product;
+ }
+ }
+ }
+
+ // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
+ /// <summary>
+ /// Multiplies a vector by the given scalar.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <param name="factor">The scalar value.</param>
+ /// <returns>The scaled vector.</returns>
+ public static Vector<T> operator *(Vector<T> value, T factor)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ return new Vector<T>(factor) * value;
+ }
+ else
+ {
+ Vector<T> product = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ product.register.byte_0 = (Byte)(value.register.byte_0 * (Byte)(object)factor);
+ product.register.byte_1 = (Byte)(value.register.byte_1 * (Byte)(object)factor);
+ product.register.byte_2 = (Byte)(value.register.byte_2 * (Byte)(object)factor);
+ product.register.byte_3 = (Byte)(value.register.byte_3 * (Byte)(object)factor);
+ product.register.byte_4 = (Byte)(value.register.byte_4 * (Byte)(object)factor);
+ product.register.byte_5 = (Byte)(value.register.byte_5 * (Byte)(object)factor);
+ product.register.byte_6 = (Byte)(value.register.byte_6 * (Byte)(object)factor);
+ product.register.byte_7 = (Byte)(value.register.byte_7 * (Byte)(object)factor);
+ product.register.byte_8 = (Byte)(value.register.byte_8 * (Byte)(object)factor);
+ product.register.byte_9 = (Byte)(value.register.byte_9 * (Byte)(object)factor);
+ product.register.byte_10 = (Byte)(value.register.byte_10 * (Byte)(object)factor);
+ product.register.byte_11 = (Byte)(value.register.byte_11 * (Byte)(object)factor);
+ product.register.byte_12 = (Byte)(value.register.byte_12 * (Byte)(object)factor);
+ product.register.byte_13 = (Byte)(value.register.byte_13 * (Byte)(object)factor);
+ product.register.byte_14 = (Byte)(value.register.byte_14 * (Byte)(object)factor);
+ product.register.byte_15 = (Byte)(value.register.byte_15 * (Byte)(object)factor);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ product.register.sbyte_0 = (SByte)(value.register.sbyte_0 * (SByte)(object)factor);
+ product.register.sbyte_1 = (SByte)(value.register.sbyte_1 * (SByte)(object)factor);
+ product.register.sbyte_2 = (SByte)(value.register.sbyte_2 * (SByte)(object)factor);
+ product.register.sbyte_3 = (SByte)(value.register.sbyte_3 * (SByte)(object)factor);
+ product.register.sbyte_4 = (SByte)(value.register.sbyte_4 * (SByte)(object)factor);
+ product.register.sbyte_5 = (SByte)(value.register.sbyte_5 * (SByte)(object)factor);
+ product.register.sbyte_6 = (SByte)(value.register.sbyte_6 * (SByte)(object)factor);
+ product.register.sbyte_7 = (SByte)(value.register.sbyte_7 * (SByte)(object)factor);
+ product.register.sbyte_8 = (SByte)(value.register.sbyte_8 * (SByte)(object)factor);
+ product.register.sbyte_9 = (SByte)(value.register.sbyte_9 * (SByte)(object)factor);
+ product.register.sbyte_10 = (SByte)(value.register.sbyte_10 * (SByte)(object)factor);
+ product.register.sbyte_11 = (SByte)(value.register.sbyte_11 * (SByte)(object)factor);
+ product.register.sbyte_12 = (SByte)(value.register.sbyte_12 * (SByte)(object)factor);
+ product.register.sbyte_13 = (SByte)(value.register.sbyte_13 * (SByte)(object)factor);
+ product.register.sbyte_14 = (SByte)(value.register.sbyte_14 * (SByte)(object)factor);
+ product.register.sbyte_15 = (SByte)(value.register.sbyte_15 * (SByte)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ product.register.uint16_0 = (UInt16)(value.register.uint16_0 * (UInt16)(object)factor);
+ product.register.uint16_1 = (UInt16)(value.register.uint16_1 * (UInt16)(object)factor);
+ product.register.uint16_2 = (UInt16)(value.register.uint16_2 * (UInt16)(object)factor);
+ product.register.uint16_3 = (UInt16)(value.register.uint16_3 * (UInt16)(object)factor);
+ product.register.uint16_4 = (UInt16)(value.register.uint16_4 * (UInt16)(object)factor);
+ product.register.uint16_5 = (UInt16)(value.register.uint16_5 * (UInt16)(object)factor);
+ product.register.uint16_6 = (UInt16)(value.register.uint16_6 * (UInt16)(object)factor);
+ product.register.uint16_7 = (UInt16)(value.register.uint16_7 * (UInt16)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ product.register.int16_0 = (Int16)(value.register.int16_0 * (Int16)(object)factor);
+ product.register.int16_1 = (Int16)(value.register.int16_1 * (Int16)(object)factor);
+ product.register.int16_2 = (Int16)(value.register.int16_2 * (Int16)(object)factor);
+ product.register.int16_3 = (Int16)(value.register.int16_3 * (Int16)(object)factor);
+ product.register.int16_4 = (Int16)(value.register.int16_4 * (Int16)(object)factor);
+ product.register.int16_5 = (Int16)(value.register.int16_5 * (Int16)(object)factor);
+ product.register.int16_6 = (Int16)(value.register.int16_6 * (Int16)(object)factor);
+ product.register.int16_7 = (Int16)(value.register.int16_7 * (Int16)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ product.register.uint32_0 = (UInt32)(value.register.uint32_0 * (UInt32)(object)factor);
+ product.register.uint32_1 = (UInt32)(value.register.uint32_1 * (UInt32)(object)factor);
+ product.register.uint32_2 = (UInt32)(value.register.uint32_2 * (UInt32)(object)factor);
+ product.register.uint32_3 = (UInt32)(value.register.uint32_3 * (UInt32)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ product.register.int32_0 = (Int32)(value.register.int32_0 * (Int32)(object)factor);
+ product.register.int32_1 = (Int32)(value.register.int32_1 * (Int32)(object)factor);
+ product.register.int32_2 = (Int32)(value.register.int32_2 * (Int32)(object)factor);
+ product.register.int32_3 = (Int32)(value.register.int32_3 * (Int32)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ product.register.uint64_0 = (UInt64)(value.register.uint64_0 * (UInt64)(object)factor);
+ product.register.uint64_1 = (UInt64)(value.register.uint64_1 * (UInt64)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ product.register.int64_0 = (Int64)(value.register.int64_0 * (Int64)(object)factor);
+ product.register.int64_1 = (Int64)(value.register.int64_1 * (Int64)(object)factor);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ product.register.single_0 = (Single)(value.register.single_0 * (Single)(object)factor);
+ product.register.single_1 = (Single)(value.register.single_1 * (Single)(object)factor);
+ product.register.single_2 = (Single)(value.register.single_2 * (Single)(object)factor);
+ product.register.single_3 = (Single)(value.register.single_3 * (Single)(object)factor);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ product.register.double_0 = (Double)(value.register.double_0 * (Double)(object)factor);
+ product.register.double_1 = (Double)(value.register.double_1 * (Double)(object)factor);
+ }
+ return product;
+ }
+ }
+ }
+
+ // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
+ /// <summary>
+ /// Multiplies a vector by the given scalar.
+ /// </summary>
+ /// <param name="factor">The scalar value.</param>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The scaled vector.</returns>
+ public static Vector<T> operator *(T factor, Vector<T> value)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ return new Vector<T>(factor) * value;
+ }
+ else
+ {
+ Vector<T> product = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ product.register.byte_0 = (Byte)(value.register.byte_0 * (Byte)(object)factor);
+ product.register.byte_1 = (Byte)(value.register.byte_1 * (Byte)(object)factor);
+ product.register.byte_2 = (Byte)(value.register.byte_2 * (Byte)(object)factor);
+ product.register.byte_3 = (Byte)(value.register.byte_3 * (Byte)(object)factor);
+ product.register.byte_4 = (Byte)(value.register.byte_4 * (Byte)(object)factor);
+ product.register.byte_5 = (Byte)(value.register.byte_5 * (Byte)(object)factor);
+ product.register.byte_6 = (Byte)(value.register.byte_6 * (Byte)(object)factor);
+ product.register.byte_7 = (Byte)(value.register.byte_7 * (Byte)(object)factor);
+ product.register.byte_8 = (Byte)(value.register.byte_8 * (Byte)(object)factor);
+ product.register.byte_9 = (Byte)(value.register.byte_9 * (Byte)(object)factor);
+ product.register.byte_10 = (Byte)(value.register.byte_10 * (Byte)(object)factor);
+ product.register.byte_11 = (Byte)(value.register.byte_11 * (Byte)(object)factor);
+ product.register.byte_12 = (Byte)(value.register.byte_12 * (Byte)(object)factor);
+ product.register.byte_13 = (Byte)(value.register.byte_13 * (Byte)(object)factor);
+ product.register.byte_14 = (Byte)(value.register.byte_14 * (Byte)(object)factor);
+ product.register.byte_15 = (Byte)(value.register.byte_15 * (Byte)(object)factor);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ product.register.sbyte_0 = (SByte)(value.register.sbyte_0 * (SByte)(object)factor);
+ product.register.sbyte_1 = (SByte)(value.register.sbyte_1 * (SByte)(object)factor);
+ product.register.sbyte_2 = (SByte)(value.register.sbyte_2 * (SByte)(object)factor);
+ product.register.sbyte_3 = (SByte)(value.register.sbyte_3 * (SByte)(object)factor);
+ product.register.sbyte_4 = (SByte)(value.register.sbyte_4 * (SByte)(object)factor);
+ product.register.sbyte_5 = (SByte)(value.register.sbyte_5 * (SByte)(object)factor);
+ product.register.sbyte_6 = (SByte)(value.register.sbyte_6 * (SByte)(object)factor);
+ product.register.sbyte_7 = (SByte)(value.register.sbyte_7 * (SByte)(object)factor);
+ product.register.sbyte_8 = (SByte)(value.register.sbyte_8 * (SByte)(object)factor);
+ product.register.sbyte_9 = (SByte)(value.register.sbyte_9 * (SByte)(object)factor);
+ product.register.sbyte_10 = (SByte)(value.register.sbyte_10 * (SByte)(object)factor);
+ product.register.sbyte_11 = (SByte)(value.register.sbyte_11 * (SByte)(object)factor);
+ product.register.sbyte_12 = (SByte)(value.register.sbyte_12 * (SByte)(object)factor);
+ product.register.sbyte_13 = (SByte)(value.register.sbyte_13 * (SByte)(object)factor);
+ product.register.sbyte_14 = (SByte)(value.register.sbyte_14 * (SByte)(object)factor);
+ product.register.sbyte_15 = (SByte)(value.register.sbyte_15 * (SByte)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ product.register.uint16_0 = (UInt16)(value.register.uint16_0 * (UInt16)(object)factor);
+ product.register.uint16_1 = (UInt16)(value.register.uint16_1 * (UInt16)(object)factor);
+ product.register.uint16_2 = (UInt16)(value.register.uint16_2 * (UInt16)(object)factor);
+ product.register.uint16_3 = (UInt16)(value.register.uint16_3 * (UInt16)(object)factor);
+ product.register.uint16_4 = (UInt16)(value.register.uint16_4 * (UInt16)(object)factor);
+ product.register.uint16_5 = (UInt16)(value.register.uint16_5 * (UInt16)(object)factor);
+ product.register.uint16_6 = (UInt16)(value.register.uint16_6 * (UInt16)(object)factor);
+ product.register.uint16_7 = (UInt16)(value.register.uint16_7 * (UInt16)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ product.register.int16_0 = (Int16)(value.register.int16_0 * (Int16)(object)factor);
+ product.register.int16_1 = (Int16)(value.register.int16_1 * (Int16)(object)factor);
+ product.register.int16_2 = (Int16)(value.register.int16_2 * (Int16)(object)factor);
+ product.register.int16_3 = (Int16)(value.register.int16_3 * (Int16)(object)factor);
+ product.register.int16_4 = (Int16)(value.register.int16_4 * (Int16)(object)factor);
+ product.register.int16_5 = (Int16)(value.register.int16_5 * (Int16)(object)factor);
+ product.register.int16_6 = (Int16)(value.register.int16_6 * (Int16)(object)factor);
+ product.register.int16_7 = (Int16)(value.register.int16_7 * (Int16)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ product.register.uint32_0 = (UInt32)(value.register.uint32_0 * (UInt32)(object)factor);
+ product.register.uint32_1 = (UInt32)(value.register.uint32_1 * (UInt32)(object)factor);
+ product.register.uint32_2 = (UInt32)(value.register.uint32_2 * (UInt32)(object)factor);
+ product.register.uint32_3 = (UInt32)(value.register.uint32_3 * (UInt32)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ product.register.int32_0 = (Int32)(value.register.int32_0 * (Int32)(object)factor);
+ product.register.int32_1 = (Int32)(value.register.int32_1 * (Int32)(object)factor);
+ product.register.int32_2 = (Int32)(value.register.int32_2 * (Int32)(object)factor);
+ product.register.int32_3 = (Int32)(value.register.int32_3 * (Int32)(object)factor);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ product.register.uint64_0 = (UInt64)(value.register.uint64_0 * (UInt64)(object)factor);
+ product.register.uint64_1 = (UInt64)(value.register.uint64_1 * (UInt64)(object)factor);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ product.register.int64_0 = (Int64)(value.register.int64_0 * (Int64)(object)factor);
+ product.register.int64_1 = (Int64)(value.register.int64_1 * (Int64)(object)factor);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ product.register.single_0 = (Single)(value.register.single_0 * (Single)(object)factor);
+ product.register.single_1 = (Single)(value.register.single_1 * (Single)(object)factor);
+ product.register.single_2 = (Single)(value.register.single_2 * (Single)(object)factor);
+ product.register.single_3 = (Single)(value.register.single_3 * (Single)(object)factor);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ product.register.double_0 = (Double)(value.register.double_0 * (Double)(object)factor);
+ product.register.double_1 = (Double)(value.register.double_1 * (Double)(object)factor);
+ }
+ return product;
+ }
+ }
+ }
+
+ // This method is intrinsic only for certain types. It cannot access fields directly unless we are sure the context is unaccelerated.
+ /// <summary>
+ /// Divides the first vector by the second.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The vector resulting from the division.</returns>
+ public static unsafe Vector<T> operator /(Vector<T> left, Vector<T> right)
+ {
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)ScalarDivide(left[g], right[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> quotient = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ quotient.register.byte_0 = (Byte)(left.register.byte_0 / right.register.byte_0);
+ quotient.register.byte_1 = (Byte)(left.register.byte_1 / right.register.byte_1);
+ quotient.register.byte_2 = (Byte)(left.register.byte_2 / right.register.byte_2);
+ quotient.register.byte_3 = (Byte)(left.register.byte_3 / right.register.byte_3);
+ quotient.register.byte_4 = (Byte)(left.register.byte_4 / right.register.byte_4);
+ quotient.register.byte_5 = (Byte)(left.register.byte_5 / right.register.byte_5);
+ quotient.register.byte_6 = (Byte)(left.register.byte_6 / right.register.byte_6);
+ quotient.register.byte_7 = (Byte)(left.register.byte_7 / right.register.byte_7);
+ quotient.register.byte_8 = (Byte)(left.register.byte_8 / right.register.byte_8);
+ quotient.register.byte_9 = (Byte)(left.register.byte_9 / right.register.byte_9);
+ quotient.register.byte_10 = (Byte)(left.register.byte_10 / right.register.byte_10);
+ quotient.register.byte_11 = (Byte)(left.register.byte_11 / right.register.byte_11);
+ quotient.register.byte_12 = (Byte)(left.register.byte_12 / right.register.byte_12);
+ quotient.register.byte_13 = (Byte)(left.register.byte_13 / right.register.byte_13);
+ quotient.register.byte_14 = (Byte)(left.register.byte_14 / right.register.byte_14);
+ quotient.register.byte_15 = (Byte)(left.register.byte_15 / right.register.byte_15);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ quotient.register.sbyte_0 = (SByte)(left.register.sbyte_0 / right.register.sbyte_0);
+ quotient.register.sbyte_1 = (SByte)(left.register.sbyte_1 / right.register.sbyte_1);
+ quotient.register.sbyte_2 = (SByte)(left.register.sbyte_2 / right.register.sbyte_2);
+ quotient.register.sbyte_3 = (SByte)(left.register.sbyte_3 / right.register.sbyte_3);
+ quotient.register.sbyte_4 = (SByte)(left.register.sbyte_4 / right.register.sbyte_4);
+ quotient.register.sbyte_5 = (SByte)(left.register.sbyte_5 / right.register.sbyte_5);
+ quotient.register.sbyte_6 = (SByte)(left.register.sbyte_6 / right.register.sbyte_6);
+ quotient.register.sbyte_7 = (SByte)(left.register.sbyte_7 / right.register.sbyte_7);
+ quotient.register.sbyte_8 = (SByte)(left.register.sbyte_8 / right.register.sbyte_8);
+ quotient.register.sbyte_9 = (SByte)(left.register.sbyte_9 / right.register.sbyte_9);
+ quotient.register.sbyte_10 = (SByte)(left.register.sbyte_10 / right.register.sbyte_10);
+ quotient.register.sbyte_11 = (SByte)(left.register.sbyte_11 / right.register.sbyte_11);
+ quotient.register.sbyte_12 = (SByte)(left.register.sbyte_12 / right.register.sbyte_12);
+ quotient.register.sbyte_13 = (SByte)(left.register.sbyte_13 / right.register.sbyte_13);
+ quotient.register.sbyte_14 = (SByte)(left.register.sbyte_14 / right.register.sbyte_14);
+ quotient.register.sbyte_15 = (SByte)(left.register.sbyte_15 / right.register.sbyte_15);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ quotient.register.uint16_0 = (UInt16)(left.register.uint16_0 / right.register.uint16_0);
+ quotient.register.uint16_1 = (UInt16)(left.register.uint16_1 / right.register.uint16_1);
+ quotient.register.uint16_2 = (UInt16)(left.register.uint16_2 / right.register.uint16_2);
+ quotient.register.uint16_3 = (UInt16)(left.register.uint16_3 / right.register.uint16_3);
+ quotient.register.uint16_4 = (UInt16)(left.register.uint16_4 / right.register.uint16_4);
+ quotient.register.uint16_5 = (UInt16)(left.register.uint16_5 / right.register.uint16_5);
+ quotient.register.uint16_6 = (UInt16)(left.register.uint16_6 / right.register.uint16_6);
+ quotient.register.uint16_7 = (UInt16)(left.register.uint16_7 / right.register.uint16_7);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ quotient.register.int16_0 = (Int16)(left.register.int16_0 / right.register.int16_0);
+ quotient.register.int16_1 = (Int16)(left.register.int16_1 / right.register.int16_1);
+ quotient.register.int16_2 = (Int16)(left.register.int16_2 / right.register.int16_2);
+ quotient.register.int16_3 = (Int16)(left.register.int16_3 / right.register.int16_3);
+ quotient.register.int16_4 = (Int16)(left.register.int16_4 / right.register.int16_4);
+ quotient.register.int16_5 = (Int16)(left.register.int16_5 / right.register.int16_5);
+ quotient.register.int16_6 = (Int16)(left.register.int16_6 / right.register.int16_6);
+ quotient.register.int16_7 = (Int16)(left.register.int16_7 / right.register.int16_7);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ quotient.register.uint32_0 = (UInt32)(left.register.uint32_0 / right.register.uint32_0);
+ quotient.register.uint32_1 = (UInt32)(left.register.uint32_1 / right.register.uint32_1);
+ quotient.register.uint32_2 = (UInt32)(left.register.uint32_2 / right.register.uint32_2);
+ quotient.register.uint32_3 = (UInt32)(left.register.uint32_3 / right.register.uint32_3);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ quotient.register.int32_0 = (Int32)(left.register.int32_0 / right.register.int32_0);
+ quotient.register.int32_1 = (Int32)(left.register.int32_1 / right.register.int32_1);
+ quotient.register.int32_2 = (Int32)(left.register.int32_2 / right.register.int32_2);
+ quotient.register.int32_3 = (Int32)(left.register.int32_3 / right.register.int32_3);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ quotient.register.uint64_0 = (UInt64)(left.register.uint64_0 / right.register.uint64_0);
+ quotient.register.uint64_1 = (UInt64)(left.register.uint64_1 / right.register.uint64_1);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ quotient.register.int64_0 = (Int64)(left.register.int64_0 / right.register.int64_0);
+ quotient.register.int64_1 = (Int64)(left.register.int64_1 / right.register.int64_1);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ quotient.register.single_0 = (Single)(left.register.single_0 / right.register.single_0);
+ quotient.register.single_1 = (Single)(left.register.single_1 / right.register.single_1);
+ quotient.register.single_2 = (Single)(left.register.single_2 / right.register.single_2);
+ quotient.register.single_3 = (Single)(left.register.single_3 / right.register.single_3);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ quotient.register.double_0 = (Double)(left.register.double_0 / right.register.double_0);
+ quotient.register.double_1 = (Double)(left.register.double_1 / right.register.double_1);
+ }
+ return quotient;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Negates a given vector.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The negated vector.</returns>
+ public static Vector<T> operator -(Vector<T> value)
+ {
+ return Zero - value;
+ }
+ #endregion Arithmetic Operators
+
+ #region Bitwise Operators
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [JitIntrinsic]
+ public static unsafe Vector<T> operator &(Vector<T> left, Vector<T> right)
+ {
+ Vector<T> result = new Vector<T>();
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ Int64* resultBase = &result.register.int64_0;
+ Int64* leftBase = &left.register.int64_0;
+ Int64* rightBase = &right.register.int64_0;
+ for (int g = 0; g < Vector<Int64>.Count; g++)
+ {
+ resultBase[g] = leftBase[g] & rightBase[g];
+ }
+ }
+ else
+ {
+ result.register.int64_0 = left.register.int64_0 & right.register.int64_0;
+ result.register.int64_1 = left.register.int64_1 & right.register.int64_1;
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [JitIntrinsic]
+ public static unsafe Vector<T> operator |(Vector<T> left, Vector<T> right)
+ {
+ Vector<T> result = new Vector<T>();
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ Int64* resultBase = &result.register.int64_0;
+ Int64* leftBase = &left.register.int64_0;
+ Int64* rightBase = &right.register.int64_0;
+ for (int g = 0; g < Vector<Int64>.Count; g++)
+ {
+ resultBase[g] = leftBase[g] | rightBase[g];
+ }
+ }
+ else
+ {
+ result.register.int64_0 = left.register.int64_0 | right.register.int64_0;
+ result.register.int64_1 = left.register.int64_1 | right.register.int64_1;
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [JitIntrinsic]
+ public static unsafe Vector<T> operator ^(Vector<T> left, Vector<T> right)
+ {
+ Vector<T> result = new Vector<T>();
+ unchecked
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ Int64* resultBase = &result.register.int64_0;
+ Int64* leftBase = &left.register.int64_0;
+ Int64* rightBase = &right.register.int64_0;
+ for (int g = 0; g < Vector<Int64>.Count; g++)
+ {
+ resultBase[g] = leftBase[g] ^ rightBase[g];
+ }
+ }
+ else
+ {
+ result.register.int64_0 = left.register.int64_0 ^ right.register.int64_0;
+ result.register.int64_1 = left.register.int64_1 ^ right.register.int64_1;
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The one's complement vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> operator ~(Vector<T> value)
+ {
+ return allOnes ^ value;
+ }
+ #endregion Bitwise Operators
+
+ #region Logical Operators
+ /// <summary>
+ /// Returns a boolean indicating whether each pair of elements in the given vectors are equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The first vector to compare.</param>
+ /// <returns>True if all elements are equal; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool operator ==(Vector<T> left, Vector<T> right)
+ {
+ return left.Equals(right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any single pair of elements in the given vectors are equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any element pairs are equal; False if no element pairs are equal.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool operator !=(Vector<T> left, Vector<T> right)
+ {
+ return !(left == right);
+ }
+ #endregion Logical Operators
+
+ #region Conversions
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Byte>(Vector<T> value)
+ {
+ return new Vector<Byte>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [JitIntrinsic]
+ public static explicit operator Vector<SByte>(Vector<T> value)
+ {
+ return new Vector<SByte>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [JitIntrinsic]
+ public static explicit operator Vector<UInt16>(Vector<T> value)
+ {
+ return new Vector<UInt16>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Int16>(Vector<T> value)
+ {
+ return new Vector<Int16>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [JitIntrinsic]
+ public static explicit operator Vector<UInt32>(Vector<T> value)
+ {
+ return new Vector<UInt32>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Int32>(Vector<T> value)
+ {
+ return new Vector<Int32>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [JitIntrinsic]
+ public static explicit operator Vector<UInt64>(Vector<T> value)
+ {
+ return new Vector<UInt64>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Int64>(Vector<T> value)
+ {
+ return new Vector<Int64>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Single>(Vector<T> value)
+ {
+ return new Vector<Single>(ref value.register);
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of another type.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [JitIntrinsic]
+ public static explicit operator Vector<Double>(Vector<T> value)
+ {
+ return new Vector<Double>(ref value.register);
+ }
+
+ #endregion Conversions
+
+ #region Internal Comparison Methods
+ [JitIntrinsic]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe Vector<T> Equals(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarEquals(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Register register = new Register();
+ if (typeof(T) == typeof(Byte))
+ {
+ register.byte_0 = left.register.byte_0 == right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_1 = left.register.byte_1 == right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_2 = left.register.byte_2 == right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_3 = left.register.byte_3 == right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_4 = left.register.byte_4 == right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_5 = left.register.byte_5 == right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_6 = left.register.byte_6 == right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_7 = left.register.byte_7 == right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_8 = left.register.byte_8 == right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_9 = left.register.byte_9 == right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_10 = left.register.byte_10 == right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_11 = left.register.byte_11 == right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_12 = left.register.byte_12 == right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_13 = left.register.byte_13 == right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_14 = left.register.byte_14 == right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_15 = left.register.byte_15 == right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ register.sbyte_0 = left.register.sbyte_0 == right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_1 = left.register.sbyte_1 == right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_2 = left.register.sbyte_2 == right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_3 = left.register.sbyte_3 == right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_4 = left.register.sbyte_4 == right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_5 = left.register.sbyte_5 == right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_6 = left.register.sbyte_6 == right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_7 = left.register.sbyte_7 == right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_8 = left.register.sbyte_8 == right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_9 = left.register.sbyte_9 == right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_10 = left.register.sbyte_10 == right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_11 = left.register.sbyte_11 == right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_12 = left.register.sbyte_12 == right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_13 = left.register.sbyte_13 == right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_14 = left.register.sbyte_14 == right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_15 = left.register.sbyte_15 == right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ register.uint16_0 = left.register.uint16_0 == right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_1 = left.register.uint16_1 == right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_2 = left.register.uint16_2 == right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_3 = left.register.uint16_3 == right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_4 = left.register.uint16_4 == right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_5 = left.register.uint16_5 == right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_6 = left.register.uint16_6 == right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_7 = left.register.uint16_7 == right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ register.int16_0 = left.register.int16_0 == right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_1 = left.register.int16_1 == right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_2 = left.register.int16_2 == right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_3 = left.register.int16_3 == right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_4 = left.register.int16_4 == right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_5 = left.register.int16_5 == right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_6 = left.register.int16_6 == right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_7 = left.register.int16_7 == right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ register.uint32_0 = left.register.uint32_0 == right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_1 = left.register.uint32_1 == right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_2 = left.register.uint32_2 == right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_3 = left.register.uint32_3 == right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ register.int32_0 = left.register.int32_0 == right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_1 = left.register.int32_1 == right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_2 = left.register.int32_2 == right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_3 = left.register.int32_3 == right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ register.uint64_0 = left.register.uint64_0 == right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ register.uint64_1 = left.register.uint64_1 == right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ register.int64_0 = left.register.int64_0 == right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ register.int64_1 = left.register.int64_1 == right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ register.single_0 = left.register.single_0 == right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_1 = left.register.single_1 == right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_2 = left.register.single_2 == right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_3 = left.register.single_3 == right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ register.double_0 = left.register.double_0 == right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ register.double_1 = left.register.double_1 == right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ return new Vector<T>(ref register);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe Vector<T> LessThan(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Register register = new Register();
+ if (typeof(T) == typeof(Byte))
+ {
+ register.byte_0 = left.register.byte_0 < right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_1 = left.register.byte_1 < right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_2 = left.register.byte_2 < right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_3 = left.register.byte_3 < right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_4 = left.register.byte_4 < right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_5 = left.register.byte_5 < right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_6 = left.register.byte_6 < right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_7 = left.register.byte_7 < right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_8 = left.register.byte_8 < right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_9 = left.register.byte_9 < right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_10 = left.register.byte_10 < right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_11 = left.register.byte_11 < right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_12 = left.register.byte_12 < right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_13 = left.register.byte_13 < right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_14 = left.register.byte_14 < right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_15 = left.register.byte_15 < right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ register.sbyte_0 = left.register.sbyte_0 < right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_1 = left.register.sbyte_1 < right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_2 = left.register.sbyte_2 < right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_3 = left.register.sbyte_3 < right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_4 = left.register.sbyte_4 < right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_5 = left.register.sbyte_5 < right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_6 = left.register.sbyte_6 < right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_7 = left.register.sbyte_7 < right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_8 = left.register.sbyte_8 < right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_9 = left.register.sbyte_9 < right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_10 = left.register.sbyte_10 < right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_11 = left.register.sbyte_11 < right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_12 = left.register.sbyte_12 < right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_13 = left.register.sbyte_13 < right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_14 = left.register.sbyte_14 < right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_15 = left.register.sbyte_15 < right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ register.uint16_0 = left.register.uint16_0 < right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_1 = left.register.uint16_1 < right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_2 = left.register.uint16_2 < right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_3 = left.register.uint16_3 < right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_4 = left.register.uint16_4 < right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_5 = left.register.uint16_5 < right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_6 = left.register.uint16_6 < right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_7 = left.register.uint16_7 < right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ register.int16_0 = left.register.int16_0 < right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_1 = left.register.int16_1 < right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_2 = left.register.int16_2 < right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_3 = left.register.int16_3 < right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_4 = left.register.int16_4 < right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_5 = left.register.int16_5 < right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_6 = left.register.int16_6 < right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_7 = left.register.int16_7 < right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ register.uint32_0 = left.register.uint32_0 < right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_1 = left.register.uint32_1 < right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_2 = left.register.uint32_2 < right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_3 = left.register.uint32_3 < right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ register.int32_0 = left.register.int32_0 < right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_1 = left.register.int32_1 < right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_2 = left.register.int32_2 < right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_3 = left.register.int32_3 < right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ register.uint64_0 = left.register.uint64_0 < right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ register.uint64_1 = left.register.uint64_1 < right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ register.int64_0 = left.register.int64_0 < right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ register.int64_1 = left.register.int64_1 < right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ register.single_0 = left.register.single_0 < right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_1 = left.register.single_1 < right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_2 = left.register.single_2 < right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_3 = left.register.single_3 < right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ register.double_0 = left.register.double_0 < right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ register.double_1 = left.register.double_1 < right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ return new Vector<T>(ref register);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe Vector<T> GreaterThan(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Register register = new Register();
+ if (typeof(T) == typeof(Byte))
+ {
+ register.byte_0 = left.register.byte_0 > right.register.byte_0 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_1 = left.register.byte_1 > right.register.byte_1 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_2 = left.register.byte_2 > right.register.byte_2 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_3 = left.register.byte_3 > right.register.byte_3 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_4 = left.register.byte_4 > right.register.byte_4 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_5 = left.register.byte_5 > right.register.byte_5 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_6 = left.register.byte_6 > right.register.byte_6 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_7 = left.register.byte_7 > right.register.byte_7 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_8 = left.register.byte_8 > right.register.byte_8 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_9 = left.register.byte_9 > right.register.byte_9 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_10 = left.register.byte_10 > right.register.byte_10 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_11 = left.register.byte_11 > right.register.byte_11 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_12 = left.register.byte_12 > right.register.byte_12 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_13 = left.register.byte_13 > right.register.byte_13 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_14 = left.register.byte_14 > right.register.byte_14 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ register.byte_15 = left.register.byte_15 > right.register.byte_15 ? ConstantHelper.GetByteWithAllBitsSet() : (Byte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ register.sbyte_0 = left.register.sbyte_0 > right.register.sbyte_0 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_1 = left.register.sbyte_1 > right.register.sbyte_1 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_2 = left.register.sbyte_2 > right.register.sbyte_2 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_3 = left.register.sbyte_3 > right.register.sbyte_3 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_4 = left.register.sbyte_4 > right.register.sbyte_4 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_5 = left.register.sbyte_5 > right.register.sbyte_5 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_6 = left.register.sbyte_6 > right.register.sbyte_6 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_7 = left.register.sbyte_7 > right.register.sbyte_7 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_8 = left.register.sbyte_8 > right.register.sbyte_8 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_9 = left.register.sbyte_9 > right.register.sbyte_9 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_10 = left.register.sbyte_10 > right.register.sbyte_10 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_11 = left.register.sbyte_11 > right.register.sbyte_11 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_12 = left.register.sbyte_12 > right.register.sbyte_12 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_13 = left.register.sbyte_13 > right.register.sbyte_13 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_14 = left.register.sbyte_14 > right.register.sbyte_14 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ register.sbyte_15 = left.register.sbyte_15 > right.register.sbyte_15 ? ConstantHelper.GetSByteWithAllBitsSet() : (SByte)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ register.uint16_0 = left.register.uint16_0 > right.register.uint16_0 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_1 = left.register.uint16_1 > right.register.uint16_1 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_2 = left.register.uint16_2 > right.register.uint16_2 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_3 = left.register.uint16_3 > right.register.uint16_3 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_4 = left.register.uint16_4 > right.register.uint16_4 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_5 = left.register.uint16_5 > right.register.uint16_5 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_6 = left.register.uint16_6 > right.register.uint16_6 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ register.uint16_7 = left.register.uint16_7 > right.register.uint16_7 ? ConstantHelper.GetUInt16WithAllBitsSet() : (UInt16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ register.int16_0 = left.register.int16_0 > right.register.int16_0 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_1 = left.register.int16_1 > right.register.int16_1 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_2 = left.register.int16_2 > right.register.int16_2 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_3 = left.register.int16_3 > right.register.int16_3 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_4 = left.register.int16_4 > right.register.int16_4 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_5 = left.register.int16_5 > right.register.int16_5 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_6 = left.register.int16_6 > right.register.int16_6 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ register.int16_7 = left.register.int16_7 > right.register.int16_7 ? ConstantHelper.GetInt16WithAllBitsSet() : (Int16)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ register.uint32_0 = left.register.uint32_0 > right.register.uint32_0 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_1 = left.register.uint32_1 > right.register.uint32_1 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_2 = left.register.uint32_2 > right.register.uint32_2 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ register.uint32_3 = left.register.uint32_3 > right.register.uint32_3 ? ConstantHelper.GetUInt32WithAllBitsSet() : (UInt32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ register.int32_0 = left.register.int32_0 > right.register.int32_0 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_1 = left.register.int32_1 > right.register.int32_1 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_2 = left.register.int32_2 > right.register.int32_2 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ register.int32_3 = left.register.int32_3 > right.register.int32_3 ? ConstantHelper.GetInt32WithAllBitsSet() : (Int32)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ register.uint64_0 = left.register.uint64_0 > right.register.uint64_0 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ register.uint64_1 = left.register.uint64_1 > right.register.uint64_1 ? ConstantHelper.GetUInt64WithAllBitsSet() : (UInt64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ register.int64_0 = left.register.int64_0 > right.register.int64_0 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ register.int64_1 = left.register.int64_1 > right.register.int64_1 ? ConstantHelper.GetInt64WithAllBitsSet() : (Int64)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ register.single_0 = left.register.single_0 > right.register.single_0 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_1 = left.register.single_1 > right.register.single_1 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_2 = left.register.single_2 > right.register.single_2 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ register.single_3 = left.register.single_3 > right.register.single_3 ? ConstantHelper.GetSingleWithAllBitsSet() : (Single)0;
+ return new Vector<T>(ref register);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ register.double_0 = left.register.double_0 > right.register.double_0 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ register.double_1 = left.register.double_1 > right.register.double_1 ? ConstantHelper.GetDoubleWithAllBitsSet() : (Double)0;
+ return new Vector<T>(ref register);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static Vector<T> GreaterThanOrEqual(Vector<T> left, Vector<T> right)
+ {
+ return Equals(left, right) | GreaterThan(left, right);
+ }
+
+ [JitIntrinsic]
+ internal static Vector<T> LessThanOrEqual(Vector<T> left, Vector<T> right)
+ {
+ return Equals(left, right) | LessThan(left, right);
+ }
+
+ [JitIntrinsic]
+ internal static Vector<T> ConditionalSelect(Vector<T> condition, Vector<T> left, Vector<T> right)
+ {
+ return (left & condition) | (Vector.AndNot(right, condition));
+ }
+ #endregion Comparison Methods
+
+ #region Internal Math Methods
+ [JitIntrinsic]
+ internal static unsafe Vector<T> Abs(Vector<T> value)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return value;
+ }
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)(object)(Math.Abs((SByte)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)(object)(Math.Abs((Int16)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)(object)(Math.Abs((Int32)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)(object)(Math.Abs((Int64)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)(object)(Math.Abs((Single)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)(object)(Math.Abs((Double)(object)value[g]));
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(SByte))
+ {
+ value.register.sbyte_0 = (SByte)(Math.Abs(value.register.sbyte_0));
+ value.register.sbyte_1 = (SByte)(Math.Abs(value.register.sbyte_1));
+ value.register.sbyte_2 = (SByte)(Math.Abs(value.register.sbyte_2));
+ value.register.sbyte_3 = (SByte)(Math.Abs(value.register.sbyte_3));
+ value.register.sbyte_4 = (SByte)(Math.Abs(value.register.sbyte_4));
+ value.register.sbyte_5 = (SByte)(Math.Abs(value.register.sbyte_5));
+ value.register.sbyte_6 = (SByte)(Math.Abs(value.register.sbyte_6));
+ value.register.sbyte_7 = (SByte)(Math.Abs(value.register.sbyte_7));
+ value.register.sbyte_8 = (SByte)(Math.Abs(value.register.sbyte_8));
+ value.register.sbyte_9 = (SByte)(Math.Abs(value.register.sbyte_9));
+ value.register.sbyte_10 = (SByte)(Math.Abs(value.register.sbyte_10));
+ value.register.sbyte_11 = (SByte)(Math.Abs(value.register.sbyte_11));
+ value.register.sbyte_12 = (SByte)(Math.Abs(value.register.sbyte_12));
+ value.register.sbyte_13 = (SByte)(Math.Abs(value.register.sbyte_13));
+ value.register.sbyte_14 = (SByte)(Math.Abs(value.register.sbyte_14));
+ value.register.sbyte_15 = (SByte)(Math.Abs(value.register.sbyte_15));
+ return value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ value.register.int16_0 = (Int16)(Math.Abs(value.register.int16_0));
+ value.register.int16_1 = (Int16)(Math.Abs(value.register.int16_1));
+ value.register.int16_2 = (Int16)(Math.Abs(value.register.int16_2));
+ value.register.int16_3 = (Int16)(Math.Abs(value.register.int16_3));
+ value.register.int16_4 = (Int16)(Math.Abs(value.register.int16_4));
+ value.register.int16_5 = (Int16)(Math.Abs(value.register.int16_5));
+ value.register.int16_6 = (Int16)(Math.Abs(value.register.int16_6));
+ value.register.int16_7 = (Int16)(Math.Abs(value.register.int16_7));
+ return value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ value.register.int32_0 = (Int32)(Math.Abs(value.register.int32_0));
+ value.register.int32_1 = (Int32)(Math.Abs(value.register.int32_1));
+ value.register.int32_2 = (Int32)(Math.Abs(value.register.int32_2));
+ value.register.int32_3 = (Int32)(Math.Abs(value.register.int32_3));
+ return value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ value.register.int64_0 = (Int64)(Math.Abs(value.register.int64_0));
+ value.register.int64_1 = (Int64)(Math.Abs(value.register.int64_1));
+ return value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ value.register.single_0 = (Single)(Math.Abs(value.register.single_0));
+ value.register.single_1 = (Single)(Math.Abs(value.register.single_1));
+ value.register.single_2 = (Single)(Math.Abs(value.register.single_2));
+ value.register.single_3 = (Single)(Math.Abs(value.register.single_3));
+ return value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ value.register.double_0 = (Double)(Math.Abs(value.register.double_0));
+ value.register.double_1 = (Double)(Math.Abs(value.register.double_1));
+ return value;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static unsafe Vector<T> Min(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Byte)(object)left[g] : (Byte)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (SByte)(object)left[g] : (SByte)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (UInt16)(object)left[g] : (UInt16)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Int16)(object)left[g] : (Int16)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (UInt32)(object)left[g] : (UInt32)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Int32)(object)left[g] : (Int32)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (UInt64)(object)left[g] : (UInt64)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Int64)(object)left[g] : (Int64)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Single)(object)left[g] : (Single)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarLessThan(left[g], right[g]) ? (Double)(object)left[g] : (Double)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> vec = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ vec.register.byte_0 = left.register.byte_0 < right.register.byte_0 ? left.register.byte_0 : right.register.byte_0;
+ vec.register.byte_1 = left.register.byte_1 < right.register.byte_1 ? left.register.byte_1 : right.register.byte_1;
+ vec.register.byte_2 = left.register.byte_2 < right.register.byte_2 ? left.register.byte_2 : right.register.byte_2;
+ vec.register.byte_3 = left.register.byte_3 < right.register.byte_3 ? left.register.byte_3 : right.register.byte_3;
+ vec.register.byte_4 = left.register.byte_4 < right.register.byte_4 ? left.register.byte_4 : right.register.byte_4;
+ vec.register.byte_5 = left.register.byte_5 < right.register.byte_5 ? left.register.byte_5 : right.register.byte_5;
+ vec.register.byte_6 = left.register.byte_6 < right.register.byte_6 ? left.register.byte_6 : right.register.byte_6;
+ vec.register.byte_7 = left.register.byte_7 < right.register.byte_7 ? left.register.byte_7 : right.register.byte_7;
+ vec.register.byte_8 = left.register.byte_8 < right.register.byte_8 ? left.register.byte_8 : right.register.byte_8;
+ vec.register.byte_9 = left.register.byte_9 < right.register.byte_9 ? left.register.byte_9 : right.register.byte_9;
+ vec.register.byte_10 = left.register.byte_10 < right.register.byte_10 ? left.register.byte_10 : right.register.byte_10;
+ vec.register.byte_11 = left.register.byte_11 < right.register.byte_11 ? left.register.byte_11 : right.register.byte_11;
+ vec.register.byte_12 = left.register.byte_12 < right.register.byte_12 ? left.register.byte_12 : right.register.byte_12;
+ vec.register.byte_13 = left.register.byte_13 < right.register.byte_13 ? left.register.byte_13 : right.register.byte_13;
+ vec.register.byte_14 = left.register.byte_14 < right.register.byte_14 ? left.register.byte_14 : right.register.byte_14;
+ vec.register.byte_15 = left.register.byte_15 < right.register.byte_15 ? left.register.byte_15 : right.register.byte_15;
+ return vec;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ vec.register.sbyte_0 = left.register.sbyte_0 < right.register.sbyte_0 ? left.register.sbyte_0 : right.register.sbyte_0;
+ vec.register.sbyte_1 = left.register.sbyte_1 < right.register.sbyte_1 ? left.register.sbyte_1 : right.register.sbyte_1;
+ vec.register.sbyte_2 = left.register.sbyte_2 < right.register.sbyte_2 ? left.register.sbyte_2 : right.register.sbyte_2;
+ vec.register.sbyte_3 = left.register.sbyte_3 < right.register.sbyte_3 ? left.register.sbyte_3 : right.register.sbyte_3;
+ vec.register.sbyte_4 = left.register.sbyte_4 < right.register.sbyte_4 ? left.register.sbyte_4 : right.register.sbyte_4;
+ vec.register.sbyte_5 = left.register.sbyte_5 < right.register.sbyte_5 ? left.register.sbyte_5 : right.register.sbyte_5;
+ vec.register.sbyte_6 = left.register.sbyte_6 < right.register.sbyte_6 ? left.register.sbyte_6 : right.register.sbyte_6;
+ vec.register.sbyte_7 = left.register.sbyte_7 < right.register.sbyte_7 ? left.register.sbyte_7 : right.register.sbyte_7;
+ vec.register.sbyte_8 = left.register.sbyte_8 < right.register.sbyte_8 ? left.register.sbyte_8 : right.register.sbyte_8;
+ vec.register.sbyte_9 = left.register.sbyte_9 < right.register.sbyte_9 ? left.register.sbyte_9 : right.register.sbyte_9;
+ vec.register.sbyte_10 = left.register.sbyte_10 < right.register.sbyte_10 ? left.register.sbyte_10 : right.register.sbyte_10;
+ vec.register.sbyte_11 = left.register.sbyte_11 < right.register.sbyte_11 ? left.register.sbyte_11 : right.register.sbyte_11;
+ vec.register.sbyte_12 = left.register.sbyte_12 < right.register.sbyte_12 ? left.register.sbyte_12 : right.register.sbyte_12;
+ vec.register.sbyte_13 = left.register.sbyte_13 < right.register.sbyte_13 ? left.register.sbyte_13 : right.register.sbyte_13;
+ vec.register.sbyte_14 = left.register.sbyte_14 < right.register.sbyte_14 ? left.register.sbyte_14 : right.register.sbyte_14;
+ vec.register.sbyte_15 = left.register.sbyte_15 < right.register.sbyte_15 ? left.register.sbyte_15 : right.register.sbyte_15;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ vec.register.uint16_0 = left.register.uint16_0 < right.register.uint16_0 ? left.register.uint16_0 : right.register.uint16_0;
+ vec.register.uint16_1 = left.register.uint16_1 < right.register.uint16_1 ? left.register.uint16_1 : right.register.uint16_1;
+ vec.register.uint16_2 = left.register.uint16_2 < right.register.uint16_2 ? left.register.uint16_2 : right.register.uint16_2;
+ vec.register.uint16_3 = left.register.uint16_3 < right.register.uint16_3 ? left.register.uint16_3 : right.register.uint16_3;
+ vec.register.uint16_4 = left.register.uint16_4 < right.register.uint16_4 ? left.register.uint16_4 : right.register.uint16_4;
+ vec.register.uint16_5 = left.register.uint16_5 < right.register.uint16_5 ? left.register.uint16_5 : right.register.uint16_5;
+ vec.register.uint16_6 = left.register.uint16_6 < right.register.uint16_6 ? left.register.uint16_6 : right.register.uint16_6;
+ vec.register.uint16_7 = left.register.uint16_7 < right.register.uint16_7 ? left.register.uint16_7 : right.register.uint16_7;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ vec.register.int16_0 = left.register.int16_0 < right.register.int16_0 ? left.register.int16_0 : right.register.int16_0;
+ vec.register.int16_1 = left.register.int16_1 < right.register.int16_1 ? left.register.int16_1 : right.register.int16_1;
+ vec.register.int16_2 = left.register.int16_2 < right.register.int16_2 ? left.register.int16_2 : right.register.int16_2;
+ vec.register.int16_3 = left.register.int16_3 < right.register.int16_3 ? left.register.int16_3 : right.register.int16_3;
+ vec.register.int16_4 = left.register.int16_4 < right.register.int16_4 ? left.register.int16_4 : right.register.int16_4;
+ vec.register.int16_5 = left.register.int16_5 < right.register.int16_5 ? left.register.int16_5 : right.register.int16_5;
+ vec.register.int16_6 = left.register.int16_6 < right.register.int16_6 ? left.register.int16_6 : right.register.int16_6;
+ vec.register.int16_7 = left.register.int16_7 < right.register.int16_7 ? left.register.int16_7 : right.register.int16_7;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ vec.register.uint32_0 = left.register.uint32_0 < right.register.uint32_0 ? left.register.uint32_0 : right.register.uint32_0;
+ vec.register.uint32_1 = left.register.uint32_1 < right.register.uint32_1 ? left.register.uint32_1 : right.register.uint32_1;
+ vec.register.uint32_2 = left.register.uint32_2 < right.register.uint32_2 ? left.register.uint32_2 : right.register.uint32_2;
+ vec.register.uint32_3 = left.register.uint32_3 < right.register.uint32_3 ? left.register.uint32_3 : right.register.uint32_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ vec.register.int32_0 = left.register.int32_0 < right.register.int32_0 ? left.register.int32_0 : right.register.int32_0;
+ vec.register.int32_1 = left.register.int32_1 < right.register.int32_1 ? left.register.int32_1 : right.register.int32_1;
+ vec.register.int32_2 = left.register.int32_2 < right.register.int32_2 ? left.register.int32_2 : right.register.int32_2;
+ vec.register.int32_3 = left.register.int32_3 < right.register.int32_3 ? left.register.int32_3 : right.register.int32_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ vec.register.uint64_0 = left.register.uint64_0 < right.register.uint64_0 ? left.register.uint64_0 : right.register.uint64_0;
+ vec.register.uint64_1 = left.register.uint64_1 < right.register.uint64_1 ? left.register.uint64_1 : right.register.uint64_1;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ vec.register.int64_0 = left.register.int64_0 < right.register.int64_0 ? left.register.int64_0 : right.register.int64_0;
+ vec.register.int64_1 = left.register.int64_1 < right.register.int64_1 ? left.register.int64_1 : right.register.int64_1;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ vec.register.single_0 = left.register.single_0 < right.register.single_0 ? left.register.single_0 : right.register.single_0;
+ vec.register.single_1 = left.register.single_1 < right.register.single_1 ? left.register.single_1 : right.register.single_1;
+ vec.register.single_2 = left.register.single_2 < right.register.single_2 ? left.register.single_2 : right.register.single_2;
+ vec.register.single_3 = left.register.single_3 < right.register.single_3 ? left.register.single_3 : right.register.single_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ vec.register.double_0 = left.register.double_0 < right.register.double_0 ? left.register.double_0 : right.register.double_0;
+ vec.register.double_1 = left.register.double_1 < right.register.double_1 ? left.register.double_1 : right.register.double_1;
+ return vec;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static unsafe Vector<T> Max(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Byte)(object)left[g] : (Byte)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (SByte)(object)left[g] : (SByte)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (UInt16)(object)left[g] : (UInt16)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Int16)(object)left[g] : (Int16)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (UInt32)(object)left[g] : (UInt32)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Int32)(object)left[g] : (Int32)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (UInt64)(object)left[g] : (UInt64)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Int64)(object)left[g] : (Int64)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Single)(object)left[g] : (Single)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = ScalarGreaterThan(left[g], right[g]) ? (Double)(object)left[g] : (Double)(object)right[g];
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ Vector<T> vec = new Vector<T>();
+ if (typeof(T) == typeof(Byte))
+ {
+ vec.register.byte_0 = left.register.byte_0 > right.register.byte_0 ? left.register.byte_0 : right.register.byte_0;
+ vec.register.byte_1 = left.register.byte_1 > right.register.byte_1 ? left.register.byte_1 : right.register.byte_1;
+ vec.register.byte_2 = left.register.byte_2 > right.register.byte_2 ? left.register.byte_2 : right.register.byte_2;
+ vec.register.byte_3 = left.register.byte_3 > right.register.byte_3 ? left.register.byte_3 : right.register.byte_3;
+ vec.register.byte_4 = left.register.byte_4 > right.register.byte_4 ? left.register.byte_4 : right.register.byte_4;
+ vec.register.byte_5 = left.register.byte_5 > right.register.byte_5 ? left.register.byte_5 : right.register.byte_5;
+ vec.register.byte_6 = left.register.byte_6 > right.register.byte_6 ? left.register.byte_6 : right.register.byte_6;
+ vec.register.byte_7 = left.register.byte_7 > right.register.byte_7 ? left.register.byte_7 : right.register.byte_7;
+ vec.register.byte_8 = left.register.byte_8 > right.register.byte_8 ? left.register.byte_8 : right.register.byte_8;
+ vec.register.byte_9 = left.register.byte_9 > right.register.byte_9 ? left.register.byte_9 : right.register.byte_9;
+ vec.register.byte_10 = left.register.byte_10 > right.register.byte_10 ? left.register.byte_10 : right.register.byte_10;
+ vec.register.byte_11 = left.register.byte_11 > right.register.byte_11 ? left.register.byte_11 : right.register.byte_11;
+ vec.register.byte_12 = left.register.byte_12 > right.register.byte_12 ? left.register.byte_12 : right.register.byte_12;
+ vec.register.byte_13 = left.register.byte_13 > right.register.byte_13 ? left.register.byte_13 : right.register.byte_13;
+ vec.register.byte_14 = left.register.byte_14 > right.register.byte_14 ? left.register.byte_14 : right.register.byte_14;
+ vec.register.byte_15 = left.register.byte_15 > right.register.byte_15 ? left.register.byte_15 : right.register.byte_15;
+ return vec;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ vec.register.sbyte_0 = left.register.sbyte_0 > right.register.sbyte_0 ? left.register.sbyte_0 : right.register.sbyte_0;
+ vec.register.sbyte_1 = left.register.sbyte_1 > right.register.sbyte_1 ? left.register.sbyte_1 : right.register.sbyte_1;
+ vec.register.sbyte_2 = left.register.sbyte_2 > right.register.sbyte_2 ? left.register.sbyte_2 : right.register.sbyte_2;
+ vec.register.sbyte_3 = left.register.sbyte_3 > right.register.sbyte_3 ? left.register.sbyte_3 : right.register.sbyte_3;
+ vec.register.sbyte_4 = left.register.sbyte_4 > right.register.sbyte_4 ? left.register.sbyte_4 : right.register.sbyte_4;
+ vec.register.sbyte_5 = left.register.sbyte_5 > right.register.sbyte_5 ? left.register.sbyte_5 : right.register.sbyte_5;
+ vec.register.sbyte_6 = left.register.sbyte_6 > right.register.sbyte_6 ? left.register.sbyte_6 : right.register.sbyte_6;
+ vec.register.sbyte_7 = left.register.sbyte_7 > right.register.sbyte_7 ? left.register.sbyte_7 : right.register.sbyte_7;
+ vec.register.sbyte_8 = left.register.sbyte_8 > right.register.sbyte_8 ? left.register.sbyte_8 : right.register.sbyte_8;
+ vec.register.sbyte_9 = left.register.sbyte_9 > right.register.sbyte_9 ? left.register.sbyte_9 : right.register.sbyte_9;
+ vec.register.sbyte_10 = left.register.sbyte_10 > right.register.sbyte_10 ? left.register.sbyte_10 : right.register.sbyte_10;
+ vec.register.sbyte_11 = left.register.sbyte_11 > right.register.sbyte_11 ? left.register.sbyte_11 : right.register.sbyte_11;
+ vec.register.sbyte_12 = left.register.sbyte_12 > right.register.sbyte_12 ? left.register.sbyte_12 : right.register.sbyte_12;
+ vec.register.sbyte_13 = left.register.sbyte_13 > right.register.sbyte_13 ? left.register.sbyte_13 : right.register.sbyte_13;
+ vec.register.sbyte_14 = left.register.sbyte_14 > right.register.sbyte_14 ? left.register.sbyte_14 : right.register.sbyte_14;
+ vec.register.sbyte_15 = left.register.sbyte_15 > right.register.sbyte_15 ? left.register.sbyte_15 : right.register.sbyte_15;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ vec.register.uint16_0 = left.register.uint16_0 > right.register.uint16_0 ? left.register.uint16_0 : right.register.uint16_0;
+ vec.register.uint16_1 = left.register.uint16_1 > right.register.uint16_1 ? left.register.uint16_1 : right.register.uint16_1;
+ vec.register.uint16_2 = left.register.uint16_2 > right.register.uint16_2 ? left.register.uint16_2 : right.register.uint16_2;
+ vec.register.uint16_3 = left.register.uint16_3 > right.register.uint16_3 ? left.register.uint16_3 : right.register.uint16_3;
+ vec.register.uint16_4 = left.register.uint16_4 > right.register.uint16_4 ? left.register.uint16_4 : right.register.uint16_4;
+ vec.register.uint16_5 = left.register.uint16_5 > right.register.uint16_5 ? left.register.uint16_5 : right.register.uint16_5;
+ vec.register.uint16_6 = left.register.uint16_6 > right.register.uint16_6 ? left.register.uint16_6 : right.register.uint16_6;
+ vec.register.uint16_7 = left.register.uint16_7 > right.register.uint16_7 ? left.register.uint16_7 : right.register.uint16_7;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ vec.register.int16_0 = left.register.int16_0 > right.register.int16_0 ? left.register.int16_0 : right.register.int16_0;
+ vec.register.int16_1 = left.register.int16_1 > right.register.int16_1 ? left.register.int16_1 : right.register.int16_1;
+ vec.register.int16_2 = left.register.int16_2 > right.register.int16_2 ? left.register.int16_2 : right.register.int16_2;
+ vec.register.int16_3 = left.register.int16_3 > right.register.int16_3 ? left.register.int16_3 : right.register.int16_3;
+ vec.register.int16_4 = left.register.int16_4 > right.register.int16_4 ? left.register.int16_4 : right.register.int16_4;
+ vec.register.int16_5 = left.register.int16_5 > right.register.int16_5 ? left.register.int16_5 : right.register.int16_5;
+ vec.register.int16_6 = left.register.int16_6 > right.register.int16_6 ? left.register.int16_6 : right.register.int16_6;
+ vec.register.int16_7 = left.register.int16_7 > right.register.int16_7 ? left.register.int16_7 : right.register.int16_7;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ vec.register.uint32_0 = left.register.uint32_0 > right.register.uint32_0 ? left.register.uint32_0 : right.register.uint32_0;
+ vec.register.uint32_1 = left.register.uint32_1 > right.register.uint32_1 ? left.register.uint32_1 : right.register.uint32_1;
+ vec.register.uint32_2 = left.register.uint32_2 > right.register.uint32_2 ? left.register.uint32_2 : right.register.uint32_2;
+ vec.register.uint32_3 = left.register.uint32_3 > right.register.uint32_3 ? left.register.uint32_3 : right.register.uint32_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ vec.register.int32_0 = left.register.int32_0 > right.register.int32_0 ? left.register.int32_0 : right.register.int32_0;
+ vec.register.int32_1 = left.register.int32_1 > right.register.int32_1 ? left.register.int32_1 : right.register.int32_1;
+ vec.register.int32_2 = left.register.int32_2 > right.register.int32_2 ? left.register.int32_2 : right.register.int32_2;
+ vec.register.int32_3 = left.register.int32_3 > right.register.int32_3 ? left.register.int32_3 : right.register.int32_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ vec.register.uint64_0 = left.register.uint64_0 > right.register.uint64_0 ? left.register.uint64_0 : right.register.uint64_0;
+ vec.register.uint64_1 = left.register.uint64_1 > right.register.uint64_1 ? left.register.uint64_1 : right.register.uint64_1;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ vec.register.int64_0 = left.register.int64_0 > right.register.int64_0 ? left.register.int64_0 : right.register.int64_0;
+ vec.register.int64_1 = left.register.int64_1 > right.register.int64_1 ? left.register.int64_1 : right.register.int64_1;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ vec.register.single_0 = left.register.single_0 > right.register.single_0 ? left.register.single_0 : right.register.single_0;
+ vec.register.single_1 = left.register.single_1 > right.register.single_1 ? left.register.single_1 : right.register.single_1;
+ vec.register.single_2 = left.register.single_2 > right.register.single_2 ? left.register.single_2 : right.register.single_2;
+ vec.register.single_3 = left.register.single_3 > right.register.single_3 ? left.register.single_3 : right.register.single_3;
+ return vec;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ vec.register.double_0 = left.register.double_0 > right.register.double_0 ? left.register.double_0 : right.register.double_0;
+ vec.register.double_1 = left.register.double_1 > right.register.double_1 ? left.register.double_1 : right.register.double_1;
+ return vec;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static T DotProduct(Vector<T> left, Vector<T> right)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ T product = GetZeroValue();
+ for (int g = 0; g < Count; g++)
+ {
+ product = ScalarAdd(product, ScalarMultiply(left[g], right[g]));
+ }
+ return product;
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte product = 0;
+ product += (Byte)(left.register.byte_0 * right.register.byte_0);
+ product += (Byte)(left.register.byte_1 * right.register.byte_1);
+ product += (Byte)(left.register.byte_2 * right.register.byte_2);
+ product += (Byte)(left.register.byte_3 * right.register.byte_3);
+ product += (Byte)(left.register.byte_4 * right.register.byte_4);
+ product += (Byte)(left.register.byte_5 * right.register.byte_5);
+ product += (Byte)(left.register.byte_6 * right.register.byte_6);
+ product += (Byte)(left.register.byte_7 * right.register.byte_7);
+ product += (Byte)(left.register.byte_8 * right.register.byte_8);
+ product += (Byte)(left.register.byte_9 * right.register.byte_9);
+ product += (Byte)(left.register.byte_10 * right.register.byte_10);
+ product += (Byte)(left.register.byte_11 * right.register.byte_11);
+ product += (Byte)(left.register.byte_12 * right.register.byte_12);
+ product += (Byte)(left.register.byte_13 * right.register.byte_13);
+ product += (Byte)(left.register.byte_14 * right.register.byte_14);
+ product += (Byte)(left.register.byte_15 * right.register.byte_15);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte product = 0;
+ product += (SByte)(left.register.sbyte_0 * right.register.sbyte_0);
+ product += (SByte)(left.register.sbyte_1 * right.register.sbyte_1);
+ product += (SByte)(left.register.sbyte_2 * right.register.sbyte_2);
+ product += (SByte)(left.register.sbyte_3 * right.register.sbyte_3);
+ product += (SByte)(left.register.sbyte_4 * right.register.sbyte_4);
+ product += (SByte)(left.register.sbyte_5 * right.register.sbyte_5);
+ product += (SByte)(left.register.sbyte_6 * right.register.sbyte_6);
+ product += (SByte)(left.register.sbyte_7 * right.register.sbyte_7);
+ product += (SByte)(left.register.sbyte_8 * right.register.sbyte_8);
+ product += (SByte)(left.register.sbyte_9 * right.register.sbyte_9);
+ product += (SByte)(left.register.sbyte_10 * right.register.sbyte_10);
+ product += (SByte)(left.register.sbyte_11 * right.register.sbyte_11);
+ product += (SByte)(left.register.sbyte_12 * right.register.sbyte_12);
+ product += (SByte)(left.register.sbyte_13 * right.register.sbyte_13);
+ product += (SByte)(left.register.sbyte_14 * right.register.sbyte_14);
+ product += (SByte)(left.register.sbyte_15 * right.register.sbyte_15);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16 product = 0;
+ product += (UInt16)(left.register.uint16_0 * right.register.uint16_0);
+ product += (UInt16)(left.register.uint16_1 * right.register.uint16_1);
+ product += (UInt16)(left.register.uint16_2 * right.register.uint16_2);
+ product += (UInt16)(left.register.uint16_3 * right.register.uint16_3);
+ product += (UInt16)(left.register.uint16_4 * right.register.uint16_4);
+ product += (UInt16)(left.register.uint16_5 * right.register.uint16_5);
+ product += (UInt16)(left.register.uint16_6 * right.register.uint16_6);
+ product += (UInt16)(left.register.uint16_7 * right.register.uint16_7);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16 product = 0;
+ product += (Int16)(left.register.int16_0 * right.register.int16_0);
+ product += (Int16)(left.register.int16_1 * right.register.int16_1);
+ product += (Int16)(left.register.int16_2 * right.register.int16_2);
+ product += (Int16)(left.register.int16_3 * right.register.int16_3);
+ product += (Int16)(left.register.int16_4 * right.register.int16_4);
+ product += (Int16)(left.register.int16_5 * right.register.int16_5);
+ product += (Int16)(left.register.int16_6 * right.register.int16_6);
+ product += (Int16)(left.register.int16_7 * right.register.int16_7);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32 product = 0;
+ product += (UInt32)(left.register.uint32_0 * right.register.uint32_0);
+ product += (UInt32)(left.register.uint32_1 * right.register.uint32_1);
+ product += (UInt32)(left.register.uint32_2 * right.register.uint32_2);
+ product += (UInt32)(left.register.uint32_3 * right.register.uint32_3);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32 product = 0;
+ product += (Int32)(left.register.int32_0 * right.register.int32_0);
+ product += (Int32)(left.register.int32_1 * right.register.int32_1);
+ product += (Int32)(left.register.int32_2 * right.register.int32_2);
+ product += (Int32)(left.register.int32_3 * right.register.int32_3);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64 product = 0;
+ product += (UInt64)(left.register.uint64_0 * right.register.uint64_0);
+ product += (UInt64)(left.register.uint64_1 * right.register.uint64_1);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64 product = 0;
+ product += (Int64)(left.register.int64_0 * right.register.int64_0);
+ product += (Int64)(left.register.int64_1 * right.register.int64_1);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single product = 0;
+ product += (Single)(left.register.single_0 * right.register.single_0);
+ product += (Single)(left.register.single_1 * right.register.single_1);
+ product += (Single)(left.register.single_2 * right.register.single_2);
+ product += (Single)(left.register.single_3 * right.register.single_3);
+ return (T)(object)product;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double product = 0;
+ product += (Double)(left.register.double_0 * right.register.double_0);
+ product += (Double)(left.register.double_1 * right.register.double_1);
+ return (T)(object)product;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+
+ [JitIntrinsic]
+ internal static unsafe Vector<T> SquareRoot(Vector<T> value)
+ {
+ if (Vector.IsHardwareAccelerated)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte* dataPtr = stackalloc Byte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Byte)Math.Sqrt((Byte)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte* dataPtr = stackalloc SByte[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (SByte)Math.Sqrt((SByte)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16* dataPtr = stackalloc UInt16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt16)Math.Sqrt((UInt16)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16* dataPtr = stackalloc Int16[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int16)Math.Sqrt((Int16)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32* dataPtr = stackalloc UInt32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt32)Math.Sqrt((UInt32)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32* dataPtr = stackalloc Int32[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int32)Math.Sqrt((Int32)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64* dataPtr = stackalloc UInt64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (UInt64)Math.Sqrt((UInt64)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64* dataPtr = stackalloc Int64[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Int64)Math.Sqrt((Int64)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single* dataPtr = stackalloc Single[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Single)Math.Sqrt((Single)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double* dataPtr = stackalloc Double[Count];
+ for (int g = 0; g < Count; g++)
+ {
+ dataPtr[g] = (Double)Math.Sqrt((Double)(object)value[g]);
+ }
+ return new Vector<T>(dataPtr);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ else
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ value.register.byte_0 = (Byte)Math.Sqrt(value.register.byte_0);
+ value.register.byte_1 = (Byte)Math.Sqrt(value.register.byte_1);
+ value.register.byte_2 = (Byte)Math.Sqrt(value.register.byte_2);
+ value.register.byte_3 = (Byte)Math.Sqrt(value.register.byte_3);
+ value.register.byte_4 = (Byte)Math.Sqrt(value.register.byte_4);
+ value.register.byte_5 = (Byte)Math.Sqrt(value.register.byte_5);
+ value.register.byte_6 = (Byte)Math.Sqrt(value.register.byte_6);
+ value.register.byte_7 = (Byte)Math.Sqrt(value.register.byte_7);
+ value.register.byte_8 = (Byte)Math.Sqrt(value.register.byte_8);
+ value.register.byte_9 = (Byte)Math.Sqrt(value.register.byte_9);
+ value.register.byte_10 = (Byte)Math.Sqrt(value.register.byte_10);
+ value.register.byte_11 = (Byte)Math.Sqrt(value.register.byte_11);
+ value.register.byte_12 = (Byte)Math.Sqrt(value.register.byte_12);
+ value.register.byte_13 = (Byte)Math.Sqrt(value.register.byte_13);
+ value.register.byte_14 = (Byte)Math.Sqrt(value.register.byte_14);
+ value.register.byte_15 = (Byte)Math.Sqrt(value.register.byte_15);
+ return value;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ value.register.sbyte_0 = (SByte)Math.Sqrt(value.register.sbyte_0);
+ value.register.sbyte_1 = (SByte)Math.Sqrt(value.register.sbyte_1);
+ value.register.sbyte_2 = (SByte)Math.Sqrt(value.register.sbyte_2);
+ value.register.sbyte_3 = (SByte)Math.Sqrt(value.register.sbyte_3);
+ value.register.sbyte_4 = (SByte)Math.Sqrt(value.register.sbyte_4);
+ value.register.sbyte_5 = (SByte)Math.Sqrt(value.register.sbyte_5);
+ value.register.sbyte_6 = (SByte)Math.Sqrt(value.register.sbyte_6);
+ value.register.sbyte_7 = (SByte)Math.Sqrt(value.register.sbyte_7);
+ value.register.sbyte_8 = (SByte)Math.Sqrt(value.register.sbyte_8);
+ value.register.sbyte_9 = (SByte)Math.Sqrt(value.register.sbyte_9);
+ value.register.sbyte_10 = (SByte)Math.Sqrt(value.register.sbyte_10);
+ value.register.sbyte_11 = (SByte)Math.Sqrt(value.register.sbyte_11);
+ value.register.sbyte_12 = (SByte)Math.Sqrt(value.register.sbyte_12);
+ value.register.sbyte_13 = (SByte)Math.Sqrt(value.register.sbyte_13);
+ value.register.sbyte_14 = (SByte)Math.Sqrt(value.register.sbyte_14);
+ value.register.sbyte_15 = (SByte)Math.Sqrt(value.register.sbyte_15);
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ value.register.uint16_0 = (UInt16)Math.Sqrt(value.register.uint16_0);
+ value.register.uint16_1 = (UInt16)Math.Sqrt(value.register.uint16_1);
+ value.register.uint16_2 = (UInt16)Math.Sqrt(value.register.uint16_2);
+ value.register.uint16_3 = (UInt16)Math.Sqrt(value.register.uint16_3);
+ value.register.uint16_4 = (UInt16)Math.Sqrt(value.register.uint16_4);
+ value.register.uint16_5 = (UInt16)Math.Sqrt(value.register.uint16_5);
+ value.register.uint16_6 = (UInt16)Math.Sqrt(value.register.uint16_6);
+ value.register.uint16_7 = (UInt16)Math.Sqrt(value.register.uint16_7);
+ return value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ value.register.int16_0 = (Int16)Math.Sqrt(value.register.int16_0);
+ value.register.int16_1 = (Int16)Math.Sqrt(value.register.int16_1);
+ value.register.int16_2 = (Int16)Math.Sqrt(value.register.int16_2);
+ value.register.int16_3 = (Int16)Math.Sqrt(value.register.int16_3);
+ value.register.int16_4 = (Int16)Math.Sqrt(value.register.int16_4);
+ value.register.int16_5 = (Int16)Math.Sqrt(value.register.int16_5);
+ value.register.int16_6 = (Int16)Math.Sqrt(value.register.int16_6);
+ value.register.int16_7 = (Int16)Math.Sqrt(value.register.int16_7);
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ value.register.uint32_0 = (UInt32)Math.Sqrt(value.register.uint32_0);
+ value.register.uint32_1 = (UInt32)Math.Sqrt(value.register.uint32_1);
+ value.register.uint32_2 = (UInt32)Math.Sqrt(value.register.uint32_2);
+ value.register.uint32_3 = (UInt32)Math.Sqrt(value.register.uint32_3);
+ return value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ value.register.int32_0 = (Int32)Math.Sqrt(value.register.int32_0);
+ value.register.int32_1 = (Int32)Math.Sqrt(value.register.int32_1);
+ value.register.int32_2 = (Int32)Math.Sqrt(value.register.int32_2);
+ value.register.int32_3 = (Int32)Math.Sqrt(value.register.int32_3);
+ return value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ value.register.uint64_0 = (UInt64)Math.Sqrt(value.register.uint64_0);
+ value.register.uint64_1 = (UInt64)Math.Sqrt(value.register.uint64_1);
+ return value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ value.register.int64_0 = (Int64)Math.Sqrt(value.register.int64_0);
+ value.register.int64_1 = (Int64)Math.Sqrt(value.register.int64_1);
+ return value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ value.register.single_0 = (Single)Math.Sqrt(value.register.single_0);
+ value.register.single_1 = (Single)Math.Sqrt(value.register.single_1);
+ value.register.single_2 = (Single)Math.Sqrt(value.register.single_2);
+ value.register.single_3 = (Single)Math.Sqrt(value.register.single_3);
+ return value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ value.register.double_0 = (Double)Math.Sqrt(value.register.double_0);
+ value.register.double_1 = (Double)Math.Sqrt(value.register.double_1);
+ return value;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ }
+ #endregion Internal Math Methods
+
+ #region Helper Methods
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static bool ScalarEquals(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (Byte)(object)left == (Byte)(object)right;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (SByte)(object)left == (SByte)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (UInt16)(object)left == (UInt16)(object)right;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (Int16)(object)left == (Int16)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (UInt32)(object)left == (UInt32)(object)right;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (Int32)(object)left == (Int32)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (UInt64)(object)left == (UInt64)(object)right;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (Int64)(object)left == (Int64)(object)right;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (Single)(object)left == (Single)(object)right;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (Double)(object)left == (Double)(object)right;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static bool ScalarLessThan(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (Byte)(object)left < (Byte)(object)right;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (SByte)(object)left < (SByte)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (UInt16)(object)left < (UInt16)(object)right;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (Int16)(object)left < (Int16)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (UInt32)(object)left < (UInt32)(object)right;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (Int32)(object)left < (Int32)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (UInt64)(object)left < (UInt64)(object)right;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (Int64)(object)left < (Int64)(object)right;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (Single)(object)left < (Single)(object)right;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (Double)(object)left < (Double)(object)right;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static bool ScalarGreaterThan(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (Byte)(object)left > (Byte)(object)right;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (SByte)(object)left > (SByte)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (UInt16)(object)left > (UInt16)(object)right;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (Int16)(object)left > (Int16)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (UInt32)(object)left > (UInt32)(object)right;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (Int32)(object)left > (Int32)(object)right;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (UInt64)(object)left > (UInt64)(object)right;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (Int64)(object)left > (Int64)(object)right;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (Single)(object)left > (Single)(object)right;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (Double)(object)left > (Double)(object)right;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T ScalarAdd(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)(Byte)((Byte)(object)left + (Byte)(object)right);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)(SByte)((SByte)(object)left + (SByte)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)(UInt16)((UInt16)(object)left + (UInt16)(object)right);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)(Int16)((Int16)(object)left + (Int16)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)(UInt32)((UInt32)(object)left + (UInt32)(object)right);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)(Int32)((Int32)(object)left + (Int32)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)(UInt64)((UInt64)(object)left + (UInt64)(object)right);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)(Int64)((Int64)(object)left + (Int64)(object)right);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)(Single)((Single)(object)left + (Single)(object)right);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)(Double)((Double)(object)left + (Double)(object)right);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T ScalarSubtract(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)(Byte)((Byte)(object)left - (Byte)(object)right);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)(SByte)((SByte)(object)left - (SByte)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)(UInt16)((UInt16)(object)left - (UInt16)(object)right);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)(Int16)((Int16)(object)left - (Int16)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)(UInt32)((UInt32)(object)left - (UInt32)(object)right);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)(Int32)((Int32)(object)left - (Int32)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)(UInt64)((UInt64)(object)left - (UInt64)(object)right);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)(Int64)((Int64)(object)left - (Int64)(object)right);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)(Single)((Single)(object)left - (Single)(object)right);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)(Double)((Double)(object)left - (Double)(object)right);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T ScalarMultiply(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)(Byte)((Byte)(object)left * (Byte)(object)right);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)(SByte)((SByte)(object)left * (SByte)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)(UInt16)((UInt16)(object)left * (UInt16)(object)right);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)(Int16)((Int16)(object)left * (Int16)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)(UInt32)((UInt32)(object)left * (UInt32)(object)right);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)(Int32)((Int32)(object)left * (Int32)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)(UInt64)((UInt64)(object)left * (UInt64)(object)right);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)(Int64)((Int64)(object)left * (Int64)(object)right);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)(Single)((Single)(object)left * (Single)(object)right);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)(Double)((Double)(object)left * (Double)(object)right);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T ScalarDivide(T left, T right)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)(Byte)((Byte)(object)left / (Byte)(object)right);
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)(SByte)((SByte)(object)left / (SByte)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)(UInt16)((UInt16)(object)left / (UInt16)(object)right);
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)(Int16)((Int16)(object)left / (Int16)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)(UInt32)((UInt32)(object)left / (UInt32)(object)right);
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)(Int32)((Int32)(object)left / (Int32)(object)right);
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)(UInt64)((UInt64)(object)left / (UInt64)(object)right);
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)(Int64)((Int64)(object)left / (Int64)(object)right);
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)(Single)((Single)(object)left / (Single)(object)right);
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)(Double)((Double)(object)left / (Double)(object)right);
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T GetZeroValue()
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64 value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single value = 0;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double value = 0;
+ return (T)(object)value;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T GetOneValue()
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ Byte value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ SByte value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ UInt16 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ Int16 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ UInt32 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ Int32 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ UInt64 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ Int64 value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ Single value = 1;
+ return (T)(object)value;
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ Double value = 1;
+ return (T)(object)value;
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static T GetAllBitsSetValue()
+ {
+ if (typeof(T) == typeof(Byte))
+ {
+ return (T)(object)ConstantHelper.GetByteWithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(SByte))
+ {
+ return (T)(object)ConstantHelper.GetSByteWithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(UInt16))
+ {
+ return (T)(object)ConstantHelper.GetUInt16WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Int16))
+ {
+ return (T)(object)ConstantHelper.GetInt16WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(UInt32))
+ {
+ return (T)(object)ConstantHelper.GetUInt32WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Int32))
+ {
+ return (T)(object)ConstantHelper.GetInt32WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(UInt64))
+ {
+ return (T)(object)ConstantHelper.GetUInt64WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Int64))
+ {
+ return (T)(object)ConstantHelper.GetInt64WithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Single))
+ {
+ return (T)(object)ConstantHelper.GetSingleWithAllBitsSet();
+ }
+ else if (typeof(T) == typeof(Double))
+ {
+ return (T)(object)ConstantHelper.GetDoubleWithAllBitsSet();
+ }
+ else
+ {
+ throw new NotSupportedException(SR.Arg_TypeNotSupported);
+ }
+ }
+ #endregion
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.CompilerServices;
+
+namespace System.Numerics
+{
+ /// <summary>
+ /// Contains various methods useful for creating, manipulating, combining, and converting generic vectors with one another.
+ /// </summary>
+ public static class Vector
+ {
+ // JIT is not looking at the Vector class methods
+ // all methods here should be inlined and they must be implemented in terms of Vector<T> intrinsics
+ #region Select Methods
+ /// <summary>
+ /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector.
+ /// </summary>
+ /// <param name="condition">The integral mask vector used to drive selection.</param>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The new vector with elements selected based on the mask.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Single> ConditionalSelect(Vector<int> condition, Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<Single>)Vector<Single>.ConditionalSelect((Vector<Single>)condition, left, right);
+ }
+
+ /// <summary>
+ /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector.
+ /// </summary>
+ /// <param name="condition">The integral mask vector used to drive selection.</param>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The new vector with elements selected based on the mask.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<double> ConditionalSelect(Vector<long> condition, Vector<double> left, Vector<double> right)
+ {
+ return (Vector<double>)Vector<double>.ConditionalSelect((Vector<double>)condition, left, right);
+ }
+
+ /// <summary>
+ /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector.
+ /// </summary>
+ /// <param name="condition">The mask vector used to drive selection.</param>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The new vector with elements selected based on the mask.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> ConditionalSelect<T>(Vector<T> condition, Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.ConditionalSelect(condition, left, right);
+ }
+ #endregion Select Methods
+
+ #region Comparison methods
+ #region Equals methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left and right were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Equals<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> Equals(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left and right were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> Equals(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> Equals(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left and right were equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> Equals(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.Equals(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether each pair of elements in the given vectors are equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The first vector to compare.</param>
+ /// <returns>True if all elements are equal; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool EqualsAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left == right;
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any single pair of elements in the given vectors are equal.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any element pairs are equal; False if no element pairs are equal.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool EqualsAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return !Vector<T>.Equals(left, right).Equals(Vector<T>.Zero);
+ }
+ #endregion Equals methods
+
+ #region Lessthan Methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> LessThan<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> LessThan(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> LessThan(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> LessThan(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> LessThan(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.LessThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether all of the elements in left are less than their corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if all elements in left are less than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool LessThanAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.LessThan(left, right);
+ return cond.Equals(Vector<int>.AllOnes);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any element in left is less than its corresponding element in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any elements in left are less than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool LessThanAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.LessThan(left, right);
+ return !cond.Equals(Vector<int>.Zero);
+ }
+ #endregion LessthanMethods
+
+ #region Lessthanorequal methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> LessThanOrEqual<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> LessThanOrEqual(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> LessThanOrEqual(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> LessThanOrEqual(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> LessThanOrEqual(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.LessThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether all elements in left are less than or equal to their corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if all elements in left are less than or equal to their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool LessThanOrEqualAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.LessThanOrEqual(left, right);
+ return cond.Equals(Vector<int>.AllOnes);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any element in left is less than or equal to its corresponding element in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any elements in left are less than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool LessThanOrEqualAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.LessThanOrEqual(left, right);
+ return !cond.Equals(Vector<int>.Zero);
+ }
+ #endregion Lessthanorequal methods
+
+ #region Greaterthan methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> GreaterThan<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> GreaterThan(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> GreaterThan(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> GreaterThan(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> GreaterThan(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.GreaterThan(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether all elements in left are greater than the corresponding elements in right.
+ /// elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if all elements in left are greater than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool GreaterThanAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.GreaterThan(left, right);
+ return cond.Equals(Vector<int>.AllOnes);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any element in left is greater than its corresponding element in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any elements in left are greater than their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool GreaterThanAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.GreaterThan(left, right);
+ return !cond.Equals(Vector<int>.Zero);
+ }
+ #endregion Greaterthan methods
+
+ #region Greaterthanorequal methods
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> GreaterThanOrEqual<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> GreaterThanOrEqual(Vector<Single> left, Vector<Single> right)
+ {
+ return (Vector<int>)Vector<Single>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<int> GreaterThanOrEqual(Vector<int> left, Vector<int> right)
+ {
+ return Vector<int>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their
+ /// corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> GreaterThanOrEqual(Vector<long> left, Vector<long> right)
+ {
+ return Vector<long>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to
+ /// their corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>The resultant integral vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<long> GreaterThanOrEqual(Vector<double> left, Vector<double> right)
+ {
+ return (Vector<long>)Vector<double>.GreaterThanOrEqual(left, right);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether all of the elements in left are greater than or equal to
+ /// their corresponding elements in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if all elements in left are greater than or equal to their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool GreaterThanOrEqualAll<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.GreaterThanOrEqual(left, right);
+ return cond.Equals(Vector<int>.AllOnes);
+ }
+
+ /// <summary>
+ /// Returns a boolean indicating whether any element in left is greater than or equal to its corresponding element in right.
+ /// </summary>
+ /// <param name="left">The first vector to compare.</param>
+ /// <param name="right">The second vector to compare.</param>
+ /// <returns>True if any elements in left are greater than or equal to their corresponding elements in right; False otherwise.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static bool GreaterThanOrEqualAny<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ Vector<int> cond = (Vector<int>)Vector<T>.GreaterThanOrEqual(left, right);
+ return !cond.Equals(Vector<int>.Zero);
+ }
+ #endregion Greaterthanorequal methods
+ #endregion Comparison methods
+
+ #region Vector Math Methods
+ // Every operation must either be a JIT intrinsic or implemented over a JIT intrinsic
+ // as a thin wrapper
+ // Operations implemented over a JIT intrinsic should be inlined
+ // Methods that do not have a <T> type parameter are recognized as intrinsics
+ /// <summary>
+ /// Returns whether or not vector operations are subject to hardware acceleration through JIT intrinsic support.
+ /// </summary>
+ [JitIntrinsic]
+ public static bool IsHardwareAccelerated
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ // Vector<T>
+ // Basic Math
+ // All Math operations for Vector<T> are aggressively inlined here
+
+ /// <summary>
+ /// Returns a new vector whose elements are the absolute values of the given vector's elements.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The absolute value vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Abs<T>(Vector<T> value) where T : struct
+ {
+ return Vector<T>.Abs(value);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are the minimum of each pair of elements in the two given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The minimum vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Min<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.Min(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are the maximum of each pair of elements in the two given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The maximum vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Max<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.Max(left, right);
+ }
+
+ // Specialized vector operations
+
+ /// <summary>
+ /// Returns the dot product of two vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The dot product.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static T Dot<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return Vector<T>.DotProduct(left, right);
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are the square roots of the given vector's elements.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The square root vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> SquareRoot<T>(Vector<T> value) where T : struct
+ {
+ return Vector<T>.SquareRoot(value);
+ }
+ #endregion Vector Math Methods
+
+ #region Named Arithmetic Operators
+ /// <summary>
+ /// Creates a new vector whose values are the sum of each pair of elements from the two given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The summed vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Add<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left + right;
+ }
+
+ /// <summary>
+ /// Creates a new vector whose values are the difference between each pairs of elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The difference vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Subtract<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left - right;
+ }
+
+ /// <summary>
+ /// Creates a new vector whose values are the product of each pair of elements from the two given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The summed vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Multiply<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left * right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value.
+ /// </summary>
+ /// <param name="left">The source vector.</param>
+ /// <param name="right">The scalar factor.</param>
+ /// <returns>The scaled vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Multiply<T>(Vector<T> left, T right) where T : struct
+ {
+ return left * right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value.
+ /// </summary>
+ /// <param name="left">The scalar factor.</param>
+ /// <param name="right">The source vector.</param>
+ /// <returns>The scaled vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Multiply<T>(T left, Vector<T> right) where T : struct
+ {
+ return left * right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose values are the result of dividing the first vector's elements
+ /// by the corresponding elements in the second vector.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The divided vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Divide<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left / right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are the given vector's elements negated.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The negated vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Negate<T>(Vector<T> value) where T : struct
+ {
+ return -value;
+ }
+ #endregion Named Arithmetic Operators
+
+ #region Named Bitwise Operators
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> BitwiseAnd<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left & right;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> BitwiseOr<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left | right;
+ }
+
+ /// <summary>
+ /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements.
+ /// </summary>
+ /// <param name="value">The source vector.</param>
+ /// <returns>The one's complement vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> OnesComplement<T>(Vector<T> value) where T : struct
+ {
+ return ~value;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> Xor<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left ^ right;
+ }
+
+ /// <summary>
+ /// Returns a new vector by performing a bitwise-and-not operation on each of the elements in the given vectors.
+ /// </summary>
+ /// <param name="left">The first source vector.</param>
+ /// <param name="right">The second source vector.</param>
+ /// <returns>The resultant vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<T> AndNot<T>(Vector<T> left, Vector<T> right) where T : struct
+ {
+ return left & ~right;
+ }
+ #endregion Named Bitwise Operators
+
+ #region Conversion Methods
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of unsigned bytes.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Byte> AsVectorByte<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Byte>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of signed bytes.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<SByte> AsVectorSByte<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<SByte>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of 16-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<UInt16> AsVectorUInt16<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<UInt16>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of signed 16-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Int16> AsVectorInt16<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Int16>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of unsigned 32-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<UInt32> AsVectorUInt32<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<UInt32>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of signed 32-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Int32> AsVectorInt32<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Int32>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of unsigned 64-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [CLSCompliant(false)]
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<UInt64> AsVectorUInt64<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<UInt64>)value;
+ }
+
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of signed 64-bit integers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Int64> AsVectorInt64<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Int64>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of 32-bit floating point numbers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Single> AsVectorSingle<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Single>)value;
+ }
+
+ /// <summary>
+ /// Reinterprets the bits of the given vector into those of a vector of 64-bit floating point numbers.
+ /// </summary>
+ /// <param name="value">The source vector</param>
+ /// <returns>The reinterpreted vector.</returns>
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ public static Vector<Double> AsVectorDouble<T>(Vector<T> value) where T : struct
+ {
+ return (Vector<Double>)value;
+ }
+ #endregion Conversion Methods
+ }
+}
--- /dev/null
+SR.cs
+System.Numerics/ConstantHelper.cs
+System.Numerics/HashCodeHelper.cs
+System.Numerics/JitIntrinsicAttribute.cs
+System.Numerics/Register.cs
+System.Numerics/Vector_Operations.cs
+System.Numerics/Vector.cs
--- /dev/null
+#include System.Numerics.Vectors.dll.sources
--- /dev/null
+//
+// AssemblyInfo.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.Reflection.Context.dll")]
+[assembly: AssemblyDescription ("System.Reflection.Context.dll")]
+[assembly: AssemblyDefaultAlias ("System.Reflection.Context.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile("../msfinal.pub")]
+
+[assembly: SecurityCritical]
+
+[assembly: ComVisible (false)]
\ No newline at end of file
--- /dev/null
+thisdir = class/System.Reflection.Context
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.Reflection.Context.dll
+LIB_REFS = System
+LIB_MCS_FLAGS =
+
+NO_TEST = yes
+
+include ../../build/library.make
--- /dev/null
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+Assembly/AssemblyInfo.cs
+System.Reflection.Context/CustomReflectionContext.cs
--- /dev/null
+//
+// CustomReflectionContext.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace System.Reflection.Context
+{
+ public abstract class CustomReflectionContext : ReflectionContext
+ {
+ [MonoTODO]
+ protected CustomReflectionContext ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected CustomReflectionContext (ReflectionContext source)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual IEnumerable<PropertyInfo> AddProperties (Type type)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected PropertyInfo CreateProperty (Type propertyType, string name, Func<object, object> getter, Action<object, object> setter)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected PropertyInfo CreateProperty (Type propertyType, string name, Func<object, object> getter, Action<object, object> setter, IEnumerable<Attribute> propertyCustomAttributes, IEnumerable<Attribute> getterCustomAttributes, IEnumerable<Attribute> setterCustomAttributes)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual IEnumerable<object> GetCustomAttributes (MemberInfo member, IEnumerable<object> declaredAttributes)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected virtual IEnumerable<object> GetCustomAttributes (ParameterInfo parameter, IEnumerable<object> declaredAttributes)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override Assembly MapAssembly (Assembly assembly)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override TypeInfo MapType (TypeInfo type)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
--- /dev/null
+//
+// AssemblyInfo.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.Reflection.DispatchProxy.dll")]
+[assembly: AssemblyDescription ("System.Reflection.DispatchProxy.dll")]
+[assembly: AssemblyDefaultAlias ("System.Reflection.DispatchProxy.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile("../msfinal.pub")]
+
+[assembly: SecurityCritical]
+
+[assembly: ComVisible (false)]
\ No newline at end of file
--- /dev/null
+thisdir = class/System.Reflection.DispatchProxy
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.Reflection.DispatchProxy.dll
+LIB_REFS = System
+LIB_MCS_FLAGS =
+
+NO_TEST = yes
+
+include ../../build/library.make
--- /dev/null
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+Assembly/AssemblyInfo.cs
+System.Reflection/DispatchProxy.cs
--- /dev/null
+//
+// DispatchProxy.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Reflection
+{
+ public abstract class DispatchProxy
+ {
+ [MonoTODO]
+ protected DispatchProxy()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static T Create<T, TProxy> () where TProxy : DispatchProxy
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected abstract object Invoke (MethodInfo targetMethod, object[] args);
+ }
+}
-//
-// ProtectedData.cs: Protect (encrypt) data without (user involved) key management
-//
+//\r
+// ProtectedData.cs: Protect (encrypt) data without (user involved) key management\r
+//\r
// Author:\r
// Sebastien Pouliot <sebastien@ximian.com>\r
-//
+//\r
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)\r
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)\r
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+// \r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
\r
using System.Runtime.InteropServices;\r
-using System.Security.Permissions;
-
-using Mono.Security.Cryptography;
-
-namespace System.Security.Cryptography {
-
- // References:
- // a. Windows Data Protection
- // http://msdn.microsoft.com/library/en-us/dnsecure/html/windataprotection-dpapi.asp?frame=true
-
- public sealed class ProtectedData {
-
- private ProtectedData ()
- {
- }
-
+using System.Security.Permissions;\r
+\r
+using Mono.Security.Cryptography;\r
+\r
+namespace System.Security.Cryptography {\r
+\r
+ // References:\r
+ // a. Windows Data Protection\r
+ // http://msdn.microsoft.com/library/en-us/dnsecure/html/windataprotection-dpapi.asp?frame=true\r
+\r
+ public sealed class ProtectedData {\r
+\r
+ private ProtectedData ()\r
+ {\r
+ }\r
+\r
// FIXME [DataProtectionPermission (SecurityAction.Demand, ProtectData = true)]\r
- public static byte[] Protect (byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
- {
- if (userData == null)
- throw new ArgumentNullException ("userData");
-
+ public static byte[] Protect (byte[] userData, byte[] optionalEntropy, DataProtectionScope scope) \r
+ {\r
+ if (userData == null)\r
+ throw new ArgumentNullException ("userData");\r
+\r
// on Windows this is supported only under 2000 and later OS\r
Check (scope);\r
\r
switch (impl) {\r
+#if !MOBILE\r
case DataProtectionImplementation.ManagedProtection:\r
try {\r
return ManagedProtection.Protect (userData, optionalEntropy, scope);\r
string msg = Locale.GetText ("Data protection failed.");\r
throw new CryptographicException (msg, e);\r
}\r
+#endif\r
default:\r
throw new PlatformNotSupportedException ();\r
}\r
}\r
\r
// FIXME [DataProtectionPermission (SecurityAction.Demand, UnprotectData = true)]\r
- public static byte[] Unprotect (byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope)
- {
- if (encryptedData == null)
- throw new ArgumentNullException ("encryptedData");
-
+ public static byte[] Unprotect (byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope) \r
+ {\r
+ if (encryptedData == null)\r
+ throw new ArgumentNullException ("encryptedData");\r
+\r
// on Windows this is supported only under 2000 and later OS\r
Check (scope);\r
\r
switch (impl) {\r
+#if !MOBILE\r
case DataProtectionImplementation.ManagedProtection:\r
try {\r
return ManagedProtection.Unprotect (encryptedData, optionalEntropy, scope);\r
string msg = Locale.GetText ("Data unprotection failed.");\r
throw new CryptographicException (msg, e);\r
}\r
+#endif\r
default:\r
throw new PlatformNotSupportedException ();\r
}\r
- }
-
+ }\r
+\r
// private stuff\r
\r
enum DataProtectionImplementation {\r
throw new PlatformNotSupportedException ();\r
}\r
}\r
- }
-}
-
+ }\r
+}\r
+\r
--- /dev/null
+Assembly/AssemblyInfo.cs
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+System.Security.Cryptography/CryptographicAttribute.cs
+System.Security.Cryptography/CryptographicAttributeCollection.cs
+System.Security.Cryptography/CryptographicAttributeEnumerator.cs
+System.Security.Cryptography/DataProtectionScope.cs
+System.Security.Cryptography/ProtectedData.cs
+System.Security.Cryptography.Pkcs/AlgorithmIdentifier.cs
+System.Security.Cryptography.Pkcs/CmsRecipient.cs
+System.Security.Cryptography.Pkcs/CmsRecipientCollection.cs
+System.Security.Cryptography.Pkcs/CmsRecipientEnumerator.cs
+System.Security.Cryptography.Pkcs/ContentInfo.cs
+System.Security.Cryptography.Pkcs/EnvelopedCms.cs
+System.Security.Cryptography.Pkcs/KeyAgreeRecipientInfo.cs
+System.Security.Cryptography.Pkcs/KeyTransRecipientInfo.cs
+System.Security.Cryptography.Pkcs/Pkcs9Attribute.cs
+System.Security.Cryptography.Pkcs/Pkcs9ContentType.cs
+System.Security.Cryptography.Pkcs/Pkcs9DocumentDescription.cs
+System.Security.Cryptography.Pkcs/Pkcs9DocumentName.cs
+System.Security.Cryptography.Pkcs/Pkcs9MessageDigest.cs
+System.Security.Cryptography.Pkcs/Pkcs9SigningTime.cs
+System.Security.Cryptography.Pkcs/PublicKeyInfo.cs
+System.Security.Cryptography.Pkcs/RecipientInfo.cs
+System.Security.Cryptography.Pkcs/RecipientInfoCollection.cs
+System.Security.Cryptography.Pkcs/RecipientInfoEnumerator.cs
+System.Security.Cryptography.Pkcs/RecipientInfoType.cs
+System.Security.Cryptography.Pkcs/SubjectIdentifier.cs
+System.Security.Cryptography.Pkcs/SubjectIdentifierOrKey.cs
+System.Security.Cryptography.Pkcs/SubjectIdentifierOrKeyType.cs
+System.Security.Cryptography.Pkcs/SubjectIdentifierType.cs
+System.Security.Cryptography.Xml/X509IssuerSerial.cs
+
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
--- /dev/null
+#include common_System.Security.dll.sources
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Xml;
+#if !MOBILE && !XAMMAC_4_5
using WS = System.Web.Services.Description;
+#endif
namespace System.ServiceModel.Channels
{
return false;
}
+#if !MOBILE && !XAMMAC_4_5
public override bool CanBuildChannelListener<TChannel> (
BindingContext context)
{
}
return false;
}
+#endif
public override T GetProperty<T> (BindingContext context)
{
return base.GetProperty<T> (context);
}
+#if !MOBILE && !XAMMAC_4_5
void IWsdlExportExtension.ExportContract (WsdlExporter exporter,
WsdlContractConversionContext context)
{
transfer_mode == TransferMode.StreamedResponse)
assertions.Add (doc.CreateElement ("msf", "Streamed", "http://schemas.microsoft.com/ws/2006/05/framing/policy"));
}
+#endif
}
}
{
public SslStreamSecurityBindingElement ()
{
+#if !MOBILE && !XAMMAC_4_5
verifier = IdentityVerifier.CreateDefault ();
+#endif
}
+#if !MOBILE && !XAMMAC_4_5
IdentityVerifier verifier;
- bool require_client_certificate;
public IdentityVerifier IdentityVerifier {
get { return verifier; }
set { verifier = value; }
}
+#endif
+
+ bool require_client_certificate;
public bool RequireClientCertificate {
get { return require_client_certificate; }
SslStreamSecurityBindingElement other)
: base (other)
{
+#if !MOBILE && !XAMMAC_4_5
verifier = other.verifier;
+#endif
require_client_certificate = other.require_client_certificate;
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
public StreamUpgradeProvider BuildClientStreamUpgradeProvider (BindingContext context)
{
"msf", "SslTransportSecurity", PolicyImportHelper.FramingPolicyNS);
return element;
}
+#endif
[MonoTODO]
public override IChannelFactory<TChannel>
throw new NotImplementedException ();
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
public override IChannelListener<TChannel>
BuildChannelListener<TChannel> (
{
throw new NotImplementedException ();
}
+#endif
[MonoTODO]
public override bool CanBuildChannelFactory<TChannel> (
throw new NotImplementedException ();
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
public override bool CanBuildChannelListener<TChannel> (
BindingContext context)
{
throw new NotImplementedException ();
}
+#endif
public override BindingElement Clone ()
{
throw new NotImplementedException ();
}
+#if !MOBILE && !XAMMAC_4_5
#region explicit interface implementations
[MonoTODO]
void IPolicyExportExtension.ExportPolicy (
context.GetBindingAssertions ().Add (transportBinding);
}
#endregion
+#endif
}
}
using System.Collections.Generic;
using System.Net;
using System.ServiceModel.Channels;
+#if !MOBILE && !XAMMAC_4_5
using System.ServiceModel.Channels.NetTcp;
+#endif
using System.ServiceModel.Description;
namespace System.ServiceModel.Channels
{
if (!CanBuildChannelFactory<TChannel> (context))
throw new InvalidOperationException (String.Format ("Not supported channel factory type '{0}'", typeof (TChannel)));
+
+#if !MOBILE && !XAMMAC_4_5
return new TcpChannelFactory<TChannel> (this, context);
+#else
+ throw new NotImplementedException ();
+#endif
}
+#if !MOBILE && !XAMMAC_4_5
public override IChannelListener<TChannel>
BuildChannelListener<TChannel> (
BindingContext context)
throw new InvalidOperationException (String.Format ("Not supported channel listener type '{0}'", typeof (TChannel)));
return new TcpChannelListener<TChannel> (this, context);
}
+#endif
public override BindingElement Clone ()
{
max_recv_message_size = other.max_recv_message_size;
}
- public bool ManualAddressing {
+ public virtual bool ManualAddressing {
get { return manual_addressing; }
set { manual_addressing = value; }
}
return context.BuildInnerChannelFactory<TChannel> ();
}
+#if !MOBILE && !XAMMAC_4_5
public override IChannelListener<TChannel>
BuildChannelListener<TChannel> (
BindingContext context)
{
return context.BuildInnerChannelListener<TChannel> ();
}
+#endif
public override bool CanBuildChannelFactory<TChannel> (
BindingContext context)
return context.CanBuildInnerChannelFactory<TChannel> ();
}
+#if !MOBILE && !XAMMAC_4_5
public override bool CanBuildChannelListener<TChannel> (
BindingContext context)
{
return context.CanBuildInnerChannelListener<TChannel> ();
}
+#endif
public override BindingElement Clone ()
{
{
if (typeof (T) == typeof (ISecurityCapabilities))
return (T) (object) this;
+#if !MOBILE && !XAMMAC_4_5
if (typeof (T) == typeof (IdentityVerifier))
return (T) (object) IdentityVerifier.CreateDefault ();
+#endif
return null;
}
get { throw new NotImplementedException (); }
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
void IPolicyExportExtension.ExportPolicy (
MetadataExporter exporter,
element.AppendChild (protectionLevel);
return element;
}
+#endif
#endregion
}
}
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
+#endif
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
+#if !MOBILE && !XAMMAC_4_5
using ReqType = System.ServiceModel.Security.Tokens.ServiceModelSecurityTokenRequirement;
+#endif
namespace System.ServiceModel.Security.Tokens
{
public class SecureConversationSecurityTokenParameters : SecurityTokenParameters
{
+#if !MOBILE && !XAMMAC_4_5
static readonly ChannelProtectionRequirements default_channel_protection_requirements;
+#endif
static readonly BindingContext dummy_context;
static SecureConversationSecurityTokenParameters ()
{
+#if !MOBILE && !XAMMAC_4_5
ChannelProtectionRequirements r =
new ChannelProtectionRequirements ();
r.IncomingSignatureParts.ChannelParts.IsBodyIncluded = true;
r.OutgoingEncryptionParts.ChannelParts.IsBodyIncluded = true;
r.MakeReadOnly ();
default_channel_protection_requirements = r;
+#endif
dummy_context = new BindingContext (
new CustomBinding (),
}
SecurityBindingElement element;
+#if !MOBILE && !XAMMAC_4_5
ChannelProtectionRequirements requirements;
+#endif
bool cancellable;
public SecureConversationSecurityTokenParameters ()
{
}
+#if !MOBILE && !XAMMAC_4_5
public SecureConversationSecurityTokenParameters (
SecurityBindingElement element,
bool requireCancellation,
else
this.requirements = new ChannelProtectionRequirements (requirements);
}
+#else
+ internal SecureConversationSecurityTokenParameters (
+ SecurityBindingElement element,
+ bool requireCancellation,
+ object dummy)
+ {
+ this.element = element;
+ this.cancellable = requireCancellation;
+ }
+#endif
protected SecureConversationSecurityTokenParameters (SecureConversationSecurityTokenParameters source)
: base (source)
{
this.element = (SecurityBindingElement) source.element.Clone ();
this.cancellable = source.cancellable;
+#if !MOBILE && !XAMMAC_4_5
this.requirements = new ChannelProtectionRequirements (default_channel_protection_requirements);
+#endif
}
public bool RequireCancellation {
set { element = value; }
}
+#if !MOBILE && !XAMMAC_4_5
public ChannelProtectionRequirements BootstrapProtectionRequirements {
get { return requirements; }
}
+#endif
// SecurityTokenParameters
return new SecureConversationSecurityTokenParameters (this);
}
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
protected override SecurityKeyIdentifierClause CreateKeyIdentifierClause (
SecurityToken token, SecurityTokenReferenceStyle referenceStyle)
{
throw new NotImplementedException ();
}
-
[MonoTODO]
protected internal override void InitializeSecurityTokenRequirement (SecurityTokenRequirement requirement)
{
requirement.Properties [ReqType.IssuedSecurityTokenParametersProperty] = this.Clone ();
requirement.KeyType = SecurityKeyType.SymmetricKey;
}
+#endif
public override string ToString ()
{
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
+#endif
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
using System.Text;
protected abstract SecurityTokenParameters CloneCore ();
+#if !MOBILE && !XAMMAC_4_5
protected abstract SecurityKeyIdentifierClause CreateKeyIdentifierClause (
SecurityToken token, SecurityTokenReferenceStyle referenceStyle);
}
protected internal abstract void InitializeSecurityTokenRequirement (SecurityTokenRequirement requirement);
+#endif
internal BindingContext IssuerBindingContext {
set { issuer_binding_context = value; }
}
+#if !MOBILE && !XAMMAC_4_5
internal void CallInitializeSecurityTokenRequirement (SecurityTokenRequirement requirement)
{
if (issuer_binding_context != null)
{
throw new NotImplementedException ();
}
+#endif
}
}
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
+#endif
using System.ServiceModel.Security;
namespace System.ServiceModel.Security.Tokens
return new UserNameSecurityTokenParameters (this);
}
+#if !MOBILE && !XAMMAC_4_5
protected override SecurityKeyIdentifierClause CreateKeyIdentifierClause (
SecurityToken token, SecurityTokenReferenceStyle referenceStyle)
{
requirement.TokenType = SecurityTokenTypes.UserName;
requirement.RequireCryptographicToken = true;
}
+#endif
}
}
System.ServiceModel/BasicHttpsBinding.cs
System.ServiceModel/BasicHttpsSecurity.cs
System.ServiceModel/NetHttpBinding.cs
+System.ServiceModel/NetHttpsBinding.cs
System.ServiceModel/NetHttpMessageEncoding.cs
System.ServiceModel.Channels/CompressionFormat.cs
System.ServiceModel.Channels/WebSocketTransportSettings.cs
public BasicHttpsSecurity Security {
get { return security; }
+ set { security = value; }
}
public override BindingElementCollection
public HttpTransportSecurity Transport {
get { return transport; }
+ set { transport = value; }
}
}
}
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
+#if !MOBILE && !XAMMAC_4_5
using System.Transactions;
+#endif
namespace System.ServiceModel
{
MaxItemsInObjectGraph = 0x10000;
UseSynchronizationContext = true;
ValidateMustUnderstand = true;
+#if !MOBILE && !XAMMAC_4_5
TransactionIsolationLevel = IsolationLevel.Unspecified;
+#endif
}
[MonoTODO]
[MonoTODO]
public int MaxItemsInObjectGraph { get; set; }
+#if !MOBILE && !XAMMAC_4_5
[MonoTODO]
public IsolationLevel TransactionIsolationLevel { get; set; }
+#endif
[MonoTODO]
public string TransactionTimeout { get; set; }
//
using System;
using System.Collections.Generic;
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Claims;
+#endif
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
{
public class DnsEndpointIdentity : EndpointIdentity
{
+#if !MOBILE && !XAMMAC_4_5
public DnsEndpointIdentity (Claim identity)
{
Initialize (identity);
: this (Claim.CreateDnsClaim (dns))
{
}
+#else
+ public DnsEndpointIdentity (string dns)
+ {
+ throw new NotImplementedException ();
+ }
+#endif
}
}
// no special magic), we have to use different approach
// that should work either.
object proxy = Activator.CreateInstance (type, new object [] {Endpoint, this, address, via});
-#else
+#elif !MOBILE && !XAMMAC_4_5
object proxy = new ClientRealProxy (typeof (TChannel), new DuplexClientRuntimeChannel (Endpoint, this, address, via), true).GetTransparentProxy ();
+#else
+ object proxy;
+ throw new NotImplementedException ();
#endif
((IDuplexContextChannel) proxy).CallbackInstance = callbackInstance;
} catch (Exception ex) {
// FIXME: log it.
Console.WriteLine (ex);
- } finally {
- // unless it is closed by session/call manager, move it back to the loop to receive the next message.
- if (loop && input.State != CommunicationState.Closed)
- ProcessRequestOrInput (input);
}
}
set { reader_quotas = value; }
}
- public override abstract string Scheme {
+ public override string Scheme {
get;
}
{
public sealed class MessageSecurityOverTcp
{
+#if !MOBILE && !XAMMAC_4_5
SecurityAlgorithmSuite alg_suite;
+#endif
MessageCredentialType client_credential_type;
internal MessageSecurityOverTcp ()
{
+#if !MOBILE && !XAMMAC_4_5
alg_suite = SecurityAlgorithmSuite.Default;
+#endif
// This default value is *silly* but anyways
// such code that does not change this ClientCredentialType
// won't work on Mono.
client_credential_type = MessageCredentialType.Windows;
}
+#if !MOBILE && !XAMMAC_4_5
public SecurityAlgorithmSuite AlgorithmSuite {
get { return alg_suite; }
set { alg_suite = value; }
}
+#endif
public MessageCredentialType ClientCredentialType {
get { return client_credential_type; }
//
using System.Collections.Generic;
using System.Collections.ObjectModel;
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
+#endif
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
{
public abstract class MessageSecurityVersion
{
+#if !MOBILE && !XAMMAC_4_5
// Types
class MessageSecurityTokenVersion : SecurityTokenVersion
{
SecureConversationVersion = SecureConversationVersion.WSSecureConversationFeb2005;
TrustVersion = TrustVersion.WSTrustFeb2005;
}
+ this.SecurityVersion = wss11 ? SecurityVersion.WSSecurity11 : SecurityVersion.WSSecurity10;
}
public override BasicSecurityProfileVersion BasicSecurityProfileVersion {
get { return MessageSecurityTokenVersion.GetVersion (wss11, basic_profile); }
}
- public override SecurityVersion SecurityVersion {
- get { return wss11 ? SecurityVersion.WSSecurity11 : SecurityVersion.WSSecurity10; }
- }
-
public override SecurityPolicyVersion SecurityPolicyVersion {
get { return use2007 ? SecurityPolicyVersion.WSSecurityPolicy12 : SecurityPolicyVersion.WSSecurityPolicy11; }
}
}
+#endif
// Static members
static MessageSecurityVersion ()
{
+#if !MOBILE && !XAMMAC_4_5
wss10_basic = new MessageSecurityVersionImpl (false, true, false);
wss11 = new MessageSecurityVersionImpl (true, false, false);
wss11_basic = new MessageSecurityVersionImpl (true, true, false);
wss10_2007_basic = new MessageSecurityVersionImpl (false, true, true);
wss11_2007_basic = new MessageSecurityVersionImpl (true, true, true);
wss11_2007 = new MessageSecurityVersionImpl (true, false, true);
+#else
+ throw new NotImplementedException ();
+#endif
}
public static MessageSecurityVersion Default {
public abstract BasicSecurityProfileVersion BasicSecurityProfileVersion { get; }
+#if !MOBILE && !XAMMAC_4_5
public abstract SecurityTokenVersion SecurityTokenVersion { get; }
+#endif
- public abstract SecurityVersion SecurityVersion { get; }
+ public SecurityVersion SecurityVersion { get; internal set; }
public SecureConversationVersion SecureConversationVersion { get; internal set; }
--- /dev/null
+// Authors:
+// Martin Baulig (martin.baulig@xamarin.com)
+//
+// Copyright 2012 Xamarin Inc. (http://www.xamarin.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+using System;
+using System.ServiceModel.Channels;
+
+namespace System.ServiceModel {
+ [MonoTODO]
+ public class NetHttpsBinding : HttpBindingBase {
+ public NetHttpsBinding ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public NetHttpsBinding (BasicHttpsSecurityMode securityMode)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public NetHttpsBinding (string configurationName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public NetHttpsBinding (
+ BasicHttpsSecurityMode securityMode, bool reliableSessionEnabled)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public NetHttpMessageEncoding MessageEncoding { get; set; }
+ public OptionalReliableSession ReliableSession { get; set; }
+ public BasicHttpsSecurity Security { get; set; }
+
+ public WebSocketTransportSettings WebSocketSettings {
+ get { throw new NotImplementedException (); }
+ }
+
+ public override string Scheme {
+ get { throw new NotImplementedException (); }
+ }
+
+ public override BindingElementCollection CreateBindingElements ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public bool ShouldSerializeReliableSession ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public bool ShouldSerializeSecurity ()
+ {
+ throw new NotImplementedException ();
+ }
+
+
+
+ }
+}
\ No newline at end of file
XmlDictionaryReaderQuotas reader_quotas
= new XmlDictionaryReaderQuotas ();
bool transaction_flow;
+#if !MOBILE && !XAMMAC_4_5
TransactionProtocol transaction_protocol;
+#endif
TcpTransportBindingElement transport;
public NetTcpBinding ()
public NetTcpBinding (string configurationName)
: this ()
{
+#if !MOBILE && !XAMMAC_4_5
var bindingsSection = ConfigUtil.BindingsSection;
var el = bindingsSection.NetTcpBinding.Bindings [configurationName];
el.ApplyConfiguration (this);
+#else
+ throw new NotImplementedException ();
+#endif
}
internal NetTcpBinding (TcpTransportBindingElement transport,
set { transaction_flow = value; }
}
+#if !MOBILE && !XAMMAC_4_5
public TransactionProtocol TransactionProtocol {
get { return transaction_protocol; }
set { transaction_protocol = value; }
}
+#endif
// overrides
public override BindingElementCollection CreateBindingElements ()
{
+#if !MOBILE && !XAMMAC_4_5
BindingElement tx = new TransactionFlowBindingElement (TransactionProtocol.WSAtomicTransactionOctober2004);
SecurityBindingElement sec = CreateMessageSecurity ();
+#endif
var msg = new BinaryMessageEncodingBindingElement ();
if (ReaderQuotas != null)
ReaderQuotas.CopyTo (msg.ReaderQuotas);
var trsec = CreateTransportSecurity ();
BindingElement tr = GetTransport ();
List<BindingElement> list = new List<BindingElement> ();
+#if !MOBILE && !XAMMAC_4_5
if (tx != null)
list.Add (tx);
if (sec != null)
list.Add (sec);
+#endif
list.Add (msg);
if (trsec != null)
list.Add (trsec);
return transport.Clone ();
}
+#if !MOBILE && !XAMMAC_4_5
// It is problematic, but there is no option to disable establishing security context in this binding unlike WSHttpBinding...
SecurityBindingElement CreateMessageSecurity ()
{
// FIXME: requireCancellation
element, true, reqs);
}
+#endif
BindingElement CreateTransportSecurity ()
{
//
using System;
using System.Collections.Generic;
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Claims;
+#endif
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
{
public class SpnEndpointIdentity : EndpointIdentity
{
+#if !MOBILE && !XAMMAC_4_5
public SpnEndpointIdentity (Claim identity)
{
Initialize (identity);
: this (Claim.CreateSpnClaim (spn))
{
}
+#else
+ public SpnEndpointIdentity (string spn)
+ {
+ throw new NotImplementedException ();
+ }
+#endif
[MonoTODO]
public static TimeSpan SpnLookupTime {
//
using System;
using System.Collections.Generic;
+#if !MOBILE && !XAMMAC_4_5
using System.IdentityModel.Claims;
+#endif
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
{
public class UpnEndpointIdentity : EndpointIdentity
{
+#if !MOBILE && !XAMMAC_4_5
public UpnEndpointIdentity (Claim identity)
{
Initialize (identity);
: this (Claim.CreateUpnClaim (upn))
{
}
+#else
+ public UpnEndpointIdentity (string upn)
+ {
+ throw new NotImplementedException ();
+ }
+#endif
}
}
NUnitMoonHelper.cs
-../../test-helpers/NetworkHelpers.cs
FeatureBased/Features.Client/AsyncCallTesterProxy.cs
FeatureBased/Features.Client/AsyncPatternServer.cs
FeatureBased/Features.Client/DataContractTesterProxy.cs
System.ServiceModel/BasicHttpMessageSecurity.cs
System.ServiceModel/BasicHttpsBinding.cs
System.ServiceModel/BasicHttpsSecurity.cs
+System.ServiceModel/CallbackBehaviorAttribute.cs
System.ServiceModel/ChannelFactory.cs
System.ServiceModel/ChannelFactory_1.cs
System.ServiceModel/ClientBase.cs
System.ServiceModel/DataContractFormatAttribute.cs
System.ServiceModel/DefaultCommunicationTimeouts.cs
System.ServiceModel/Dummy.cs
+System.ServiceModel/DuplexClientBase.cs
+System.ServiceModel/DuplexChannelFactory.cs
System.ServiceModel/EndpointAddress.cs
System.ServiceModel/EndpointAddress10.cs
System.ServiceModel/EndpointAddressBuilder.cs
System.ServiceModel/ICommunicationObject.cs
System.ServiceModel/IContextChannel.cs
System.ServiceModel/IDefaultCommunicationTimeouts.cs
+System.ServiceModel/IDuplexClientChannel.cs
System.ServiceModel/IExtensibleObject.cs
System.ServiceModel/IExtension.cs
System.ServiceModel/IExtensionCollection.cs
System.ServiceModel/MessageParameterAttribute.cs
System.ServiceModel/MessagePropertyAttribute.cs
System.ServiceModel/NetHttpBinding.cs
+System.ServiceModel/NetHttpsBinding.cs
System.ServiceModel/NetHttpMessageEncoding.cs
System.ServiceModel/OperationContext.cs
System.ServiceModel/OperationContextScope.cs
System.ServiceModel/XmlSerializerFormatAttribute.cs
System.ServiceModel.Description/XmlSerializerOperationBehavior.cs
System.ServiceModel.Dispatcher/XmlMessagesFormatter.cs
+
+System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs
+System.ServiceModel.Channels/SslStreamSecurityBindingElement.cs
+System.ServiceModel.Channels/TcpConnectionPoolSettings.cs
+System.ServiceModel.Channels/TcpTransportBindingElement.cs
+System.ServiceModel.Channels/WindowsStreamSecurityBindingElement.cs
+
+System.ServiceModel/MessageSecurityOverTcp.cs
+System.ServiceModel/NetTcpBinding.cs
+System.ServiceModel/NetTcpSecurity.cs
+System.ServiceModel/TcpTransportSecurity.cs
+System.ServiceModel/DnsEndpointIdentity.cs
+System.ServiceModel/SpnEndpointIdentity.cs
+System.ServiceModel/UpnEndpointIdentity.cs
+System.ServiceModel/MessageSecurityVersion.cs
+
+System.ServiceModel.Security/BasicSecurityProfileVersion.cs
+System.ServiceModel.Security/SecurityVersion.cs
+System.ServiceModel.Security/TrustVersion.cs
+System.ServiceModel.Security/SecureConversationVersion.cs
+System.ServiceModel.Security/SecurityPolicyVersion.cs
+
+System.ServiceModel.Security.Tokens/SecurityTokenParameters.cs
+System.ServiceModel.Security.Tokens/SecurityTokenReferenceStyle.cs
+System.ServiceModel.Security.Tokens/SecureConversationSecurityTokenParameters.cs
+System.ServiceModel.Security.Tokens/SupportingTokenParameters.cs
+System.ServiceModel.Security.Tokens/UserNameSecurityTokenParameters.cs
--- /dev/null
+//
+// AssemblyInfo.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.Xml.XPath.XmlDocument.dll")]
+[assembly: AssemblyDescription ("System.Xml.XPath.XmlDocument.dll")]
+[assembly: AssemblyDefaultAlias ("System.Xml.XPath.XmlDocument.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright (Consts.MonoCopyright)]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile("../msfinal.pub")]
+
+[assembly: SecurityCritical]
+
+[assembly: ComVisible (false)]
\ No newline at end of file
--- /dev/null
+thisdir = class/System.Xml.XPath.XmlDocument
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.Xml.XPath.XmlDocument.dll
+LIB_REFS = System System.Xml
+LIB_MCS_FLAGS =
+
+NO_TEST = yes
+
+include ../../build/library.make
--- /dev/null
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+Assembly/AssemblyInfo.cs
+System.Xml/XmlDocumentXPathExtensions.cs
--- /dev/null
+//
+// XmlDocumentXPathExtensions.cs
+//
+// Author:
+// Alexander Köplinger (alexander.koeplinger@xamarin.com)
+//
+// (C) 2016 Xamarin, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.Xml
+{
+ public static class XmlDocumentXPathExtensions
+ {
+ [MonoTODO]
+ public static XmlNodeList SelectNodes (this XmlNode node, string xpath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XmlNodeList SelectNodes (this XmlNode node, string xpath, XmlNamespaceManager nsmgr)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XmlNode SelectSingleNode (this XmlNode node, string xpath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XmlNode SelectSingleNode (this XmlNode node, string xpath, XmlNamespaceManager nsmgr)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XPath.XPathNavigator CreateNavigator (this XmlNode node)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XPath.IXPathNavigable ToXPathNavigable (this XmlNode node)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XPath.XPathNavigator CreateNavigator (this XmlDocument document)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public static XPath.XPathNavigator CreateNavigator (this XmlDocument document, XmlNode node)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
bool result;
#if MONODROID
- result = AndroidPlatform.TrustEvaluateSsl (certs);
- if (result) {
- // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
- // Android (there are no mozroots or preinstalled root certificates),
- // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
- // Android just verified the chain; clear RemoteCertificateChainErrors.
- errors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
+ try {
+ result = AndroidPlatform.TrustEvaluateSsl (certs);
+ if (result) {
+ // FIXME: check whether this is still correct.
+ //
+ // chain.Build() + GetErrorsFromChain() (above) will ALWAYS fail on
+ // Android (there are no mozroots or preinstalled root certificates),
+ // thus `errors` will ALWAYS have RemoteCertificateChainErrors.
+ // Android just verified the chain; clear RemoteCertificateChainErrors.
+ errors &= ~SslPolicyErrors.RemoteCertificateChainErrors;
+ } else {
+ errors |= SslPolicyErrors.RemoteCertificateChainErrors;
+ status11 = unchecked((int)0x800B010B);
+ }
+ } catch {
+ result = false;
+ errors |= SslPolicyErrors.RemoteCertificateChainErrors;
+ status11 = unchecked((int)0x800B010B);
+ // Ignore
}
#else
if (is_macosx) {
InnerList.AddRange (processModules);
}
-#if !NET_2_1
public ProcessModule this[int index] {
get {
return (ProcessModule)InnerList[index];
{
return InnerList.IndexOf (module);
}
-#endif
}
}
InnerList.AddRange (processThreads);
}
-#if !NET_2_1
public ProcessThread this[int index] {
get {
return (ProcessThread)InnerList[index];
{
InnerList.Remove (thread);
}
-#endif
}
}
--- /dev/null
+//
+// FileSystemWatcher.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System.IO
+{
+ public class FileSystemWatcher
+ {
+ public FileSystemWatcher () { throw new NotImplementedException (); }
+ public FileSystemWatcher (string path) { throw new NotImplementedException (); }
+ public FileSystemWatcher (string path, string filter) { throw new NotImplementedException (); }
+ public bool EnableRaisingEvents { get { throw new NotImplementedException (); } set { throw new NotImplementedException (); } }
+ public string Filter { get { throw new NotImplementedException (); } set { } }
+ public bool IncludeSubdirectories { get { throw new NotImplementedException (); } set { } }
+ public int InternalBufferSize { get { throw new NotImplementedException (); } set { } }
+ public NotifyFilters NotifyFilter { get { throw new NotImplementedException (); } set { } }
+ public string Path { get { throw new NotImplementedException (); } set { } }
+ public event FileSystemEventHandler Changed;
+ public event FileSystemEventHandler Created;
+ public event FileSystemEventHandler Deleted;
+ public event ErrorEventHandler Error;
+ public event RenamedEventHandler Renamed;
+ protected void OnChanged (FileSystemEventArgs e) { throw new NotImplementedException (); }
+ protected void OnCreated (FileSystemEventArgs e) { throw new NotImplementedException (); }
+ protected void OnDeleted (System.IO.FileSystemEventArgs e) { throw new NotImplementedException (); }
+ protected void OnError (ErrorEventArgs e) { throw new NotImplementedException (); }
+ protected void OnRenamed (RenamedEventArgs e) { throw new NotImplementedException (); }
+ public WaitForChangedResult WaitForChanged (WatcherChangeTypes changeType) { throw new NotImplementedException (); }
+ public WaitForChangedResult WaitForChanged (WatcherChangeTypes changeType, int timeout) { throw new NotImplementedException (); }
+ }
+}
\ No newline at end of file
EndpointUnavailable = 1001,
ProtocolError = 1002,
InvalidMessageType = 1003,
- Empty,
+ Empty = 1005,
InvalidPayloadData = 1007,
PolicyViolation = 1008,
- MessageTooBig = 1004,
+ MessageTooBig = 1009,
MandatoryExtension = 1010,
- InternalServerError
+ InternalServerError = 1011
}
}
byte [] bytes = null;
MemoryStream ms = GetHeaders (true);
bool chunked = response.SendChunked;
- if (ms != null) {
- long start = ms.Position;
- if (chunked && !trailer_sent) {
- bytes = GetChunkSizeBytes (0, true);
- ms.Position = ms.Length;
- ms.Write (bytes, 0, bytes.Length);
+ if (stream.CanWrite) {
+ try {
+ if (ms != null) {
+ long start = ms.Position;
+ if (chunked && !trailer_sent) {
+ bytes = GetChunkSizeBytes (0, true);
+ ms.Position = ms.Length;
+ ms.Write (bytes, 0, bytes.Length);
+ }
+ InternalWrite (ms.GetBuffer (), (int) start, (int) (ms.Length - start));
+ trailer_sent = true;
+ } else if (chunked && !trailer_sent) {
+ bytes = GetChunkSizeBytes (0, true);
+ InternalWrite (bytes, 0, bytes.Length);
+ trailer_sent = true;
+ }
+ } catch (IOException ex) {
+ // Ignore error due to connection reset by peer
}
- InternalWrite (ms.GetBuffer (), (int) start, (int) (ms.Length - start));
- trailer_sent = true;
- } else if (chunked && !trailer_sent) {
- bytes = GetChunkSizeBytes (0, true);
- InternalWrite (bytes, 0, bytes.Length);
- trailer_sent = true;
}
response.Close ();
}
{
Stream s = null;
lock (this) {
+ if (request.Aborted)
+ throw new WebException ("Request aborted", WebExceptionStatus.RequestCanceled);
if (Data.request != request)
throw new ObjectDisposedException (typeof (NetworkStream).FullName);
if (nstream == null)
{
public enum ChannelBindingKind
{
- Unknown,
- Unique,
- Endpoint
+ Unknown = 0,
+ Unique = 25,
+ Endpoint = 26
}
}
namespace MonoTests.System.Net.Mail
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class SmtpClientTest
{
SmtpClient smtp;
{
[TestFixture]
+[Category ("RequiresBSDSockets")]
public class SslStreamTest {
byte[] m_serverCertRaw = { 48, 130, 5, 165, 2, 1, 3, 48, 130, 5, 95, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 1, 160, 130, 5, 80, 4, 130, 5, 76, 48, 130, 5, 72, 48, 130, 2, 87, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 6, 160, 130, 2, 72, 48, 130, 2, 68, 2, 1, 0, 48, 130, 2, 61, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 1, 48, 28, 6, 10, 42, 134, 72, 134, 247, 13, 1, 12, 1, 3, 48, 14, 4, 8, 211, 176, 234, 3, 252, 26, 32, 15, 2, 2, 7, 208, 128, 130, 2, 16, 183, 149, 35, 180, 127, 95, 163, 122, 138, 244, 29, 177, 220, 173, 46, 73, 208, 217, 211, 190, 164, 183, 21, 110, 33, 122, 98, 163, 251, 16, 23, 106, 154, 14, 52, 177, 3, 12, 248, 226, 48, 123, 211, 6, 216, 6, 192, 175, 203, 142, 141, 143, 252, 178, 7, 162, 81, 232, 159, 42, 56, 177, 191, 53, 7, 146, 189, 236, 75, 140, 210, 143, 11, 103, 64, 58, 10, 73, 123, 39, 97, 119, 166, 114, 123, 65, 68, 214, 42, 17, 156, 122, 8, 58, 184, 134, 255, 48, 64, 20, 229, 247, 196, 12, 130, 56, 176, 69, 179, 254, 216, 45, 25, 244, 240, 116, 88, 137, 66, 13, 18, 202, 199, 59, 200, 245, 19, 175, 232, 217, 211, 12, 191, 222, 26, 162, 253, 73, 201, 48, 61, 3, 248, 117, 16, 71, 233, 183, 90, 110, 91, 116, 56, 133, 223, 148, 19, 78, 140, 123, 159, 203, 78, 15, 172, 39, 190, 39, 71, 180, 155, 48, 156, 116, 212, 52, 1, 231, 201, 196, 73, 87, 68, 104, 208, 40, 104, 32, 218, 235, 245, 84, 136, 168, 51, 9, 93, 126, 46, 80, 180, 240, 144, 79, 88, 87, 159, 24, 108, 186, 9, 20, 48, 100, 148, 250, 4, 163, 115, 131, 44, 13, 38, 222, 117, 196, 196, 128, 114, 149, 97, 93, 37, 191, 3, 192, 231, 88, 80, 218, 147, 8, 192, 165, 27, 206, 56, 42, 157, 230, 223, 130, 253, 169, 182, 245, 192, 181, 18, 212, 133, 168, 73, 92, 66, 197, 117, 245, 107, 127, 23, 146, 249, 41, 66, 219, 210, 207, 221, 205, 205, 15, 110, 92, 12, 207, 76, 239, 4, 13, 129, 127, 170, 205, 253, 148, 208, 24, 129, 24, 210, 220, 85, 45, 179, 137, 66, 134, 142, 22, 112, 48, 160, 236, 232, 38, 83, 101, 55, 51, 18, 110, 99, 69, 41, 173, 107, 233, 11, 199, 23, 61, 135, 222, 94, 74, 29, 219, 80, 128, 167, 186, 254, 235, 42, 96, 134, 5, 13, 90, 59, 231, 137, 195, 207, 28, 165, 12, 218, 5, 72, 102, 61, 135, 198, 73, 250, 97, 89, 214, 179, 244, 194, 23, 142, 157, 4, 243, 90, 69, 54, 10, 139, 76, 95, 40, 225, 219, 59, 15, 54, 182, 206, 142, 228, 248, 79, 156, 129, 246, 63, 6, 6, 236, 44, 67, 116, 213, 170, 47, 193, 186, 139, 25, 80, 166, 57, 99, 231, 156, 191, 117, 65, 76, 7, 243, 244, 127, 225, 210, 190, 164, 141, 46, 36, 99, 111, 203, 133, 127, 80, 28, 61, 160, 36, 132, 182, 16, 41, 39, 185, 232, 123, 32, 57, 189, 100, 152, 38, 205, 5, 189, 240, 65, 3, 191, 73, 85, 12, 209, 180, 1, 194, 70, 124, 57, 71, 48, 230, 235, 122, 175, 157, 35, 233, 83, 40, 20, 169, 224, 14, 11, 216, 48, 194, 105, 25, 187, 210, 182, 6, 184, 73, 95, 85, 210, 227, 113, 58, 10, 186, 175, 254, 25, 102, 39, 3, 2, 200, 194, 197, 200, 224, 77, 164, 8, 36, 114, 48, 130, 2, 233, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 1, 160, 130, 2, 218, 4, 130, 2, 214, 48, 130, 2, 210, 48, 130, 2, 206, 6, 11, 42, 134, 72, 134, 247, 13, 1, 12, 10, 1, 2, 160, 130, 2, 166, 48, 130, 2, 162, 48, 28, 6, 10, 42, 134, 72, 134, 247, 13, 1, 12, 1, 3, 48, 14, 4, 8, 178, 13, 52, 135, 85, 49, 79, 105, 2, 2, 7, 208, 4, 130, 2, 128, 21, 84, 227, 109, 230, 144, 140, 170, 117, 250, 179, 207, 129, 100, 126, 126, 29, 231, 94, 140, 45, 26, 168, 45, 240, 4, 170, 73, 98, 115, 109, 96, 177, 206, 6, 80, 170, 22, 237, 144, 58, 95, 59, 26, 85, 135, 178, 69, 184, 44, 122, 81, 213, 135, 149, 198, 246, 83, 68, 129, 2, 186, 118, 33, 44, 214, 227, 240, 220, 51, 175, 220, 220, 180, 113, 216, 101, 138, 81, 54, 38, 0, 216, 30, 29, 187, 213, 230, 12, 181, 130, 21, 241, 98, 120, 41, 150, 176, 69, 37, 169, 249, 123, 212, 254, 135, 154, 214, 127, 39, 105, 149, 180, 218, 41, 207, 75, 70, 105, 169, 185, 169, 132, 173, 188, 82, 251, 71, 234, 136, 5, 254, 110, 223, 34, 4, 145, 7, 19, 51, 123, 140, 75, 226, 0, 21, 220, 228, 223, 218, 8, 169, 210, 194, 139, 93, 218, 55, 40, 174, 50, 238, 38, 166, 222, 103, 0, 209, 88, 131, 51, 222, 154, 217, 18, 172, 73, 17, 133, 54, 173, 208, 118, 104, 167, 113, 153, 223, 251, 154, 120, 176, 18, 127, 51, 206, 164, 77, 86, 9, 82, 212, 86, 162, 206, 230, 79, 217, 178, 42, 217, 162, 152, 188, 217, 59, 212, 117, 200, 135, 75, 74, 43, 1, 42, 79, 180, 164, 250, 122, 103, 103, 157, 11, 14, 33, 48, 8, 108, 155, 46, 124, 223, 204, 169, 124, 104, 11, 246, 213, 226, 16, 125, 17, 228, 15, 178, 141, 79, 78, 115, 76, 131, 122, 166, 124, 154, 1, 174, 178, 176, 213, 208, 188, 71, 118, 220, 168, 64, 218, 176, 134, 38, 229, 14, 109, 162, 125, 16, 57, 249, 201, 180, 17, 182, 143, 184, 12, 248, 113, 65, 70, 109, 79, 249, 34, 170, 35, 228, 219, 121, 202, 228, 121, 127, 255, 22, 173, 202, 171, 33, 232, 4, 240, 142, 216, 80, 56, 177, 83, 93, 123, 217, 213, 157, 99, 34, 194, 61, 228, 239, 194, 20, 27, 9, 53, 132, 79, 19, 97, 107, 31, 51, 39, 176, 223, 90, 88, 67, 138, 194, 169, 176, 144, 202, 119, 146, 74, 27, 118, 63, 129, 230, 101, 104, 75, 116, 49, 223, 254, 225, 70, 206, 183, 11, 134, 148, 10, 55, 57, 50, 178, 144, 164, 139, 233, 169, 109, 186, 211, 95, 123, 75, 111, 192, 187, 127, 240, 45, 226, 194, 240, 128, 10, 79, 178, 192, 66, 21, 197, 24, 171, 141, 255, 185, 230, 84, 206, 151, 9, 93, 115, 162, 12, 115, 129, 218, 103, 219, 183, 142, 123, 3, 110, 139, 208, 4, 146, 76, 99, 246, 240, 32, 169, 148, 16, 146, 172, 230, 36, 56, 145, 23, 94, 209, 92, 38, 244, 127, 70, 121, 253, 66, 55, 36, 140, 98, 105, 233, 112, 24, 23, 230, 112, 62, 244, 12, 48, 30, 51, 0, 18, 244, 139, 66, 245, 234, 203, 195, 52, 119, 255, 84, 82, 204, 100, 176, 167, 24, 224, 8, 127, 214, 148, 115, 242, 56, 190, 72, 221, 68, 252, 36, 74, 254, 57, 52, 96, 20, 173, 32, 236, 87, 15, 16, 76, 9, 48, 3, 61, 2, 137, 137, 9, 68, 213, 99, 163, 63, 201, 83, 241, 98, 7, 117, 108, 4, 123, 170, 18, 10, 19, 198, 31, 170, 15, 247, 216, 145, 172, 239, 137, 181, 80, 160, 24, 11, 35, 131, 58, 218, 22, 250, 215, 52, 160, 246, 197, 183, 92, 137, 0, 245, 63, 49, 183, 246, 195, 58, 63, 4, 75, 10, 92, 131, 181, 59, 78, 247, 44, 150, 49, 49, 107, 211, 62, 71, 62, 222, 159, 161, 118, 236, 55, 219, 49, 0, 3, 82, 236, 96, 20, 83, 39, 245, 208, 240, 245, 174, 218, 49, 21, 48, 19, 6, 9, 42, 134, 72, 134, 247, 13, 1, 9, 21, 49, 6, 4, 4, 1, 0, 0, 0, 48, 61, 48, 33, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 4, 20, 30, 154, 48, 126, 198, 239, 114, 62, 12, 58, 129, 172, 67, 156, 76, 214, 62, 205, 89, 28, 4, 20, 135, 177, 105, 83, 79, 93, 181, 149, 169, 49, 112, 201, 70, 212, 153, 79, 198, 163, 137, 90, 2, 2, 7, 208 };
namespace MonoTests.System.Net.Sockets
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class NetworkStreamTest
{
[Test]
namespace MonoTests.System.Net.Sockets
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class SocketAcceptAsyncTest
{
[Test]
namespace MonoTests.System.Net.Sockets
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class SocketAsyncTest
{
Socket serverSocket;
namespace MonoTests.System.Net.Sockets
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class SocketTest
{
// note: also used in SocketCas tests
/// Tests System.Net.Sockets.TcpClient
/// </summary>
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class TcpClientTest
{
namespace MonoTests.System.Net.Sockets
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class TcpListenerTest
{
[Test]
namespace MonoTests.System.Net.Sockets {
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class UdpClientTest {
[Test] // .ctor ()
public void Constructor1 ()
namespace MonoTests.System.Net
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class CookieParserTest
{
public const string A = "Foo=Bar, expires=World; expires=Sat, 11-Oct-14 22:45:19 GMT, A=B";
namespace MonoTests.System.Net\r
{\r
[TestFixture]\r
+ [Category ("RequiresBSDSockets")]\r
public class DnsTest\r
{\r
private String site1Name = "google-public-dns-a.google.com",\r
\r
IAsyncResult async = Dns.BeginResolve (site1Dot, null, null);\r
IPHostEntry entry = Dns.EndResolve (async);\r
- SubTestValidIPHostEntry (entry);
+ SubTestValidIPHostEntry (entry);\r
var ip = GetIPv4Address (entry);\r
Assert.AreEqual (site1Dot, ip.ToString ());\r
}\r
{\r
IPAddress addr = new IPAddress (IPAddress.NetworkToHostOrder ((int) site2IP));\r
IPHostEntry h = Dns.GetHostByAddress (addr);\r
- SubTestValidIPHostEntry (h);
+ SubTestValidIPHostEntry (h);\r
var ip = GetIPv4Address (h);\r
Assert.AreEqual (addr.ToString (), ip.ToString ());\r
}\r
namespace MonoTests.System.Net
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class FileWebRequestTest
{
private string _tempDirectory;
namespace MonoTests.System.Net
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class FtpWebRequestTest
{
FtpWebRequest defaultRequest;
namespace MonoTests.System.Net {
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class HttpListener2Test {
private HttpListener _listener = null;
}
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class HttpListenerBugs {
[Test]
public void TestNonChunkedAsync ()
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void AddOne ()
{
HttpListener listener = new HttpListener ();
}
[Test]
+ [Category ("RequiresBSDSockets")]
public void Duplicate ()
{
HttpListener listener = new HttpListener ();
namespace MonoTests.System.Net
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class HttpListenerRequestTest
{
[Test]
namespace MonoTests.System.Net {
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class HttpListenerTest {
int port;
namespace MonoTests.System.Net
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class HttpWebRequestTest
{
private Random rand = new Random ();
}
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class HttpRequestStreamTest
{
[Test]
namespace MonoTests.System.Net
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class HttpWebResponseTest
{
[Test]
}
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class HttpResponseStreamTest
{
[Test]
namespace MonoTests.System.Net
{
[TestFixture]
+ [Category ("RequiresBSDSockets")]
public class WebClientTest
{
private string _tempFolder;
//\r
\r
using NUnit.Framework;\r
+using MonoTests.Helpers;
using System;\r
using System.Net;\r
+using System.Threading;
using System.Collections;\r
using System.Runtime.Serialization;\r
using Socks = System.Net.Sockets;\r
{\r
internal TestWebRequest3 () { }\r
}\r
+
+ [Test] // Covers #41477
+ [Category ("RequiresBSDSockets")]
+ public void TestReceiveCancelation ()
+ {
+ var uri = "http://localhost:" + NetworkHelpers.FindFreePort () + "/";
+
+ HttpListener listener = new HttpListener ();
+ listener.Prefixes.Add (uri);
+ listener.Start ();
+
+ try {
+ for (var i = 0; i < 10; i++) {
+ var request = WebRequest.CreateHttp (uri);
+ request.Method = "GET";
+
+ var tokenSource = new CancellationTokenSource ();
+ tokenSource.Token.Register(() => request.Abort ());
+
+ var responseTask = request.GetResponseAsync ();
+
+ var context = listener.GetContext ();
+ byte[] outBuffer = new byte[8 * 1024];
+ context.Response.OutputStream.WriteAsync (outBuffer, 0, outBuffer.Length);
+
+ Assert.IsTrue (responseTask.Wait (1000), "Timeout #1");
+
+ WebResponse response = responseTask.Result;
+ var stream = response.GetResponseStream ();
+
+ byte[] buffer = new byte[8 * 1024];
+ var taskRead = stream.ReadAsync (buffer, 0, buffer.Length, tokenSource.Token);
+
+ tokenSource.Cancel ();
+
+ Assert.IsTrue (taskRead.Wait (1000), "Timeout #2");
+
+ var byteRead = taskRead.Result;
+ }
+ } catch (AggregateException ex) {
+ var webEx = ex.InnerException as WebException;
+ Assert.IsNotNull(webEx, "Inner exception is not a WebException");
+ Assert.AreEqual (webEx.Status, WebExceptionStatus.RequestCanceled);
+ }
+
+ listener.Close ();
+ }
}\r
\r
}\r
System.IO.Compression/GZipStream.cs
System.IO/InternalBufferOverflowException.cs
System.IO/InvalidDataException.cs
+System.IO/ErrorEventArgs.cs
+System.IO/ErrorEventHandler.cs
+System.IO/FileSystemEventArgs.cs
+System.IO/FileSystemEventHandler.cs
+System.IO/FileSystemWatcher_mobile.cs
+System.IO/NotifyFilters.cs
+System.IO/RenamedEventArgs.cs
+System.IO/RenamedEventHandler.cs
+System.IO/WaitForChangedResult.cs
+System.IO/WatcherChangeTypes.cs
System.Net.Mail/AlternateView.cs
System.Net.Mail/AlternateViewCollection.cs
System.Net.Mail/Attachment.cs
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System;
using System.Runtime.InteropServices;
}
}
-#endif // NET_2_1
-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System;
using System.Runtime.InteropServices;
}
-#endif // NET_2_1
-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System;
using System.IO;
using System.Collections;
namespace Microsoft.Win32
{
+
+#if MOBILE
+ public sealed class RegistryKey : IDisposable
+ {
+ internal RegistryKey (RegistryHive hiveId)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public void Dispose ()
+ {
+ }
+
+ public RegistryKey CreateSubKey (string subkey)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public object GetValue (string name, object defaultValue)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public static object GetValue (string keyName, string valueName, object defaultValue)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public RegistryKey OpenSubKey (string name, bool writable)
+ {
+ throw new PlatformNotSupportedException ();
+ }
+
+ public void SetValue (string name, object value)
+ {
+ }
+
+ public void SetValue (string name, object value, RegistryValueKind valueKind)
+ {
+ }
+
+ // TODO: Finish full contract API
+ }
+#else
/// <summary>
/// Wrapper class for Windows Registry Entry.
/// </summary>
}
}
+#endif
}
-#endif // NET_2_1
-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System.Runtime.InteropServices;
namespace Microsoft.Win32
}
}
-#endif // NET_2_1
-
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !NET_2_1
-
using System;
namespace Microsoft.Win32
}
}
-#endif // NET_2_1
-
//
using System;
+using System.Reflection;
using System.Runtime.CompilerServices;
namespace Mono {
}
}
}
+
+ internal struct RuntimeGenericParamInfoHandle {
+ unsafe RuntimeStructs.GenericParamInfo* value;
+
+ internal unsafe RuntimeGenericParamInfoHandle (RuntimeStructs.GenericParamInfo* value)
+ {
+ this.value = value;
+ }
+
+ internal unsafe RuntimeGenericParamInfoHandle (IntPtr ptr)
+ {
+ this.value = (RuntimeStructs.GenericParamInfo*) ptr;
+ }
+
+
+ internal Type[] Constraints { get { return GetConstraints (); } }
+
+ internal GenericParameterAttributes Attributes {
+ get {
+ unsafe {
+ return (GenericParameterAttributes) value->flags;
+ }
+ }
+ }
+
+ Type[] GetConstraints () {
+ int n = GetConstraintsCount ();
+ var a = new Type[n];
+ for (int i = 0; i < n; i++) {
+ unsafe {
+ RuntimeClassHandle c = new RuntimeClassHandle (value->constraints[i]);
+ a[i] = Type.GetTypeFromHandle (c.GetTypeHandle ());
+ }
+ }
+ return a;
+ }
+
+ int GetConstraintsCount () {
+ int i = 0;
+ unsafe {
+ RuntimeStructs.MonoClass** p = value->constraints;
+ while (p != null && *p != null) {
+ p++; i++;
+ }
+ }
+ return i;
+ }
+ }
+
+ internal struct RuntimeEventHandle {
+ IntPtr value;
+
+ internal RuntimeEventHandle (IntPtr v)
+ {
+ value = v;
+ }
+
+ public IntPtr Value {
+ get {
+ return value;
+ }
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj == null || GetType () != obj.GetType ())
+ return false;
+
+ return value == ((RuntimeEventHandle)obj).Value;
+ }
+
+ public bool Equals (RuntimeEventHandle handle)
+ {
+ return value == handle.Value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return value.GetHashCode ();
+ }
+
+ public static bool operator == (RuntimeEventHandle left, RuntimeEventHandle right)
+ {
+ return left.Equals (right);
+ }
+
+ public static bool operator != (RuntimeEventHandle left, RuntimeEventHandle right)
+ {
+ return !left.Equals (right);
+ }
+ }
+
+ internal struct RuntimePropertyHandle {
+ IntPtr value;
+
+ internal RuntimePropertyHandle (IntPtr v)
+ {
+ value = v;
+ }
+
+ public IntPtr Value {
+ get {
+ return value;
+ }
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj == null || GetType () != obj.GetType ())
+ return false;
+
+ return value == ((RuntimePropertyHandle)obj).Value;
+ }
+
+ public bool Equals (RuntimePropertyHandle handle)
+ {
+ return value == handle.Value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return value.GetHashCode ();
+ }
+
+ public static bool operator == (RuntimePropertyHandle left, RuntimePropertyHandle right)
+ {
+ return left.Equals (right);
+ }
+
+ public static bool operator != (RuntimePropertyHandle left, RuntimePropertyHandle right)
+ {
+ return !left.Equals (right);
+ }
+ }
+
+ internal struct RuntimeGPtrArrayHandle {
+ unsafe RuntimeStructs.GPtrArray* value;
+
+ internal unsafe RuntimeGPtrArrayHandle (RuntimeStructs.GPtrArray* value)
+ {
+ this.value = value;
+ }
+
+ internal unsafe RuntimeGPtrArrayHandle (IntPtr ptr)
+ {
+ this.value = (RuntimeStructs.GPtrArray*) ptr;
+ }
+
+ internal int Length {
+ get {
+ unsafe {
+ return value->len;
+ }
+ }
+ }
+
+ internal IntPtr this[int i] => Lookup (i);
+
+ internal IntPtr Lookup (int i)
+ {
+ if (i >= 0 && i < Length) {
+ unsafe {
+ return value->data[i];
+ }
+ } else
+ throw new IndexOutOfRangeException ();
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ unsafe extern static void GPtrArrayFree (RuntimeStructs.GPtrArray* value, bool freeSeg);
+
+ internal static void DestroyAndFree (ref RuntimeGPtrArrayHandle h, bool freeSeg) {
+ unsafe {
+ GPtrArrayFree (h.value, freeSeg);
+ h.value = null;
+ }
+ }
+ }
}
internal struct MonoClass {
}
+
+ // class-internals.h MonoGenericParamInfo
+ internal unsafe struct GenericParamInfo {
+ internal MonoClass* pklass;
+ internal IntPtr name;
+ internal ushort flags;
+ internal uint token;
+ internal MonoClass** constraints; /* NULL terminated */
+ }
+
+ // glib.h GPtrArray
+ internal unsafe struct GPtrArray {
+ internal IntPtr* data;
+ internal int len;
+ }
}
}
--- /dev/null
+//
+// Safe handle class for Mono.RuntimeGPtrArrayHandle
+//
+// Authors:
+// Aleksey Kliger <aleksey@xamarin.com>
+// Rodrigo Kumpera <kumpera@xamarin.com>
+//
+// Copyright 2016 Dot net foundation.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Mono {
+ internal sealed class SafeGPtrArrayHandle : IDisposable {
+ RuntimeGPtrArrayHandle handle;
+ bool freeSeg;
+
+ internal SafeGPtrArrayHandle (IntPtr ptr, bool freeSeg)
+ {
+ handle = new RuntimeGPtrArrayHandle (ptr);
+ this.freeSeg = freeSeg;
+ }
+
+ ~SafeGPtrArrayHandle ()
+ {
+ Dispose (false);
+ }
+
+ void Dispose (bool disposing)
+ {
+ RuntimeGPtrArrayHandle.DestroyAndFree (ref handle, freeSeg);
+ }
+
+ public void Dispose () {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ internal int Length {
+ get {
+ return handle.Length;
+ }
+ }
+
+ internal IntPtr this[int i] => handle[i];
+ }
+
+
+}
internal static MethodBase GetMethodFromHandleNoGenericCheck (RuntimeMethodHandle handle)
{
- return GetMethodFromHandleInternalType (handle.Value, IntPtr.Zero);
+ return GetMethodFromHandleInternalType_native (handle.Value, IntPtr.Zero, false);
+ }
+
+ internal static MethodBase GetMethodFromHandleNoGenericCheck (RuntimeMethodHandle handle, RuntimeTypeHandle reflectedType)
+ {
+ return GetMethodFromHandleInternalType_native (handle.Value, reflectedType.Value, false);
}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
return GetMethodBodyInternal (handle);
}
+ static MethodBase GetMethodFromHandleInternalType (IntPtr method_handle, IntPtr type_handle) {
+ return GetMethodFromHandleInternalType_native (method_handle, type_handle, true);
+ }
+
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- extern static MethodBase GetMethodFromHandleInternalType (IntPtr method_handle, IntPtr type_handle);
+ internal extern static MethodBase GetMethodFromHandleInternalType_native (IntPtr method_handle, IntPtr type_handle, bool genericCheck);
+
}
-}
\ No newline at end of file
+}
throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
Contract.EndContractBlock();
- Type[] constraints = GetGenericParameterConstraints_impl ();
+ var paramInfo = new Mono.RuntimeGenericParamInfoHandle (RuntimeTypeHandle.GetGenericParameterInfo (this));
+ Type[] constraints = paramInfo.Constraints;
if (constraints == null)
constraints = EmptyArray<Type>.Value;
static extern Type MakeGenericType (Type gt, Type [] types);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type);
+ internal extern IntPtr GetMethodsByName_native (string name, BindingFlags bindingAttr, bool ignoreCase);
+
+ internal RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, RuntimeType reflectedType)
+ {
+ var refh = new RuntimeTypeHandle (reflectedType);
+ using (var h = new Mono.SafeGPtrArrayHandle (GetMethodsByName_native (name, bindingAttr, ignoreCase), false)) {
+ var n = h.Length;
+ var a = new RuntimeMethodInfo [n];
+ for (int i = 0; i < n; i++) {
+ var mh = new RuntimeMethodHandle (h[i]);
+ a[i] = (RuntimeMethodInfo) MethodBase.GetMethodFromHandleNoGenericCheck (mh, refh);
+ }
+ return a;
+ }
+ }
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);
+ extern IntPtr GetPropertiesByName_native (string name, BindingFlags bindingAttr, bool icase);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type);
+ extern IntPtr GetConstructors_native (BindingFlags bindingAttr);
+
+ RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, RuntimeType reflectedType)
+ {
+ var refh = new RuntimeTypeHandle (reflectedType);
+ using (var h = new Mono.SafeGPtrArrayHandle (GetConstructors_native (bindingAttr), false)) {
+ var n = h.Length;
+ var a = new RuntimeConstructorInfo [n];
+ for (int i = 0; i < n; i++) {
+ var mh = new RuntimeMethodHandle (h[i]);
+ a[i] = (RuntimeConstructorInfo) MethodBase.GetMethodFromHandleNoGenericCheck (mh, refh);
+ }
+ return a;
+ }
+ }
+
+ RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, RuntimeType reflectedType)
+ {
+ var refh = new RuntimeTypeHandle (reflectedType);
+ using (var h = new Mono.SafeGPtrArrayHandle (GetPropertiesByName_native (name, bindingAttr, icase), false)) {
+ var n = h.Length;
+ var a = new RuntimePropertyInfo [n];
+ for (int i = 0; i < n; i++) {
+ var ph = new Mono.RuntimePropertyHandle (h[i]);
+ a[i] = (RuntimePropertyInfo) PropertyInfo.GetPropertyFromHandle (ph, refh);
+ }
+ return a;
+ }
+ }
public override InterfaceMapping GetInterfaceMap (Type ifaceType)
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern Type[] GetGenericArgumentsInternal (bool runtimeArray);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern GenericParameterAttributes GetGenericParameterAttributes ();
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern Type[] GetGenericParameterConstraints_impl ();
+ GenericParameterAttributes GetGenericParameterAttributes () {
+ return (new Mono.RuntimeGenericParamInfoHandle (RuntimeTypeHandle.GetGenericParameterInfo (this))).Attributes;
+ }
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern int GetGenericParameterPosition ();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern RuntimeEventInfo[] GetEvents_internal (string name, BindingFlags bindingAttr, Type reflected_type);
+ extern IntPtr GetEvents_native (string name, BindingFlags bindingAttr);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, Type reflected_type);
+ extern IntPtr GetFields_native (string name, BindingFlags bindingAttr);
+
+ RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, RuntimeType reflectedType)
+ {
+ var refh = new RuntimeTypeHandle (reflectedType);
+ using (var h = new Mono.SafeGPtrArrayHandle (GetFields_native (name, bindingAttr), false)) {
+ int n = h.Length;
+ var a = new RuntimeFieldInfo[n];
+ for (int i = 0; i < n; i++) {
+ var fh = new RuntimeFieldHandle (h[i]);
+ a[i] = (RuntimeFieldInfo) FieldInfo.GetFieldFromHandle (fh, refh);
+ }
+ return a;
+ }
+ }
+
+ RuntimeEventInfo[] GetEvents_internal (string name, BindingFlags bindingAttr, RuntimeType reflectedType)
+ {
+ var refh = new RuntimeTypeHandle (reflectedType);
+ using (var h = new Mono.SafeGPtrArrayHandle (GetEvents_native (name, bindingAttr), false)) {
+ int n = h.Length;
+ var a = new RuntimeEventInfo[n];
+ for (int i = 0; i < n; i++) {
+ var eh = new Mono.RuntimeEventHandle (h[i]);
+ a[i] = (RuntimeEventInfo) EventInfo.GetEventFromHandle (eh, refh);
+ }
+ return a;
+ }
+ }
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override Type[] GetInterfaces();
{
public class EventSource : IDisposable
{
+ protected internal struct EventData
+ {
+ public IntPtr DataPointer { get; set; }
+ public int Size { get; set; }
+ }
+
protected EventSource ()
{
this.Name = this.GetType().Name;
using System.Security.Permissions;
using System.Text;
using System.Threading;
+using System.IO;
namespace System.Diagnostics {
readonly StackTrace[] captured_traces;
private bool debug_info;
+ private static Dictionary<string, Func<StackTrace, string>> metadataHandlers;
+
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public StackTrace ()
{
if (!t.AddFrames (sb))
continue;
+ t.AddMetadata (sb);
+
sb.Append (Environment.NewLine);
sb.Append ("--- End of stack trace from previous location where exception was thrown ---");
sb.Append (Environment.NewLine);
}
AddFrames (sb);
+ AddMetadata (sb);
+
return sb.ToString ();
}
+ void AddMetadata (StringBuilder sb)
+ {
+ if (metadataHandlers == null)
+ InitMetadataHandlers ();
+
+ foreach (var handler in metadataHandlers) {
+ var lines = handler.Value (this);
+ using (var reader = new StringReader (lines)) {
+ string line;
+ while ((line = reader.ReadLine()) != null) {
+ sb.AppendLine ();
+ sb.AppendFormat ("[{0}] {1}", handler.Key, line);
+ }
+ }
+ }
+ }
+
internal String ToString (TraceFormat traceFormat)
{
// TODO:
return ToString ();
}
+
+ static void InitMetadataHandlers ()
+ {
+ metadataHandlers = new Dictionary<string, Func<StackTrace, string>> (StringComparer.Ordinal);
+
+ var aotid = Assembly.GetAotId ();
+ if (aotid != null)
+ AddMetadataHandler ("AOTID", st => { return new Guid (aotid).ToString ("N"); });
+
+ AddMetadataHandler ("MVID", st => {
+ var mvidLines = new Dictionary<Guid, List<int>> ();
+ var frames = st.GetFrames ();
+ for (var lineNumber = 0; lineNumber < frames.Length; lineNumber++) {
+ var method = frames[lineNumber].GetMethod ();
+ if (method == null)
+ continue;
+ var mvid = method.Module.ModuleVersionId;
+
+ List<int> lines = null;
+ if (!mvidLines.TryGetValue (mvid, out lines)) {
+ lines = new List<int> ();
+ mvidLines.Add (mvid, lines);
+ }
+
+ lines.Add (lineNumber);
+ }
+
+ var mvids = new List<Guid> (mvidLines.Keys);
+ mvids.Sort ();
+
+ var sb = new StringBuilder ();
+ foreach (var mvid in mvids)
+ sb.AppendLine (string.Format ("{0} {1}", mvid.ToString ("N"), string.Join (",", mvidLines[mvid])));
+
+ return sb.ToString ();
+ });
+ }
+
+ // This method signature should not change, apps can use it with reflection to add custom metadata handlers.
+ private static void AddMetadataHandler (string id, Func<StackTrace, string> handler)
+ {
+ if (metadataHandlers == null)
+ InitMetadataHandlers ();
+
+ metadataHandlers.Add (id, handler);
+ }
}
}
get {
return Thread.CurrentThread.CurrentCulture;
}
+#if NETSTANDARD
+ set {
+ throw new NotImplementedException ();
+ }
+#endif
}
public static CultureInfo CurrentUICulture {
get {
return Thread.CurrentThread.CurrentUICulture;
}
+#if NETSTANDARD
+ set {
+ throw new NotImplementedException ();
+ }
+#endif
}
internal static CultureInfo ConstructCurrentCulture ()
FileShare.None, bufferSize);
}
-#if !NET_2_1
[MonoLimitation ("FileOptions are ignored")]
public static FileStream Create (string path, int bufferSize,
FileOptions options)
{
- return Create (path, bufferSize, options, null);
+ return new FileStream (path, FileMode.Create, FileAccess.ReadWrite,
+ FileShare.None, bufferSize, options);
}
-
+
+#if !NET_2_1
[MonoLimitation ("FileOptions and FileSecurity are ignored")]
public static FileStream Create (string path, int bufferSize,
FileOptions options,
internal static string WindowsDriveAdjustment (string path)
{
- // two special cases to consider when a drive is specified
- if (path.Length < 2)
+ // three special cases to consider when a drive is specified
+ if (path.Length < 2) {
+ if (path.Length == 1 && (path[0] == '\\' || path[0] == '/'))
+ return Path.GetPathRoot(Directory.GetCurrentDirectory());
return path;
+ }
if ((path [1] != ':') || !Char.IsLetter (path [0]))
return path;
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-
-#endif
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
-
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
}
-#endif
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
namespace System.Reflection.Emit {
static class OpCodeNames {
internal static readonly string [] names = {
};
}
}
-#endif
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-#endif
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
}
-#endif
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-
-#endif
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-
-
-#endif
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if !FULL_AOT_RUNTIME || IOS_REFLECTION
using System.Runtime.InteropServices;
namespace System.Reflection.Emit {
}
}
-#endif
--- /dev/null
+//
+// AssemblyExtensions.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NETSTANDARD
+
+namespace System.Reflection.Metadata
+{
+ public static class AssemblyExtensions
+ {
+ //
+ // System.Runtime.Loader netstandard typeforwarders dependency
+ //
+ [CLSCompliant(false)]
+ public unsafe static bool TryGetRawMetadata (this System.Reflection.Assembly assembly, out byte* blob, out int length)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
+#endif
\ No newline at end of file
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern string InternalImageRuntimeVersion ();
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ static internal extern string GetAotId ();
+
// SECURITY: this should be the only caller to icall get_code_base
private string GetCodeBase (bool escaped)
{
get {
return (cultureinfo == null)? null : cultureinfo.Name;
}
+#if NETSTANDARD
+ set {
+ throw new NotImplementedException ();
+ }
+#endif
}
[ComVisibleAttribute(false)]
//
using System.Diagnostics;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System.Reflection {
public virtual MethodInfo RemoveMethod {
get { return GetRemoveMethod (true); }
}
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern EventInfo internal_from_handle_type (IntPtr event_handle, IntPtr type_handle);
+
+ internal static EventInfo GetEventFromHandle (Mono.RuntimeEventHandle handle)
+ {
+ if (handle.Value == IntPtr.Zero)
+ throw new ArgumentException ("The handle is invalid.");
+ return internal_from_handle_type (handle.Value, IntPtr.Zero);
+ }
+
+ internal static EventInfo GetEventFromHandle (Mono.RuntimeEventHandle handle, RuntimeTypeHandle reflectedType)
+ {
+ if (handle.Value == IntPtr.Zero)
+ throw new ArgumentException ("The handle is invalid.");
+ EventInfo ei = internal_from_handle_type (handle.Value, reflectedType.Value);
+ if (ei == null)
+ throw new ArgumentException ("The event handle and the type handle are incompatible.");
+ return ei;
+ }
}
}
throw new NotImplementedException ();
}
#endif
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern PropertyInfo internal_from_handle_type (IntPtr event_handle, IntPtr type_handle);
+
+ internal static PropertyInfo GetPropertyFromHandle (Mono.RuntimePropertyHandle handle, RuntimeTypeHandle reflectedType)
+ {
+ if (handle.Value == IntPtr.Zero)
+ throw new ArgumentException ("The handle is invalid.");
+ PropertyInfo pi = internal_from_handle_type (handle.Value, reflectedType.Value);
+ if (pi == null)
+ throw new ArgumentException ("The property handle and the type handle are incompatible.");
+ return pi;
+ }
}
}
GC.register_ephemeron_array (data);
}
+ ~ConditionalWeakTable ()
+ {
+ }
+
/*LOCKING: _lock must be held*/
void Rehash () {
uint newSize = (uint)HashHelpers.GetPrime ((data.Length << 1) | 1);
--- /dev/null
+//
+// AssemblyLoadContext.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2016 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NETSTANDARD
+
+namespace System.Runtime.Loader
+{
+ //
+ // System.Runtime.Loader netstandard typeforwarders dependency
+ //
+ public abstract class AssemblyLoadContext
+ {
+ protected AssemblyLoadContext ()
+ {
+ }
+
+ public static System.Runtime.Loader.AssemblyLoadContext Default {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public static System.Reflection.AssemblyName GetAssemblyName (string assemblyPath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public static AssemblyLoadContext GetLoadContext (System.Reflection.Assembly assembly)
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected abstract System.Reflection.Assembly Load (System.Reflection.AssemblyName assemblyName);
+
+ public System.Reflection.Assembly LoadFromAssemblyName(System.Reflection.AssemblyName assemblyName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public System.Reflection.Assembly LoadFromAssemblyPath (string assemblyPath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public System.Reflection.Assembly LoadFromNativeImagePath (string nativeImagePath, string assemblyPath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public System.Reflection.Assembly LoadFromStream (System.IO.Stream assembly)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public System.Reflection.Assembly LoadFromStream (System.IO.Stream assembly, System.IO.Stream assemblySymbols)
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected IntPtr LoadUnmanagedDllFromPath (string unmanagedDllPath)
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected virtual IntPtr LoadUnmanagedDll (string unmanagedDllName)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public void SetProfileOptimizationRoot (string directoryPath)
+ {
+ }
+
+ public void StartProfileOptimization (string profile)
+ {
+ }
+
+ public event Func<AssemblyLoadContext, System.Reflection.AssemblyName, System.Reflection.Assembly> Resolving;
+ public event Action<AssemblyLoadContext> Unloading;
+ }
+}
+
+#endif
\ No newline at end of file
+++ /dev/null
-using System;
-using System.Runtime.InteropServices;
-
-namespace Microsoft.Win32.SafeHandles
-{
- public sealed class SafeAccessTokenHandle : SafeHandle
- {
- public override bool IsInvalid {
- get {
- return handle == IntPtr.Zero;
- }
- }
-
- public SafeAccessTokenHandle ()
- : base (IntPtr.Zero, true)
- {
-
- }
-
- protected override bool ReleaseHandle()
- {
- return true;
- }
- }
-}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsGenericTypeDefinition (RuntimeType type);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr GetGenericParameterInfo (RuntimeType type);
+
}
}
public bool IsDaylightSavingTime (DateTimeOffset dateTimeOffset)
{
- throw new NotImplementedException ();
+ return IsDaylightSavingTime (dateTimeOffset.DateTime);
}
internal DaylightTime GetDaylightChanges (int year)
i, root + test [i, 0], ex.GetType ()));
}
}
+
+ // These cases require that we don't pass a root to GetFullPath - it should return the proper drive root.
+ string root4 = Path.GetPathRoot(Directory.GetCurrentDirectory());
+ Assert.AreEqual(root4, Path.GetFullPath(@"\"));
+ Assert.AreEqual(root4, Path.GetFullPath("/"));
}
[Test]
using System.Text;
using System.Diagnostics;
using System.Runtime.ExceptionServices;
+using System.Linq;
using NUnit.Framework;
invoke (456324);
Assert.IsNotNull (ExceptionHandling_Test_Support.Caught, "#1");
- Assert.AreEqual (2, ExceptionHandling_Test_Support.CaughtStackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.None).Length, "#2");
+
+ var lines = ExceptionHandling_Test_Support.CaughtStackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.None);
+ lines = lines.Where (l => !l.StartsWith ("[")).ToArray ();
+ Assert.AreEqual (2, lines.Length, "#2");
var st = new StackTrace (ExceptionHandling_Test_Support.Caught, 0, true);
public static void Handler (Exception e)
{
- var split = e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual (5, split.Length, "#1");
- Assert.IsTrue (split [1].Contains ("---"), "#2");
+ var lines = e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ // Ignore Metadata
+ lines = lines.Where (l => !l.StartsWith ("[")).ToArray ();
+
+ Assert.AreEqual (5, lines.Length, "#1");
+ Assert.IsTrue (lines [1].Contains ("---"), "#2");
}
}
using System.Security.Permissions;
using System.Collections.Generic;
using System.Threading;
+using MonoTests.Helpers;
namespace MonoTests.System.Runtime.CompilerServices {
var cwt = new ConditionalWeakTable <object,object> ();
List<object> keepAlive = null;
List<WeakReference> keys = null;
- Thread t = new Thread (delegate () {
+ FinalizerHelpers.PerformNoPinAction (delegate () {
FillStuff (cwt, out keepAlive, out keys);
});
- t.Start ();
- t.Join ();
GC.Collect ();
cwt.Add (b, new object ());
List<WeakReference> res = null;
- ThreadStart dele = () => { res = FillWithNetwork (cwt); };
- var th = new Thread(dele);
- th.Start ();
- th.Join ();
+ FinalizerHelpers.PerformNoPinAction (() => { res = FillWithNetwork (cwt); });
GC.Collect ();
GC.Collect ();
List<WeakReference> res, res2;
res = res2 = null;
- ThreadStart dele = () => {
+ FinalizerHelpers.PerformNoPinAction (() => {
res = FillWithNetwork2 (cwt);
ForcePromotion ();
k = FillReachable (cwt);
res2 = FillWithNetwork2 (cwt);
- };
-
- var th = new Thread(dele);
- th.Start ();
- th.Join ();
+ });
GC.Collect ();
Assert.Ignore ("Not working on Boehm.");
lock (_lock1) {
var cwt = new ConditionalWeakTable <object,object> ();
- ThreadStart dele = () => { FillWithFinalizable (cwt); };
- var th = new Thread(dele);
- th.Start ();
- th.Join ();
+ FinalizerHelpers.PerformNoPinAction (() => { FillWithFinalizable (cwt); });
GC.Collect ();
GC.Collect ();
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using System.Diagnostics;
+using System.Linq;
namespace MonoTests.System.Runtime.ExceptionServices
{
[Category ("BitcodeNotWorking")]
public class ExceptionDispatchInfoTest
{
+ static string[] GetLines (string str)
+ {
+ var lines = str.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+
+ // Ignore Metadata
+ return lines.Where (l => !l.StartsWith ("[")).ToArray ();
+ }
+
[Test]
public void Capture_InvalidArguments ()
{
ed.Throw ();
Assert.Fail ("#0");
} catch (Exception e) {
- var s = e.StackTrace.Split ('\n');
+ var s = GetLines (e.StackTrace);
Assert.AreEqual (4, s.Length, "#1");
Assert.AreEqual (orig, e, "#2");
Assert.AreNotEqual (orig_stack, e.StackTrace, "#3");
edi.Throw ();
Assert.Fail ("#0");
} catch (OperationCanceledException e) {
- Assert.IsFalse (e.StackTrace.Contains ("---"));
- Assert.AreEqual (2, e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Length);
+ Assert.IsTrue (!e.StackTrace.Contains("---"));
+ var lines = GetLines (e.StackTrace);
+ Assert.AreEqual (2, lines.Length, "#1");
}
}
try {
edi.Throw ();
} catch (Exception ex) {
- var split = ex.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual (4, split.Length, "#1");
- Assert.IsTrue (split [1].Contains ("---"), "#2");
+ var lines = GetLines (ex.StackTrace);
+ Assert.AreEqual (4, lines.Length, "#1");
+ Assert.IsTrue (lines [1].Contains ("---"), "#2");
}
}
try {
edi.Throw ();
} catch (Exception ex) {
- var split = ex.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual (7, split.Length, "#1");
- Assert.IsTrue (split [1].Contains ("---"), "#2");
- Assert.IsTrue (split [4].Contains ("---"), "#3");
+ var lines = GetLines (ex.StackTrace);
+ Assert.AreEqual (7, lines.Length, "#1");
+ Assert.IsTrue (lines [1].Contains ("---"), "#2");
+ Assert.IsTrue (lines [4].Contains ("---"), "#3");
}
}
}
} catch (Exception ex) {
var st = new StackTrace (ex, true);
- var split = st.ToString ().Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- Assert.AreEqual (4, split.Length, "#1");
- Assert.IsTrue (split [1].Contains ("---"), "#2");
+ var lines = GetLines (st.ToString ());
+ Assert.AreEqual (4, lines.Length, "#1");
+ Assert.IsTrue (lines [1].Contains ("---"), "#2");
}
}
}
Assert.IsFalse (tzi.IsDaylightSavingTime (date));
Assert.AreEqual (new TimeSpan (2,0,0), tzi.GetUtcOffset (date));
}
+
+ [Test] //Covers #41349
+ public void TestIsDST_DateTimeOffset ()
+ {
+ TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Athens");
+ var date = new DateTime (2014, 3, 30 , 2, 0, 0);
+ var offset = tzi.GetUtcOffset (date);
+ var dateOffset = new DateTimeOffset (date, offset);
+ Assert.IsFalse (tzi.IsDaylightSavingTime (dateOffset));
+
+ date = new DateTime (2014, 3, 30 , 3, 0, 0);
+ offset = tzi.GetUtcOffset (date);
+ dateOffset = new DateTimeOffset (date, offset);
+ Assert.IsTrue (tzi.IsDaylightSavingTime (dateOffset));
+ }
}
[TestFixture]
Mono/Runtime.cs
Mono/RuntimeStructs.cs
Mono/RuntimeHandles.cs
+Mono/SafeGPtrArrayHandle.cs
Mono/DataConverter.cs
Mono.Interop/ComInteropProxy.cs
Mono.Interop/IDispatch.cs
System.Reflection.Emit/TypeBuilder.cs
System.Reflection.Emit/TypeToken.cs
System.Reflection.Emit/UnmanagedMarshal.cs
+System.Reflection.Metadata/AssemblyExtensions.cs
System.Resources/Win32Resources.cs
System.Runtime/GCLargeObjectHeapCompactionMode.cs
System.Runtime/GCLatencyMode.cs
System.Runtime.Remoting.Services/EnterpriseServicesHelper.cs
System.Runtime.Remoting.Services/ITrackingHandler.cs
System.Runtime.Remoting.Services/TrackingServices.cs
+System.Runtime.Loader/AssemblyLoadContext.cs
System.Runtime.Versioning/CompatibilitySwitch.cs
System.Security/CodeAccessPermission.cs
System.Security/HostProtectionException.cs
System.Security/PermissionBuilder.cs
System.Security/PermissionSet.cs
System.Security/PolicyLevelType.cs
-System.Security/SafeAccessTokenHandle.cs
System.Security/SecureString.cs
System.Security/SecurityElement.cs
System.Security/SecurityFrame.cs
../referencesource/mscorlib/system/security/attributes.cs
../referencesource/mscorlib/system/security/securitycontext.cs
../referencesource/mscorlib/system/security/securitydocument.cs
+../referencesource/mscorlib/system/security/safesecurityhandles.cs
../referencesource/mscorlib/system/security/claims/Claim.cs
../referencesource/mscorlib/system/security/claims/ClaimsIdentity.cs
System/AggregateExceptionTests.cs
System.Threading/ThreadLocalTests.cs
System.Threading/SpinLockTests.cs
-
+../../test-helpers/TestHelpers.cs
public const string Sha512 = "SHA512"; // BCRYPT_SHA512_ALGORITHM
internal const string Rsa = "RSA"; // BCRYPT_RSA_ALGORITHM
}
-
+#if !MONO
/// <summary>
/// Well known key blob tyes
/// </summary>
}
return keyBlob;
}
+#endif
}
}
/// </summary>
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public sealed class CngKey : IDisposable {
+#if MONO
+ public void Dispose() {
+ }
+#else
private SafeNCryptKeyHandle m_keyHandle;
private SafeNCryptProviderHandle m_kspHandle;
Contract.Assert(m_keyHandle != null);
NCryptNative.SetProperty(m_keyHandle, property.Name, property.Value, property.Options);
}
+#endif
}
}
/// </summary>
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public sealed class ECDsaCng : ECDsa {
+#if MONO
+ public override byte[] SignHash(byte[] hash) {
+ throw new NotImplementedException();
+ }
+
+ public override bool VerifyHash(byte[] hash, byte[] signature) {
+ throw new NotImplementedException();
+ }
+#else
private static KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(256, 384, 128), new KeySizes(521, 521, 0) };
private CngKey m_key;
return hasher.HashFinal();
}
}
+ #endif
}
}
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+#if !MONO
using System.Numerics;
+#endif
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
ProtectKey = 0x00000001, // NCRYPT_UI_PROTECT_KEY_FLAG
ForceHighProtection = 0x00000002 // NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG
}
-
+#if !MONO
/// <summary>
/// Native interop with CNG's NCrypt layer. Native definitions are in ncrypt.h
/// </summary>
return error == ErrorCode.Success;
}
}
+#endif
}
{
public sealed class RSACng : RSA
{
+#if MONO
+ public override RSAParameters ExportParameters(bool includePrivateParameters)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void ImportParameters(RSAParameters parameters)
+ {
+ throw new NotImplementedException();
+ }
+#else
+
// See https://msdn.microsoft.com/en-us/library/windows/desktop/bb931354(v=vs.85).aspx
private static KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(512, 16384, 64) };
throw new CryptographicException(SR.GetString(SR.Cryptography_UnsupportedPaddingMode));
}
}
+#endif
}
}
[SecurityCritical]
protected override bool ReleaseHandle()
{
+#if MONO
+ return true;
+#else
return Win32Native.CloseHandle(handle);
+#endif
}
}
--- /dev/null
+../../../mono/mini/TestHelpers.cs
\ No newline at end of file
--- /dev/null
+// CS1644: Feature `interpolated strings' cannot be used because it is not part of the C# 5.0 language specification
+// Line: 9
+// Compiler options: -langversion:5
+
+public class Program
+{
+ public static void Main()
+ {
+ var x = $"I should not compile";
+ }
+}
// InstrToken.cs\r
// Author: Sergey Chaban (serge@wildwestsoftware.com)\r
\r
+#if !MOBILE\r
+\r
using System;\r
using System.Reflection.Emit;\r
\r
}\r
\r
}\r
+\r
+#endif\r
Builder.Save (module.Builder.ScopeName, pekind, machine);
}
} catch (ArgumentOutOfRangeException) {
- Report.Error (16, "Output file `{0}' exceeds the 4GB limit");
+ Report.Error (16, "Output file `{0}' exceeds the 4GB limit", name);
} catch (Exception e) {
Report.Error (16, "Could not write to file `{0}'. {1}", name, e.Message);
}
interpolated_string
: INTERPOLATED_STRING interpolations INTERPOLATED_STRING_END
{
+ if (lang_version < LanguageVersion.V_6)
+ FeatureIsNotAvailable (GetLocation ($1), "interpolated strings");
+
$$ = new InterpolatedString ((StringLiteral) $1, (List<Expression>) $2, (StringLiteral) $3);
}
| INTERPOLATED_STRING_END
{
+ if (lang_version < LanguageVersion.V_6)
+ FeatureIsNotAvailable (GetLocation ($1), "interpolated strings");
+
$$ = new InterpolatedString ((StringLiteral) $1, null, null);
}
;
{ "h|?|help",
"Show this message and exit.",
v => showHelp = v != null },
+ { "contract-api",
+ "Produces contract API with all members at each level of inheritance hierarchy",
+ v => FullAPISet = v != null },
};
var asms = options.Parse (args);
internal static bool AbiMode { get; private set; }
internal static bool FollowForwarders { get; private set; }
+ internal static bool FullAPISet { get; set; }
}
public class Utils {
members.Add (new ConstructorData (writer, ctors));
}
- PropertyDefinition[] properties = GetProperties (type);
+ PropertyDefinition[] properties = GetProperties (type, Driver.FullAPISet);
if (properties.Length > 0) {
Array.Sort (properties, PropertyDefinitionComparer.Default);
members.Add (new PropertyData (writer, properties));
members.Add (new EventData (writer, events));
}
- MethodDefinition [] methods = GetMethods (type);
+ MethodDefinition [] methods = GetMethods (type, Driver.FullAPISet);
if (methods.Length > 0) {
Array.Sort (methods, MethodDefinitionComparer.Default);
members.Add (new MethodData (writer, methods));
}
- internal static PropertyDefinition [] GetProperties (TypeDefinition type) {
- ArrayList list = new ArrayList ();
+ internal static PropertyDefinition [] GetProperties (TypeDefinition type, bool fullAPI) {
+ var list = new List<PropertyDefinition> ();
+
+ var t = type;
+ do {
+ var properties = t.Properties;//type.GetProperties (flags);
+ foreach (PropertyDefinition property in properties) {
+ MethodDefinition getMethod = property.GetMethod;
+ MethodDefinition setMethod = property.SetMethod;
- var properties = type.Properties;//type.GetProperties (flags);
- foreach (PropertyDefinition property in properties) {
- MethodDefinition getMethod = property.GetMethod;
- MethodDefinition setMethod = property.SetMethod;
+ bool hasGetter = (getMethod != null) && MustDocumentMethod (getMethod);
+ bool hasSetter = (setMethod != null) && MustDocumentMethod (setMethod);
- bool hasGetter = (getMethod != null) && MustDocumentMethod (getMethod);
- bool hasSetter = (setMethod != null) && MustDocumentMethod (setMethod);
+ // if neither the getter or setter should be documented, then
+ // skip the property
+ if (hasGetter || hasSetter) {
+
+ if (t != type && list.Any (l => l.Name == property.Name))
+ continue;
- // if neither the getter or setter should be documented, then
- // skip the property
- if (hasGetter || hasSetter) {
- list.Add (property);
+ list.Add (property);
+ }
}
- }
- return (PropertyDefinition []) list.ToArray (typeof (PropertyDefinition));
+ if (!fullAPI)
+ break;
+
+ if (t.IsInterface || t.IsEnum)
+ break;
+
+ if (t.BaseType == null || t.BaseType.FullName == "System.Object")
+ t = null;
+ else
+ t = t.BaseType.Resolve ();
+
+ } while (t != null);
+
+ return list.ToArray ();
}
- private MethodDefinition[] GetMethods (TypeDefinition type)
+ private MethodDefinition[] GetMethods (TypeDefinition type, bool fullAPI)
{
- ArrayList list = new ArrayList ();
+ var list = new List<MethodDefinition> ();
- var methods = type.Methods;//type.GetMethods (flags);
- foreach (MethodDefinition method in methods) {
- if (method.IsSpecialName && !method.Name.StartsWith ("op_", StringComparison.Ordinal))
- continue;
+ var t = type;
+ do {
+ var methods = t.Methods;//type.GetMethods (flags);
+ foreach (MethodDefinition method in methods) {
+ if (method.IsSpecialName && !method.Name.StartsWith ("op_", StringComparison.Ordinal))
+ continue;
- // we're only interested in public or protected members
- if (!MustDocumentMethod(method))
- continue;
+ // we're only interested in public or protected members
+ if (!MustDocumentMethod (method))
+ continue;
+
+ if (t == type && IsFinalizer (method)) {
+ string name = method.DeclaringType.Name;
+ int arity = name.IndexOf ('`');
+ if (arity > 0)
+ name = name.Substring (0, arity);
- if (IsFinalizer (method)) {
- string name = method.DeclaringType.Name;
- int arity = name.IndexOf ('`');
- if (arity > 0)
- name = name.Substring (0, arity);
+ method.Name = "~" + name;
+ }
+
+ // TODO: Better check
+ if (t != type && list.Any (l => l.DeclaringType != method.DeclaringType && l.Name == method.Name && l.Parameters.Count == method.Parameters.Count))
+ continue;
- method.Name = "~" + name;
+ list.Add (method);
}
- list.Add (method);
- }
+ if (!fullAPI)
+ break;
- return (MethodDefinition []) list.ToArray (typeof (MethodDefinition));
+ if (!t.IsInterface || t.IsEnum)
+ break;
+
+ if (t.BaseType == null || t.BaseType.FullName == "System.Object")
+ t = null;
+ else
+ t = t.BaseType.Resolve ();
+
+ } while (t != null);
+
+ return list.ToArray ();
}
static bool IsFinalizer (MethodDefinition method)
public static bool IgnoreVirtualChanges { get; set; }
public static bool IgnoreAddedPropertySetters { get; set; }
+ public static bool IgnoreNonbreaking { get; set; }
+
public static bool Lax;
public static bool Colorize = true;
}
-
class Program {
public static int Main (string[] args)
v => State.IgnoreVirtualChanges = v != null
},
{ "c|colorize:", "Colorize HTML output", v => State.Colorize = string.IsNullOrEmpty (v) ? true : bool.Parse (v) },
- { "x|lax", "Ignore duplicate XML entries", v => State.Lax = true }
+ { "x|lax", "Ignore duplicate XML entries", v => State.Lax = true },
+ { "ignore-nonbreaking", "Ignore all nonbreaking changes", v => State.IgnoreNonbreaking = true }
};
try {
showHelp = true;
}
+ if (State.IgnoreNonbreaking) {
+ State.IgnoreAddedPropertySetters = true;
+ State.IgnoreVirtualChanges = true;
+ State.IgnoreNew.Add (new Regex (".*"));
+ State.IgnoreAdded.Add (new Regex (".*"));
+ }
+
if (showHelp || extra == null || extra.Count < 2 || extra.Count > 3) {
Console.WriteLine (@"Usage: mono-api-html [options] <reference.xml> <assembly.xml> [diff.html]");
Console.WriteLine ();
} else {
file.WriteLine ("<h1>{0}.dll vs {1}.dll</h1>", ac.SourceAssembly, ac.TargetAssembly);
}
- file.WriteLine ("<a href='javascript: hideNonBreakingChanges (); ' class='hide-nonbreaking'>Hide non-breaking changes</a>");
- file.WriteLine ("<a href='javascript: showNonBreakingChanges (); ' class='restore-nonbreaking' style='display: none;'>Show non-breaking changes</a>");
- file.WriteLine ("<br/>");
+ if (!State.IgnoreNonbreaking) {
+ file.WriteLine ("<a href='javascript: hideNonBreakingChanges (); ' class='hide-nonbreaking'>Hide non-breaking changes</a>");
+ file.WriteLine ("<a href='javascript: showNonBreakingChanges (); ' class='restore-nonbreaking' style='display: none;'>Show non-breaking changes</a>");
+ file.WriteLine ("<br/>");
+ }
file.WriteLine ("<div data-is-topmost>");
file.Write (diffHtml);
file.WriteLine ("</div> <!-- end topmost div -->");
Indent ().WriteLine ("}");
}
+ //HACK: we don't have hierarchy information here so just check some basic heuristics for now
+ bool IsBaseChangeCompatible (string source, string target)
+ {
+ if (source == "System.Object")
+ return true;
+ if (source == "System.Exception" && target.EndsWith ("Exception", StringComparison.Ordinal))
+ return true;
+ if (source == "System.EventArgs" && target.EndsWith ("EventArgs", StringComparison.Ordinal))
+ return true;
+ if (source == "System.Runtime.InteropServices.SafeHandle" && target.StartsWith ("Microsoft.Win32.SafeHandles.SafeHandle", StringComparison.Ordinal))
+ return true;
+ return false;
+ }
+
public override void Modified (XElement source, XElement target, ApiChanges diff)
{
// hack - there could be changes that we're not monitoring (e.g. attributes properties)
var sb = source.GetAttribute ("base");
var tb = target.GetAttribute ("base");
- if (sb != tb) {
+ if (sb != tb && !(State.IgnoreNonbreaking && IsBaseChangeCompatible (sb, tb))) {
Output.Write ("Modified base type: ");
Output.WriteLine (new ApiChange ().AppendModified (sb, tb, true).Member.ToString ());
}
void RenderFieldAttributes (FieldAttributes source, FieldAttributes target, ApiChange change)
{
- var srcNotSerialized = (source & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
- var tgtNotSerialized = (target & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
- if (srcNotSerialized != tgtNotSerialized) {
- // this is not a breaking change, so only render it if it changed.
- if (srcNotSerialized) {
- change.AppendRemoved ("[NonSerialized]\n");
- } else {
- change.AppendAdded ("[NonSerialized]\n");
+ if (!State.IgnoreNonbreaking) {
+ var srcNotSerialized = (source & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
+ var tgtNotSerialized = (target & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized;
+ if (srcNotSerialized != tgtNotSerialized) {
+ // this is not a breaking change, so only render it if it changed.
+ if (srcNotSerialized) {
+ change.AppendRemoved ("[NonSerialized]\n");
+ } else {
+ change.AppendAdded ("[NonSerialized]\n");
+ }
}
}
void Modify (ApiChanges modified)
{
foreach (var changes in modified) {
+ if (State.IgnoreNonbreaking && changes.Value.All (c => !c.Breaking))
+ continue;
Output.WriteLine ("<p>{0}:</p>", changes.Key);
Output.WriteLine ("<pre>");
foreach (var element in changes.Value) {
+ if (State.IgnoreNonbreaking && !element.Breaking)
+ continue;
Output.Write ("<div {0}>", element.Breaking ? "data-is-breaking" : "data-is-non-breaking");
foreach (var line in element.Member.ToString ().Split ('\n'))
Output.WriteLine ("\t{0}", line);
if (State.IgnoreRemoved.Any (re => re.IsMatch (GetDescription (item))))
continue;
SetContext (item);
+ if (State.IgnoreNonbreaking && !IsBreakingRemoval (item))
+ continue;
if (!r) {
BeforeRemoving (elements);
r = true;
if (tgtAbstract) {
change.AppendAdded ("abstract", true).Append (" ");
} else if (srcWord != tgtWord) {
- if (!tgtFinal)
- change.AppendModified (srcWord, tgtWord, breaking).Append (" ");
+ if (!tgtFinal) {
+ if (State.IgnoreVirtualChanges) {
+ change.HasIgnoredChanges = true;
+ } else {
+ change.AppendModified (srcWord, tgtWord, breaking).Append (" ");
+ }
+ }
} else if (tgtWord.Length > 0) {
change.Append (tgtWord).Append (" ");
} else if (srcWord.Length > 0) {
if (tgtFinal) {
change.Append ("final ");
} else {
- change.AppendRemoved ("final", false).Append (" "); // removing 'final' is not a breaking change.
+ if (srcVirtual && !tgtVirtual && State.IgnoreVirtualChanges) {
+ change.HasIgnoredChanges = true;
+ } else {
+ change.AppendRemoved ("final", false).Append (" "); // removing 'final' is not a breaking change.
+ }
}
} else {
if (tgtFinal && srcVirtual) {
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
-namespace Symbolicate
+namespace Mono
{
- class LocationProvider {
- class AssemblyLocationProvider {
- AssemblyDefinition assembly;
- string seqPointDataPath;
-
- public AssemblyLocationProvider (AssemblyDefinition assembly, string seqPointDataPath)
- {
- this.assembly = assembly;
- this.seqPointDataPath = seqPointDataPath;
- }
+ class AssemblyLocationProvider
+ {
+ AssemblyDefinition assembly;
+ Logger logger;
- public SequencePoint TryGetLocation (string typeFullName, string methodSignature, int offset, bool isOffsetIL, uint methodIndex)
- {
- if (!assembly.MainModule.HasSymbols)
- return null;
+ public AssemblyLocationProvider (string assemblyPath, Logger logger)
+ {
+ assemblyPath = Path.GetFullPath (assemblyPath);
+ this.logger = logger;
- TypeDefinition type = null;
- var nested = typeFullName.Split ('+');
- var types = assembly.MainModule.Types;
- foreach (var ntype in nested) {
- type = types.FirstOrDefault (t => t.Name == ntype);
- if (type == null)
- return null;
+ if (!File.Exists (assemblyPath))
+ throw new ArgumentException ("assemblyPath does not exist: "+ assemblyPath);
+
+ var readerParameters = new ReaderParameters { ReadSymbols = true };
+ assembly = AssemblyDefinition.ReadAssembly (assemblyPath, readerParameters);
+ }
- types = type.NestedTypes;
+ public bool TryResolveLocation (StackFrameData sfData, SeqPointInfo seqPointInfo)
+ {
+ if (!assembly.MainModule.HasSymbols)
+ return false;
+
+ TypeDefinition type = null;
+ var nested = sfData.TypeFullName.Split ('+');
+ var types = assembly.MainModule.Types;
+ foreach (var ntype in nested) {
+ if (type == null) {
+ // Use namespace first time.
+ type = types.FirstOrDefault (t => t.FullName == ntype);
+ } else {
+ type = types.FirstOrDefault (t => t.Name == ntype);
}
- var parensStart = methodSignature.IndexOf ('(');
- var methodName = methodSignature.Substring (0, parensStart).TrimEnd ();
- var methodParameters = methodSignature.Substring (parensStart);
- var method = type.Methods.FirstOrDefault (m => CompareName (m, methodName) && CompareParameters (m.Parameters, methodParameters));
- if (method == null)
- return null;
-
- int ilOffset = isOffsetIL ? offset : GetILOffsetFromFile (method.MetadataToken.ToInt32 (), methodIndex, offset);
- if (ilOffset < 0)
- return null;
-
- SequencePoint sp = null;
- foreach (var instr in method.Body.Instructions) {
- if (instr.SequencePoint != null)
- sp = instr.SequencePoint;
-
- if (instr.Offset >= ilOffset) {
- return sp;
- }
+ if (type == null) {
+ logger.LogWarning ("Could not find type: {0}", ntype);
+ return false;
}
- return null;
+ types = type.NestedTypes;
}
- SeqPointInfo seqPointInfo;
- private int GetILOffsetFromFile (int methodToken, uint methodIndex, int nativeOffset)
- {
- if (seqPointInfo == null)
- seqPointInfo = SeqPointInfo.Read (seqPointDataPath);
-
- return seqPointInfo.GetILOffset (methodToken, methodIndex, nativeOffset);
+ var parensStart = sfData.MethodSignature.IndexOf ('(');
+ var methodName = sfData.MethodSignature.Substring (0, parensStart).TrimEnd ();
+ var methodParameters = sfData.MethodSignature.Substring (parensStart);
+ var method = type.Methods.FirstOrDefault (m => CompareName (m, methodName) && CompareParameters (m.Parameters, methodParameters));
+ if (method == null) {
+ logger.LogWarning ("Could not find method: {0}", methodName);
+ return false;
}
- static bool CompareName (MethodDefinition candidate, string expected)
- {
- if (candidate.Name == expected)
- return true;
-
- if (!candidate.HasGenericParameters)
- return false;
-
- var genStart = expected.IndexOf ('[');
- if (genStart < 0)
- return false;
-
- if (candidate.Name != expected.Substring (0, genStart))
+ int ilOffset;
+ if (sfData.IsILOffset) {
+ ilOffset = sfData.Offset;
+ } else {
+ if (seqPointInfo == null)
return false;
- int arity = 1;
- for (int pos = genStart; pos < expected.Length; ++pos) {
- if (expected [pos] == ',')
- ++arity;
- }
-
- return candidate.GenericParameters.Count == arity;
+ ilOffset = seqPointInfo.GetILOffset (method.MetadataToken.ToInt32 (), sfData.MethodIndex, sfData.Offset);
}
- static bool CompareParameters (Collection<ParameterDefinition> candidate, string expected)
- {
- var builder = new StringBuilder ();
- builder.Append ("(");
-
- for (int i = 0; i < candidate.Count; i++) {
- var parameter = candidate [i];
- if (i > 0)
- builder.Append (", ");
-
- if (parameter.ParameterType.IsSentinel)
- builder.Append ("...,");
-
- var pt = parameter.ParameterType;
- if (!string.IsNullOrEmpty (pt.Namespace)) {
- builder.Append (pt.Namespace);
- builder.Append (".");
- }
+ if (ilOffset < 0)
+ return false;
- FormatElementType (pt, builder);
-
- builder.Append (" ");
- builder.Append (parameter.Name);
+ SequencePoint sp = null;
+ foreach (var instr in method.Body.Instructions) {
+ if (instr.SequencePoint != null)
+ sp = instr.SequencePoint;
+
+ if (instr.Offset >= ilOffset) {
+ sfData.SetLocation (sp.Document.Url, sp.StartLine);
+ return true;
}
+ }
- builder.Append (")");
+ return false;
+ }
- return builder.ToString () == expected;
+ static bool CompareName (MethodDefinition candidate, string expected)
+ {
+ if (candidate.Name == expected)
+ return true;
+
+ if (!candidate.HasGenericParameters)
+ return false;
+
+ var genStart = expected.IndexOf ('[');
+ if (genStart < 0)
+ return false;
+
+ if (candidate.Name != expected.Substring (0, genStart))
+ return false;
+
+ int arity = 1;
+ for (int pos = genStart; pos < expected.Length; ++pos) {
+ if (expected [pos] == ',')
+ ++arity;
}
- static void FormatElementType (TypeReference tr, StringBuilder builder)
- {
- var ts = tr as TypeSpecification;
- if (ts != null) {
- if (ts.IsByReference) {
- FormatElementType (ts.ElementType, builder);
- builder.Append ("&");
- return;
- }
+ return candidate.GenericParameters.Count == arity;
+ }
+
+ static bool CompareParameters (Collection<ParameterDefinition> candidate, string expected)
+ {
+ var builder = new StringBuilder ();
+ builder.Append ("(");
- var array = ts as ArrayType;
- if (array != null) {
- FormatElementType (ts.ElementType, builder);
- builder.Append ("[");
+ for (int i = 0; i < candidate.Count; i++) {
+ var parameter = candidate [i];
+ if (i > 0)
+ builder.Append (", ");
- for (int ii = 0; ii < array.Rank - 1; ++ii) {
- builder.Append (",");
- }
+ if (parameter.ParameterType.IsSentinel)
+ builder.Append ("...,");
- builder.Append ("]");
- return;
- }
+ var pt = parameter.ParameterType;
+ if (!string.IsNullOrEmpty (pt.Namespace)) {
+ builder.Append (pt.Namespace);
+ builder.Append (".");
}
- builder.Append (tr.Name);
+ FormatElementType (pt, builder);
+
+ builder.Append (" ");
+ builder.Append (parameter.Name);
}
- }
- Dictionary<string, AssemblyLocationProvider> assemblies;
- HashSet<string> directories;
+ builder.Append (")");
- public LocationProvider () {
- assemblies = new Dictionary<string, AssemblyLocationProvider> ();
- directories = new HashSet<string> ();
+ return builder.ToString () == expected;
}
- public void AddAssembly (string assemblyPath)
+ static void FormatElementType (TypeReference tr, StringBuilder builder)
{
- assemblyPath = Path.GetFullPath (assemblyPath);
- if (assemblies.ContainsKey (assemblyPath))
- return;
-
- if (!File.Exists (assemblyPath))
- throw new ArgumentException ("assemblyPath does not exist: "+ assemblyPath);
-
- var readerParameters = new ReaderParameters { ReadSymbols = true };
- var assembly = AssemblyDefinition.ReadAssembly (assemblyPath, readerParameters);
-
- var seqPointDataPath = assemblyPath + ".msym";
- if (!File.Exists (seqPointDataPath))
- seqPointDataPath = null;
-
- assemblies.Add (assemblyPath, new AssemblyLocationProvider (assembly, seqPointDataPath));
-
- // TODO: Should use AssemblyName with .net unification rules
- directories.Add (Path.GetDirectoryName (assemblyPath));
-
- foreach (var assemblyRef in assembly.MainModule.AssemblyReferences) {
- string refPath = null;
- foreach (var dir in directories) {
- refPath = Path.Combine (dir, assemblyRef.Name);
- if (File.Exists (refPath))
- break;
- refPath = Path.Combine (dir, assemblyRef.Name + ".dll");
- if (File.Exists (refPath))
- break;
- refPath = Path.Combine (dir, assemblyRef.Name + ".exe");
- if (File.Exists (refPath))
- break;
- refPath = null;
+ var ts = tr as TypeSpecification;
+ if (ts != null) {
+ if (ts.IsByReference) {
+ FormatElementType (ts.ElementType, builder);
+ builder.Append ("&");
+ return;
}
- if (refPath != null)
- AddAssembly (refPath);
- }
- }
- public void AddDirectory (string directory)
- {
- directory = Path.GetFullPath (directory);
- if (!Directory.Exists (directory)) {
- Console.Error.WriteLine ("Directory " + directory + " does not exist.");
- return;
- }
+ var array = ts as ArrayType;
+ if (array != null) {
+ FormatElementType (ts.ElementType, builder);
+ builder.Append ("[");
- directories.Add (directory);
- }
+ for (int ii = 0; ii < array.Rank - 1; ++ii) {
+ builder.Append (",");
+ }
- public SequencePoint TryGetLocation (string typeFullName, string methodSignature, int offset, bool isOffsetIL, uint methodIndex)
- {
- foreach (var assembly in assemblies.Values) {
- var loc = assembly.TryGetLocation (typeFullName, methodSignature, offset, isOffsetIL, methodIndex);
- if (loc != null)
- return loc;
+ builder.Append ("]");
+ return;
+ }
}
- return null;
+ builder.Append (tr.Name);
}
}
}
--- /dev/null
+using System;
+
+namespace Mono
+{
+ public class Logger
+ {
+ public enum Level
+ {
+ Debug = 1,
+ Warning = 2,
+ Error = 3,
+ None = 4,
+ }
+
+ Level level;
+ Action<string> logAction;
+
+ public Logger (Level level, Action<string> logAction)
+ {
+ this.level = level;
+ this.logAction = logAction;
+ }
+
+ public void LogDebug (string str, params string[] vals)
+ {
+ Log (Level.Debug, "Debug: " + str, vals);
+ }
+
+ public void LogWarning (string str, params string[] vals)
+ {
+ Log (Level.Warning, "Warning: " + str, vals);
+ }
+
+ public void LogError (string str, params string[] vals)
+ {
+ Log (Level.Error, "Error: " + str, vals);
+ }
+
+ private void Log (Level msgLevel, string str, params string[] vals)
+ {
+ if ((int) level > (int) msgLevel)
+ return;
+
+ logAction (string.Format (str, vals));
+ }
+ }
+}
+
MONO = MONO_PATH="$(LIB_PATH)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) -O=-inline
-OUT_DIR = Test/out
+MSYM_DIR = $(OUT_DIR)/msymdir
TEST_CS = Test/StackTraceDumper.cs
TEST_EXE = $(OUT_DIR)/StackTraceDumper.exe
-RELEASE_FILE = $(OUT_DIR)/release.out
-SYMBOLICATE_FILE = $(OUT_DIR)/symbolicate.out
+STACKTRACE_FILE = $(OUT_DIR)/stacktrace.out
+SYMBOLICATE_RAW_FILE = $(OUT_DIR)/symbolicate_raw.out
+SYMBOLICATE_RESULT_FILE = $(OUT_DIR)/symbolicate.result
SYMBOLICATE_EXPECTED_FILE = Test/symbolicate.expected
CHECK_DIFF = @\
- MONO_DEBUG=gen-compact-seq-points $(MONO) $(TEST_EXE) > $(RELEASE_FILE); \
- $(MONO) $(LIB_PATH)/$(PROGRAM) $(TEST_EXE) $(RELEASE_FILE) | sed "s/).*Test\//) in /" > $(SYMBOLICATE_FILE); \
- DIFF=$$(diff $(SYMBOLICATE_FILE) $(SYMBOLICATE_EXPECTED_FILE)); \
+ $(MONO) $(TEST_EXE) > $(STACKTRACE_FILE); \
+ $(MONO) $(LIB_PATH)/$(PROGRAM) $(MSYM_DIR) $(STACKTRACE_FILE) > $(SYMBOLICATE_RAW_FILE); \
+ sed "s/) .* in .*\/mcs\//) in mcs\//" $(SYMBOLICATE_RAW_FILE) | sed '/\[MVID\]/d' | sed '/\[AOTID\]/d' > $(SYMBOLICATE_RESULT_FILE); \
+ DIFF=$$(diff $(SYMBOLICATE_RESULT_FILE) $(SYMBOLICATE_EXPECTED_FILE)); \
if [ ! -z "$$DIFF" ]; then \
echo "Symbolicate tests failed."; \
- echo "If $(SYMBOLICATE_FILE) is correct copy it to $(SYMBOLICATE_EXPECTED_FILE)."; \
+ echo "If $(SYMBOLICATE_RESULT_FILE) is correct copy it to $(SYMBOLICATE_EXPECTED_FILE)."; \
echo "Otherwise runtime sequence points need to be fixed."; \
echo "$$DIFF"; \
exit 1; \
fi
-BUILD_TEST_EXE = \
+PREPARE_OUTDIR = @\
rm -rf $(OUT_DIR); \
mkdir -p $(OUT_DIR); \
- $(CSCOMPILE) $(TEST_CS) -out:$(TEST_EXE)
+ mkdir -p $(MSYM_DIR);
+
+COMPILE = \
+ $(CSCOMPILE) $(TEST_CS) -out:$(TEST_EXE); \
+ $(MONO) $(LIB_PATH)/$(PROGRAM) store-symbols $(MSYM_DIR) $(OUT_DIR); \
+ $(MONO) $(LIB_PATH)/$(PROGRAM) store-symbols $(MSYM_DIR) $(LIB_PATH);
check: test-local
AOT_SUPPORTED = $(shell $(MONO) --aot 2>&1 | grep -q "AOT compilation is not supported" && echo 0 || echo 1)
-test-local: all
- $(BUILD_TEST_EXE)
- @echo "Checking $(TEST_EXE) without AOT"
+test-local: test-without-aot test-with-aot test-with-aot-msym
+
+test-without-aot: OUT_DIR = Test/without_aot
+test-without-aot: all
+ @echo "Checking $(TEST_EXE) without AOT in $(OUT_DIR)"
+ $(PREPARE_OUTDIR)
+ $(COMPILE)
$(CHECK_DIFF)
+
+test-with-aot: OUT_DIR = Test/with_aot
+test-with-aot: all
ifeq ($(AOT_SUPPORTED), 1)
- @echo "Checking $(TEST_EXE) with AOT"
- @MONO_DEBUG=gen-compact-seq-points $(MONO) --aot $(TEST_EXE) > /dev/null
+ @echo "Checking $(TEST_EXE) with AOT in $(OUT_DIR)"
+ $(PREPARE_OUTDIR)
+ $(COMPILE)
+ @$(MONO) --aot $(TEST_EXE) > /dev/null
$(CHECK_DIFF)
- @echo "Checking $(TEST_EXE) with AOT (using .msym)"
- $(BUILD_TEST_EXE)
- @MONO_DEBUG=gen-compact-seq-points $(MONO) --aot=gen-seq-points-file $(TEST_EXE) > /dev/null
+endif
+
+test-with-aot-msym: OUT_DIR = Test/with_aot_msym
+test-with-aot-msym: all
+ifeq ($(AOT_SUPPORTED), 1)
+ @echo "Checking $(TEST_EXE) with AOT (using .msym) in $(OUT_DIR)"
+ $(PREPARE_OUTDIR)
+ $(COMPILE)
+ @$(MONO) --aot=msym-dir=$(MSYM_DIR) $(TEST_EXE) > /dev/null
$(CHECK_DIFF)
endif
+++ /dev/null
-Mono Symbolicate Tool - README
-
-Usage
------------------------------
-
-mono-symbolicate exefile stacktracesfile [directories...]
-
-Description
------------------------------
-
-mono-symbolicate is a tool that converts a stack trace with `<filename unknown>:0`
-into one with file names and line numbers.
-
-The output of calling this tool will be the provided stacktracesfile where
-`<filename unknown>:0` parts are replaced by a file name and a line number.
-
-For the tool to work it needs to load referenced assemblies, it will first look
-in the same folder as exefile then from one of the provided directories.
-
-The tool assumes that the folder with a referenced assembly called for example
-name.dll will also include name.dll.mdb, if the referenced assembly is AOT
-compiled then the tool is also expecting to find name.dll.msym.
\ No newline at end of file
--- /dev/null
+Mono Symbolicate Tool - README
+
+Usage
+-----------------------------
+
+```
+mono-symbolicate <msym dir> <input file>
+mono-symbolicate store-symbols <msym dir> [<dir>]+
+```
+
+Description
+-----------------------------
+
+`mono-symbolicate` is a tool that converts a stack trace with `<filename unknown>:0`
+into one with file names and line numbers.
+
+The output of calling this tool will be the provided stacktracesfile where
+`<filename unknown>:0` parts are replaced by a file name and a line number.
+
+The tool uses the AOTID and MVID metadata contained at the end of the stacktraces,
+to retrieve the symbols mapping code into line numbers from a provided symbol directory.
+
+When `mono-symbolicate` is called with a symbol directory and a file containing a stacktrace:
+``` mono-symbolicate <msym dir> <input file> ```
+The tool writes into stdout the file contents while adding file location to stack frames when
+it is possible to symbolicate with the symbols available on the symbol directory.
+
+## Symbol directory
+The symbol directory contains subfolder named as a MVID or AOTID.
+ - MVID subfolders contain .dll/.exe and .mdb files.
+ - AOTID subfolder contain .msym files.
+
+Managed assemblies can be added by calling `mono-symbolicate` with the command `store-symbols`:
+```
+mono-symbolicate store-symbols <msym dir> [<dir>]+
+```
+
+.msym are generated and stored automatically in an AOTID subfolder at the same time the assembly
+is compiled ahead of time, by running a command such as:
+```
+mono --aot=msym-dir=<msym dir>
+```
+
+## Practical example
+
+If you do not have `mono-symbolicate` installed on your system you can set it to the built one by doing:
+```
+alias mono="MONO_PATH=../../class/lib/net_4_x ../../../runtime/mono-wrapper"
+alias mono-symbolicate="mono ../../class/lib/net_4_x/mono-symbolicate.exe"
+```
+
+For the example we will use the csharp file `Test/StackTraceDumper.cs` which contains a program that
+outputs a larger number of stacktraces.
+
+The first step is to compile our program with debug data.
+```
+mkdir example
+mcs -debug -out:example/Program.exe Test/StackTraceDumper.cs
+```
+
+Next we need to create the symbol directory and store all the symbols we might need while symbolicating.
+```
+mkdir example/msym-dir
+mono-symbolicate store-symbols example/msym-dir example
+```
+
+After running `mono-symbolicate store-symbols` command the directory `example/msym-dir` should have a subdirectory
+named as a minified GUID containing the Program.exe and Program.mdb.
+
+If we want to symbolicate the stacktraces containing BCL stack frames we need to add those symbols too.
+```
+mono-symbolicate store-symbols example/msym-dir ../../class/lib/net_4_x
+```
+
+We delete the mdb file so on our next step the generated stack trace won't have line numbers.
+```
+rm example/*.mdb
+```
+
+Now we can run our program and dump its output to `example/out`.
+```
+mono example/Program.exe > example/out
+```
+
+Doing `cat example/out` shows us a large number of stacktraces without any line number.
+
+We can finally run `mono-symbolicate` to replace all the `<filename unknown>:0` with actually useful file names and line numbers.
+```
+mono-symbolicate example/msym-dir example/out
+```
+The previous command should display the same as `cat example/out` but this time with file names and line numbers.
+
using System.IO;
using System.Collections.Generic;
-namespace Symbolicate
+namespace Mono
{
static class BinaryReaderExtensions
{
--- /dev/null
+using System;
+using System.Text.RegularExpressions;
+using System.Globalization;
+
+namespace Mono
+{
+ class StackFrameData
+ {
+ static Regex regex = new Regex (@"\w*at (?<Method>.+) *(\[0x(?<IL>.+)\]|<0x.+ \+ 0x(?<NativeOffset>.+)>( (?<MethodIndex>\d+)|)) in <filename unknown>:0");
+
+ public readonly string TypeFullName;
+ public readonly string MethodSignature;
+ public readonly int Offset;
+ public readonly bool IsILOffset;
+ public readonly uint MethodIndex;
+ public readonly string Line;
+
+ public readonly bool IsValid;
+
+ public string File { get; private set; }
+ public int LineNumber { get; private set; }
+
+ private StackFrameData (string line, string typeFullName, string methodSig, int offset, bool isILOffset, uint methodIndex)
+ {
+ LineNumber = -1;
+
+ Line = line;
+ TypeFullName = typeFullName;
+ MethodSignature = methodSig;
+ Offset = offset;
+ IsILOffset = isILOffset;
+ MethodIndex = methodIndex;
+
+ IsValid = true;
+ }
+
+ private StackFrameData (string line)
+ {
+ LineNumber = -1;
+
+ Line = line;
+ }
+
+ public static bool TryParse (string line, out StackFrameData stackFrame)
+ {
+ stackFrame = null;
+
+ var match = regex.Match (line);
+ if (!match.Success) {
+ if (line.Trim ().StartsWith ("at ", StringComparison.InvariantCulture)) {
+ stackFrame = new StackFrameData (line);
+ return true;
+ }
+ return false;
+ }
+
+ string typeFullName, methodSignature;
+ var methodStr = match.Groups ["Method"].Value.Trim ();
+ if (!ExtractSignatures (methodStr, out typeFullName, out methodSignature))
+ return false;
+
+ var isILOffset = !string.IsNullOrEmpty (match.Groups ["IL"].Value);
+ var offsetVarName = (isILOffset)? "IL" : "NativeOffset";
+ var offset = int.Parse (match.Groups [offsetVarName].Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+
+ uint methodIndex = 0xffffff;
+ if (!string.IsNullOrEmpty (match.Groups ["MethodIndex"].Value))
+ methodIndex = uint.Parse (match.Groups ["MethodIndex"].Value, CultureInfo.InvariantCulture);
+
+ stackFrame = new StackFrameData (line, typeFullName, methodSignature, offset, isILOffset, methodIndex);
+
+ return true;
+ }
+
+ static bool ExtractSignatures (string str, out string typeFullName, out string methodSignature)
+ {
+ var methodNameEnd = str.IndexOf ('(');
+ if (methodNameEnd == -1) {
+ typeFullName = methodSignature = null;
+ return false;
+ }
+
+ var typeNameEnd = str.LastIndexOf ('.', methodNameEnd);
+ if (typeNameEnd == -1) {
+ typeFullName = methodSignature = null;
+ return false;
+ }
+
+ // Adjustment for Type..ctor ()
+ if (typeNameEnd > 0 && str [typeNameEnd - 1] == '.') {
+ --typeNameEnd;
+ }
+
+ typeFullName = str.Substring (0, typeNameEnd);
+ // Remove generic parameters
+ typeFullName = Regex.Replace (typeFullName, @"\[[^\[\]]*\]", "");
+
+ methodSignature = str.Substring (typeNameEnd + 1);
+
+ return true;
+ }
+
+ internal void SetLocation (string file, int lineNumber)
+ {
+ File = file;
+ LineNumber = lineNumber;
+ }
+
+ public override string ToString () {
+ if (Line.Contains ("<filename unknown>:0") && LineNumber != -1)
+ return Line.Replace ("<filename unknown>:0", string.Format ("{0}:{1}", File, LineNumber));
+
+ return Line;
+ }
+ }
+}
--- /dev/null
+using System.Text.RegularExpressions;
+
+namespace Mono
+{
+ class StackTraceMetadata
+ {
+ static Regex regex = new Regex (@"\[(?<Id>.+)\] (?<Value>.+)");
+
+ public readonly string Id;
+ public readonly string Value;
+ public readonly string Line;
+
+ private StackTraceMetadata (string line, string id, string val)
+ {
+ Line = line;
+ Id = id;
+ Value = val;
+ }
+
+ public static bool TryParse (string line, out StackTraceMetadata metadata)
+ {
+ metadata = null;
+
+ var match = regex.Match (line);
+ if (!match.Success)
+ return false;
+
+ string id = match.Groups ["Id"].Value;
+ string val = match.Groups ["Value"].Value;
+
+ metadata = new StackTraceMetadata (line, id, val);
+
+ return true;
+ }
+ }
+}
--- /dev/null
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Collections.Generic;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using Mono.Collections.Generic;
+
+namespace Mono
+{
+ public class SymbolManager
+ {
+ string msymDir;
+ Logger logger;
+
+ public SymbolManager (string msymDir, Logger logger) {
+ this.msymDir = msymDir;
+ this.logger = logger;
+ }
+
+ internal bool TryResolveLocation (StackFrameData sfData, string mvid, string aotid)
+ {
+ if (mvid == null)
+ return false;
+
+ var assemblyLocProvider = GetOrCreateAssemblyLocationProvider (mvid);
+ if (assemblyLocProvider == null)
+ return false;
+
+ SeqPointInfo seqPointInfo = null;
+ if (!sfData.IsILOffset && aotid != null)
+ seqPointInfo = GetOrCreateSeqPointInfo (aotid);
+
+ return assemblyLocProvider.TryResolveLocation (sfData, seqPointInfo);
+ }
+
+ Dictionary<string, AssemblyLocationProvider> assemblies = new Dictionary<string, AssemblyLocationProvider> ();
+
+ private AssemblyLocationProvider GetOrCreateAssemblyLocationProvider (string mvid)
+ {
+ if (assemblies.ContainsKey (mvid))
+ return assemblies[mvid];
+
+ var mvidDir = Path.Combine (msymDir, mvid);
+ if (!Directory.Exists (mvidDir)) {
+ logger.LogWarning ("MVID directory does not exist: {0}", mvidDir);
+ return null;
+ }
+
+ string assemblyPath = null;
+ var exeFiles = Directory.GetFiles (mvidDir, "*.exe");
+ var dllFiles = Directory.GetFiles (mvidDir, "*.dll");
+
+ if (exeFiles.Length + dllFiles.Length != 1) {
+ logger.LogError ("MVID directory should include one assembly: {0}", mvidDir);
+ return null;
+ }
+
+ assemblyPath = (exeFiles.Length > 0)? exeFiles[0] : dllFiles[0];
+
+ var locProvider = new AssemblyLocationProvider (assemblyPath, logger);
+
+ assemblies.Add (mvid, locProvider);
+
+ return locProvider;
+ }
+
+ Dictionary<string, SeqPointInfo> seqPointInfos = new Dictionary<string, SeqPointInfo> ();
+
+ private SeqPointInfo GetOrCreateSeqPointInfo (string aotid)
+ {
+ if (seqPointInfos.ContainsKey (aotid))
+ return seqPointInfos[aotid];
+
+ var aotidDir = Path.Combine (msymDir, aotid);
+ if (!Directory.Exists (aotidDir)) {
+ logger.LogError ("AOTID directory does not exist: {0}", aotidDir);
+ return null;
+ }
+
+ string msymFile = null;
+ var msymFiles = Directory.GetFiles(aotidDir, "*.msym");
+ msymFile = msymFiles[0];
+
+ var seqPointInfo = SeqPointInfo.Read (msymFile);
+
+ seqPointInfos.Add (aotid, seqPointInfo);
+
+ return seqPointInfo;
+ }
+
+ public void StoreSymbols (params string[] lookupDirs)
+ {
+ foreach (var dir in lookupDirs) {
+ var exeFiles = Directory.GetFiles (dir, "*.exe");
+ var dllFiles = Directory.GetFiles (dir, "*.dll");
+ var assemblies = exeFiles.Concat (dllFiles);
+ foreach (var assemblyPath in assemblies) {
+ var mdbPath = assemblyPath + ".mdb";
+ if (!File.Exists (mdbPath)) {
+ logger.LogWarning ("Directory {0} contains {1} but no mdb {2}.", dir, Path.GetFileName (assemblyPath), Path.GetFileName (mdbPath));
+ // assemblies without mdb files are useless
+ continue;
+ }
+
+ var assembly = AssemblyDefinition.ReadAssembly (assemblyPath);
+
+ var mvid = assembly.MainModule.Mvid.ToString ("N");
+ var mvidDir = Path.Combine (msymDir, mvid);
+
+ if (Directory.Exists (mvidDir)) {
+ try {
+ Directory.Delete (mvidDir, true);
+ } catch (DirectoryNotFoundException e) {}
+ }
+
+ Directory.CreateDirectory (mvidDir);
+
+ var mvidAssemblyPath = Path.Combine (mvidDir, Path.GetFileName (assemblyPath));
+ File.Copy (assemblyPath, mvidAssemblyPath);
+
+ var mvidMdbPath = Path.Combine (mvidDir, Path.GetFileName (mdbPath));
+ File.Copy (mdbPath, mvidMdbPath);
+
+ // TODO create MVID dir for non main modules with links to main module MVID
+ }
+ }
+ }
+ }
+}
Catch (() => InnerGenericClass<string>.InnerInnerGenericClass<int>.ThrowException ("Stack trace with 2 inner generic class and generic overload"));
Catch (() => InnerGenericClass<int>.InnerInnerGenericClass<string>.ThrowException ("Stack trace with 2 inner generic class and generic overload"));
+
+ Catch (() => {
+ var d = new Dictionary<string, string> ();
+ d.ContainsKey (null); // ArgumentNullException
+ });
}
public static void Catch (Action action)
System.Exception: Stacktrace with 1 frame
- at StackTraceDumper.Main () in StackTraceDumper.cs:9
+ at StackTraceDumper.Main () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:9
Stacktrace:
- at StackTraceDumper.Main () in StackTraceDumper.cs:9
+ at StackTraceDumper.Main () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:9
System.Exception: Stacktrace with 2 frames
- at StackTraceDumper.<Main>m__0 () in StackTraceDumper.cs:16
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.<Main>m__0 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:16
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper.<Main>m__0 () in StackTraceDumper.cs:16
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.<Main>m__0 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:16
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stacktrace with 3 frames
- at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in StackTraceDumper.cs:78
- at StackTraceDumper.<Main>m__1 () in StackTraceDumper.cs:18
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:83
+ at StackTraceDumper.<Main>m__1 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:18
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in StackTraceDumper.cs:78
- at StackTraceDumper.<Main>m__1 () in StackTraceDumper.cs:18
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:83
+ at StackTraceDumper.<Main>m__1 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:18
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stacktrace with 4 frames
- at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in StackTraceDumper.cs:78
- at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in StackTraceDumper.cs:76
- at StackTraceDumper.<Main>m__2 () in StackTraceDumper.cs:20
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
-Stacktrace:
- at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in StackTraceDumper.cs:78
- at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in StackTraceDumper.cs:76
- at StackTraceDumper.<Main>m__2 () in StackTraceDumper.cs:20
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:83
+ at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:81
+ at StackTraceDumper.<Main>m__2 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:20
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
+Stacktrace:
+ at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:83
+ at StackTraceDumper.ThrowException (System.String message, System.Int32 i) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:81
+ at StackTraceDumper.<Main>m__2 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:20
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack frame with method overload using ref parameter
- at StackTraceDumper.ThrowException (System.String& message) in StackTraceDumper.cs:70
- at StackTraceDumper.<Main>m__3 () in StackTraceDumper.cs:24
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowException (System.String& message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:75
+ at StackTraceDumper.<Main>m__3 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:24
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper.ThrowException (System.String& message) in StackTraceDumper.cs:70
- at StackTraceDumper.<Main>m__3 () in StackTraceDumper.cs:24
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowException (System.String& message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:75
+ at StackTraceDumper.<Main>m__3 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:24
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack frame with method overload using out parameter
- at StackTraceDumper.ThrowException (System.String message, System.Int32& o) in StackTraceDumper.cs:83
- at StackTraceDumper.<Main>m__4 () in StackTraceDumper.cs:29
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowException (System.String message, System.Int32& o) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:88
+ at StackTraceDumper.<Main>m__4 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:29
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper.ThrowException (System.String message, System.Int32& o) in StackTraceDumper.cs:83
- at StackTraceDumper.<Main>m__4 () in StackTraceDumper.cs:29
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowException (System.String message, System.Int32& o) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:88
+ at StackTraceDumper.<Main>m__4 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:29
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack frame with 1 generic parameter
- at StackTraceDumper.ThrowExceptionGeneric[T] (System.String message) in StackTraceDumper.cs:88
- at StackTraceDumper.<Main>m__5 () in StackTraceDumper.cs:32
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowExceptionGeneric[T] (System.String message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:93
+ at StackTraceDumper.<Main>m__5 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:32
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper.ThrowExceptionGeneric[T] (System.String message) in StackTraceDumper.cs:88
- at StackTraceDumper.<Main>m__5 () in StackTraceDumper.cs:32
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowExceptionGeneric[T] (System.String message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:93
+ at StackTraceDumper.<Main>m__5 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:32
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack frame with 2 generic parameters
- at StackTraceDumper.ThrowExceptionGeneric[T1,T2] (System.String message) in StackTraceDumper.cs:108
- at StackTraceDumper.<Main>m__6 () in StackTraceDumper.cs:34
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowExceptionGeneric[T1,T2] (System.String message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:113
+ at StackTraceDumper.<Main>m__6 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:34
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper.ThrowExceptionGeneric[T1,T2] (System.String message) in StackTraceDumper.cs:108
- at StackTraceDumper.<Main>m__6 () in StackTraceDumper.cs:34
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowExceptionGeneric[T1,T2] (System.String message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:113
+ at StackTraceDumper.<Main>m__6 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:34
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack frame with generic method overload
- at StackTraceDumper.ThrowExceptionGeneric[T] (T a1) in StackTraceDumper.cs:93
- at StackTraceDumper.<Main>m__7 () in StackTraceDumper.cs:36
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowExceptionGeneric[T] (T a1) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:98
+ at StackTraceDumper.<Main>m__7 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:36
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper.ThrowExceptionGeneric[T] (T a1) in StackTraceDumper.cs:93
- at StackTraceDumper.<Main>m__7 () in StackTraceDumper.cs:36
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper.ThrowExceptionGeneric[T] (T a1) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:98
+ at StackTraceDumper.<Main>m__7 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:36
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack trace with inner class
- at StackTraceDumper+InnerClass.ThrowException (System.String message) in StackTraceDumper.cs:114
- at StackTraceDumper.<Main>m__8 () in StackTraceDumper.cs:38
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerClass.ThrowException (System.String message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:119
+ at StackTraceDumper.<Main>m__8 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:38
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper+InnerClass.ThrowException (System.String message) in StackTraceDumper.cs:114
- at StackTraceDumper.<Main>m__8 () in StackTraceDumper.cs:38
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerClass.ThrowException (System.String message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:119
+ at StackTraceDumper.<Main>m__8 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:38
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack trace with inner generic class
- at StackTraceDumper+InnerGenericClass`1[T].ThrowException (System.String message) in StackTraceDumper.cs:121
- at StackTraceDumper.<Main>m__9 () in StackTraceDumper.cs:40
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1[T].ThrowException (System.String message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:126
+ at StackTraceDumper.<Main>m__9 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:40
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper+InnerGenericClass`1[T].ThrowException (System.String message) in StackTraceDumper.cs:121
- at StackTraceDumper.<Main>m__9 () in StackTraceDumper.cs:40
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1[T].ThrowException (System.String message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:126
+ at StackTraceDumper.<Main>m__9 () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:40
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Generic to string:string
System.Exception: Stack trace with inner generic class and method generic parameter
- at StackTraceDumper+InnerGenericClass`1[T].ThrowException (System.String message, T arg) in StackTraceDumper.cs:127
- at StackTraceDumper.<Main>m__A () in StackTraceDumper.cs:42
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1[T].ThrowException (System.String message, T arg) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:132
+ at StackTraceDumper.<Main>m__A () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:42
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper+InnerGenericClass`1[T].ThrowException (System.String message, T arg) in StackTraceDumper.cs:127
- at StackTraceDumper.<Main>m__A () in StackTraceDumper.cs:42
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1[T].ThrowException (System.String message, T arg) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:132
+ at StackTraceDumper.<Main>m__A () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:42
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack trace with inner generic class and generic overload
- at StackTraceDumper+InnerGenericClass`1[T].ThrowException[T1] (System.String message, T1 arg) in StackTraceDumper.cs:132
- at StackTraceDumper.<Main>m__B () in StackTraceDumper.cs:44
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1[T].ThrowException[T1] (System.String message, T1 arg) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:137
+ at StackTraceDumper.<Main>m__B () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:44
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper+InnerGenericClass`1[T].ThrowException[T1] (System.String message, T1 arg) in StackTraceDumper.cs:132
- at StackTraceDumper.<Main>m__B () in StackTraceDumper.cs:44
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1[T].ThrowException[T1] (System.String message, T1 arg) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:137
+ at StackTraceDumper.<Main>m__B () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:44
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack trace with 2 inner generic class and generic overload
- at StackTraceDumper+InnerGenericClass`1+InnerInnerGenericClass`1[T,T2].ThrowException (T message) in StackTraceDumper.cs:138
- at StackTraceDumper.<Main>m__C () in StackTraceDumper.cs:46
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1+InnerInnerGenericClass`1[T,T2].ThrowException (T message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:143
+ at StackTraceDumper.<Main>m__C () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:46
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper+InnerGenericClass`1+InnerInnerGenericClass`1[T,T2].ThrowException (T message) in StackTraceDumper.cs:138
- at StackTraceDumper.<Main>m__C () in StackTraceDumper.cs:46
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1+InnerInnerGenericClass`1[T,T2].ThrowException (T message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:143
+ at StackTraceDumper.<Main>m__C () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:46
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
System.Exception: Stack trace with 2 inner generic class and generic overload
- at StackTraceDumper+InnerGenericClass`1+InnerInnerGenericClass`1[T,T2].ThrowException (T2 message) in StackTraceDumper.cs:143
- at StackTraceDumper.<Main>m__D () in StackTraceDumper.cs:48
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at StackTraceDumper+InnerGenericClass`1+InnerInnerGenericClass`1[T,T2].ThrowException (T2 message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:148
+ at StackTraceDumper.<Main>m__D () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:48
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
+Stacktrace:
+ at StackTraceDumper+InnerGenericClass`1+InnerInnerGenericClass`1[T,T2].ThrowException (T2 message) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:148
+ at StackTraceDumper.<Main>m__D () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:48
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
+
+System.ArgumentNullException: Value cannot be null.
+Parameter name: key
+ at System.ThrowHelper.ThrowArgumentNullException (System.ExceptionArgument argument) in mcs/class/referencesource/mscorlib/system/throwhelper.cs:80
+ at System.Collections.Generic.Dictionary`2[TKey,TValue].FindEntry (TKey key) in mcs/class/referencesource/mscorlib/system/collections/generic/dictionary.cs:299
+ at System.Collections.Generic.Dictionary`2[TKey,TValue].ContainsKey (TKey key) in mcs/class/referencesource/mscorlib/system/collections/generic/dictionary.cs:228
+ at StackTraceDumper.<Main>m__E () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:52
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
Stacktrace:
- at StackTraceDumper+InnerGenericClass`1+InnerInnerGenericClass`1[T,T2].ThrowException (T2 message) in StackTraceDumper.cs:143
- at StackTraceDumper.<Main>m__D () in StackTraceDumper.cs:48
- at StackTraceDumper.Catch (System.Action action) in StackTraceDumper.cs:54
+ at System.ThrowHelper.ThrowArgumentNullException (System.ExceptionArgument argument) in mcs/class/referencesource/mscorlib/system/throwhelper.cs:80
+ at System.Collections.Generic.Dictionary`2[TKey,TValue].FindEntry (TKey key) in mcs/class/referencesource/mscorlib/system/collections/generic/dictionary.cs:299
+ at System.Collections.Generic.Dictionary`2[TKey,TValue].ContainsKey (TKey key) in mcs/class/referencesource/mscorlib/system/collections/generic/dictionary.cs:228
+ at StackTraceDumper.<Main>m__E () in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:52
+ at StackTraceDumper.Catch (System.Action action) in mcs/tools/mono-symbolicate/Test/StackTraceDumper.cs:59
symbolicate.cs
LocationProvider.cs
SeqPointInfo.cs
+StackFrameData.cs
+StackTraceMetadata.cs
+SymbolManager.cs
+Logger.cs
+../../class/Mono.Options/Mono.Options/Options.cs
using System;
using System.IO;
+using System.Text;
+using System.Linq;
+using System.Collections.Generic;
using System.Globalization;
-using System.Text.RegularExpressions;
+using Mono.Options;
-namespace Symbolicate
+namespace Mono
{
- public class Program
+ public class Symbolicate
{
- static Regex regex = new Regex (@"\w*at (?<Method>.+) *(\[0x(?<IL>.+)\]|<0x.+ \+ 0x(?<NativeOffset>.+)>( (?<MethodIndex>\d+)|)) in <filename unknown>:0");
+ class Command {
+ public readonly int MinArgCount;
+ public readonly int MaxArgCount;
+ public readonly Action<List<string>> Action;
+
+ public Command (Action<List<string>> action, int minArgCount = 0, int maxArgCount = int.MaxValue)
+ {
+ Action = action;
+ MinArgCount = minArgCount;
+ MaxArgCount = maxArgCount;
+ }
+ }
+
+ static Logger logger;
public static int Main (String[] args)
{
- if (args.Length < 2) {
- Console.Error.WriteLine ("Usage: symbolicate <assembly path> <input file> [lookup directories]");
- return 1;
- }
+ var showHelp = false;
+ List<string> extra = null;
- var assemblyPath = args [0];
- var inputFile = args [1];
+ Command cmd = null;
+
+ var logLevel = Logger.Level.Warning;
- var locProvider = new LocationProvider ();
+ var options = new OptionSet {
+ { "h|help", "Show this help", v => showHelp = true },
+ { "q", "Quiet, warnings are not displayed", v => logLevel = Logger.Level.Error },
+ { "v", "Verbose, log debug messages", v => logLevel = Logger.Level.Debug },
+ };
- for (var i = 2; i < args.Length; i++)
- locProvider.AddDirectory (args [i]);
+ try {
+ extra = options.Parse (args);
+ } catch (OptionException e) {
+ Console.WriteLine ("Option error: {0}", e.Message);
+ showHelp = true;
+ }
- locProvider.AddAssembly (assemblyPath);
+ if (extra.Count > 0 && extra[0] == "store-symbols")
+ cmd = new Command (StoreSymbolsAction, 2);
- using (StreamReader r = new StreamReader (inputFile)) {
- for (var line = r.ReadLine (); line != null; line = r.ReadLine ()) {
- line = SymbolicateLine (line, locProvider);
- Console.WriteLine (line);
- }
+ if (cmd != null) {
+ extra.RemoveAt (0);
+ } else {
+ cmd = new Command (SymbolicateAction, 2, 2);
}
+ if (showHelp || extra == null || extra.Count < cmd.MinArgCount || extra.Count > cmd.MaxArgCount) {
+ Console.Error.WriteLine ("Usage: symbolicate [options] <msym dir> <input file>");
+ Console.Error.WriteLine (" symbolicate [options] store-symbols <msym dir> [<dir>]+");
+ Console.WriteLine ();
+ Console.WriteLine ("Available options:");
+ options.WriteOptionDescriptions (Console.Out);
+ return 1;
+ }
+
+ logger = new Logger (logLevel, msg => Console.Error.WriteLine (msg));
+
+ cmd.Action (extra);
+
return 0;
}
- static string SymbolicateLine (string line, LocationProvider locProvider)
+ private static void SymbolicateAction (List<string> args)
{
- var match = regex.Match (line);
- if (!match.Success)
- return line;
+ var msymDir = args [0];
+ var inputFile = args [1];
- string typeFullName, methodSignature;
- var methodStr = match.Groups ["Method"].Value.Trim ();
- if (!ExtractSignatures (methodStr, out typeFullName, out methodSignature))
- return line;
+ var symbolManager = new SymbolManager (msymDir, logger);
- var isOffsetIL = !string.IsNullOrEmpty (match.Groups ["IL"].Value);
- var offsetVarName = (isOffsetIL)? "IL" : "NativeOffset";
- var offset = int.Parse (match.Groups [offsetVarName].Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+ using (StreamReader r = new StreamReader (inputFile)) {
+ var sb = Process (r, symbolManager);
+ Console.Write (sb.ToString ());
+ }
+ }
- uint methodIndex = 0xffffff;
- if (!string.IsNullOrEmpty (match.Groups ["MethodIndex"].Value))
- methodIndex = uint.Parse (match.Groups ["MethodIndex"].Value, CultureInfo.InvariantCulture);
+ private static void StoreSymbolsAction (List<string> args)
+ {
+ var msymDir = args[0];
+ var lookupDirs = args.Skip (1).ToArray ();
- var loc = locProvider.TryGetLocation (typeFullName, methodSignature, offset, isOffsetIL, methodIndex);
- if (loc == null)
- return line;
+ var symbolManager = new SymbolManager (msymDir, logger);
- return line.Replace ("<filename unknown>:0", string.Format ("{0}:{1}", loc.Document.Url, loc.StartLine));
+ symbolManager.StoreSymbols (lookupDirs);
}
- static bool ExtractSignatures (string str, out string typeFullName, out string methodSignature)
+ public static StringBuilder Process (StreamReader reader, SymbolManager symbolManager)
{
- var methodNameEnd = str.IndexOf ('(');
- if (methodNameEnd == -1) {
- typeFullName = methodSignature = null;
- return false;
+ List<StackFrameData> stackFrames = new List<StackFrameData>();
+ List<StackTraceMetadata> metadata = new List<StackTraceMetadata>();
+ StringBuilder sb = new StringBuilder ();
+ bool linesEnded = false;
+
+ for (var line = reader.ReadLine (); line != null; line = reader.ReadLine ()) {
+ StackFrameData sfData;
+ if (!linesEnded && StackFrameData.TryParse (line, out sfData)) {
+ stackFrames.Add (sfData);
+ continue;
+ }
+
+ if (stackFrames.Count > 0) {
+ linesEnded = true;
+
+ StackTraceMetadata stMetadata;
+ if (StackTraceMetadata.TryParse (line, out stMetadata)) {
+ metadata.Add (stMetadata);
+ continue;
+ }
+
+ DumpStackTrace (symbolManager, sb, stackFrames, metadata);
+
+ // Clear lists for next stack trace
+ stackFrames.Clear ();
+ metadata.Clear ();
+ }
+
+ linesEnded = false;
+
+ // Append last line
+ sb.AppendLine (line);
}
- var typeNameEnd = str.LastIndexOf ('.', methodNameEnd);
- if (typeNameEnd == -1) {
- typeFullName = methodSignature = null;
- return false;
- }
+ if (stackFrames.Count > 0)
+ DumpStackTrace (symbolManager, sb, stackFrames, metadata);
- // Adjustment for Type..ctor ()
- if (typeNameEnd > 0 && str [typeNameEnd - 1] == '.') {
- --typeNameEnd;
+ return sb;
+ }
+
+ private static void DumpStackTrace (SymbolManager symbolManager, StringBuilder sb, List<StackFrameData> stackFrames, List<StackTraceMetadata> metadata)
+ {
+ string aotid = null;
+ var aotidMetadata = metadata.FirstOrDefault ( m => m.Id == "AOTID" );
+ if (aotidMetadata != null)
+ aotid = aotidMetadata.Value;
+
+ var linesMvid = ProcessLinesMVID (metadata);
+ var lineNumber = -1;
+ foreach (var sfData in stackFrames) {
+ string mvid = null;
+ lineNumber++;
+ if (!sfData.IsValid)
+ continue;
+ if (linesMvid.ContainsKey (lineNumber))
+ mvid = linesMvid [lineNumber];
+
+ symbolManager.TryResolveLocation (sfData, mvid, aotid);
+
+ sb.AppendLine (sfData.ToString ());
}
- typeFullName = str.Substring (0, typeNameEnd);
- // Remove generic parameters
- typeFullName = Regex.Replace (typeFullName, @"\[[^\[\]]*\]", "");
+ foreach (var m in metadata)
+ sb.AppendLine (m.Line);
+ }
+
+ private static Dictionary<int, string> ProcessLinesMVID (List<StackTraceMetadata> metadata)
+ {
+ var linesMvid = new Dictionary<int, string> ();
+ var mvidData = metadata.Where ( m => m.Id == "MVID" ).Select ( m => m.Value );
+ foreach (var m in mvidData) {
+ var s1 = m.Split (new char[] {' '}, 2);
+ var mvid = s1 [0];
+ var lines = s1 [1].Split (',');
+ foreach (var line in lines)
+ linesMvid.Add (int.Parse (line), mvid);
+ }
- methodSignature = str.Substring (typeNameEnd + 1);
- return true;
+ return linesMvid;
}
}
-}
\ No newline at end of file
+}
install-local: install-extras
endif
+PORTABLE_TARGETS_SRC=../../../external/buildtools/src/Portable/Targets
+PCL5_FX_SRC=../../../external/buildtools/src/Portable/Frameworks/v5.0
+
NETFRAMEWORK_DIR=$(mono_libdir)/mono/xbuild-frameworks/.NETFramework
+PCL5_FX_DIR=$(mono_libdir)/mono/xbuild-frameworks/.NETPortable/v5.0
VS_TARGETS_DIR = $(mono_libdir)/mono/xbuild/Microsoft/VisualStudio
PORTABLE_TARGETS_DIR = $(mono_libdir)/mono/xbuild/Microsoft/Portable
+NUGET_BUILDTASKS_TARGETS_DIR = $(mono_libdir)/mono/xbuild/Microsoft/NuGet
+
+ifeq (14.0, $(XBUILD_VERSION))
+install-extras: install-versioned-files install-global-files
+else
+install-extras: install-versioned-files
+endif
+#install files into xbuild's versioned locations
+install-versioned-files: install-bin-data install-nuget-imports
-install-extras: install-bin-data install-frameworks install-pcl-targets install-web-targets
+#install files that are only installed once across all xbuild versions
+install-global-files: install-frameworks install-web-targets install-pcl-targets install-pcl5-framework install-nuget-targets
install-bin-data:
$(MKINSTALLDIRS) $(DESTDIR)$(XBUILD_BIN_DIR)/MSBuild
$(INSTALL_DATA) data/xbuild.rsp $(DESTDIR)$(XBUILD_BIN_DIR)
$(INSTALL_DATA) data/$(XBUILD_VERSION)/Microsoft.Common.tasks $(DESTDIR)$(XBUILD_BIN_DIR)
$(INSTALL_DATA) data/$(XBUILD_VERSION)/Microsoft.Common.targets $(DESTDIR)$(XBUILD_BIN_DIR)
+ifeq (14.0, $(XBUILD_VERSION))
+ $(INSTALL_DATA) data/$(XBUILD_VERSION)/Microsoft.Common.props $(DESTDIR)$(XBUILD_BIN_DIR)/../
+endif
$(INSTALL_DATA) data/$(XBUILD_VERSION)/Microsoft.CSharp.targets $(DESTDIR)$(XBUILD_BIN_DIR)
$(INSTALL_DATA) data/Microsoft.Build.xsd $(DESTDIR)$(XBUILD_BIN_DIR)
$(INSTALL_DATA) data/Microsoft.VisualBasic.targets $(DESTDIR)$(XBUILD_BIN_DIR)
$(INSTALL_DATA) frameworks/net_4.6.1.xml $(DESTDIR)$(NETFRAMEWORK_DIR)/v4.6.1/RedistList/FrameworkList.xml
install-pcl-targets:
- $(MKINSTALLDIRS) $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.0
- $(INSTALL_DATA) targets/Microsoft.Portable.Common.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.0/Microsoft.Portable.Common.targets
- $(INSTALL_DATA) targets/Microsoft.Portable.CSharp_4.0.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.0/Microsoft.Portable.CSharp.targets
- $(INSTALL_DATA) targets/Microsoft.Portable.VisualBasic_4.0.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.0/Microsoft.Portable.VisualBasic.targets
- $(MKINSTALLDIRS) $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.5
- $(INSTALL_DATA) targets/Microsoft.Portable.Common.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.5/Microsoft.Portable.Common.targets
- $(INSTALL_DATA) targets/Microsoft.Portable.CSharp_4.5.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.5/Microsoft.Portable.CSharp.targets
- $(INSTALL_DATA) targets/Microsoft.Portable.VisualBasic_4.5.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.5/Microsoft.Portable.VisualBasic.targets
- $(INSTALL_DATA) targets/Microsoft.Portable.Core.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/Microsoft.Portable.Core.targets
- $(INSTALL_DATA) targets/Microsoft.Portable.Core.props $(DESTDIR)$(PORTABLE_TARGETS_DIR)/Microsoft.Portable.Core.props
- $(MKINSTALLDIRS) $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.6
- $(INSTALL_DATA) targets/Microsoft.Portable.Common.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.6/Microsoft.Portable.Common.targets
- $(INSTALL_DATA) targets/Microsoft.Portable.CSharp_4.5.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.6/Microsoft.Portable.CSharp.targets
- $(INSTALL_DATA) targets/Microsoft.Portable.VisualBasic_4.5.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/v4.6/Microsoft.Portable.VisualBasic.targets
+ $(MKINSTALLDIRS) $(DESTDIR)$(PORTABLE_TARGETS_DIR)
+ $(INSTALL_DATA) $(PORTABLE_TARGETS_SRC)/Microsoft.Portable.Core.props $(DESTDIR)$(PORTABLE_TARGETS_DIR)/Microsoft.Portable.Core.props
+ $(INSTALL_DATA) $(PORTABLE_TARGETS_SRC)/Microsoft.Portable.Core.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/Microsoft.Portable.Core.targets
+
+ for VERSION in v4.0 v4.5 v4.6 v5.0; do \
+ $(MKINSTALLDIRS) $(DESTDIR)$(PORTABLE_TARGETS_DIR)/$$VERSION; \
+ $(INSTALL_DATA) $(PORTABLE_TARGETS_SRC)/$$VERSION/Microsoft.Portable.Common.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/$$VERSION/Microsoft.Portable.Common.targets; \
+ $(INSTALL_DATA) $(PORTABLE_TARGETS_SRC)/$$VERSION/Microsoft.Portable.CSharp.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/$$VERSION/Microsoft.Portable.CSharp.targets; \
+ $(INSTALL_DATA) $(PORTABLE_TARGETS_SRC)/$$VERSION/Microsoft.Portable.VisualBasic.targets $(DESTDIR)$(PORTABLE_TARGETS_DIR)/$$VERSION/Microsoft.Portable.VisualBasic.targets; \
+ done
install-web-targets:
$(MKINSTALLDIRS) $(DESTDIR)$(VS_TARGETS_DIR)/v9.0/WebApplications
$(MKINSTALLDIRS) $(DESTDIR)$(VS_TARGETS_DIR)/v14.0/WebApplications
$(INSTALL_DATA) targets/Microsoft.WebApplication.targets $(DESTDIR)$(VS_TARGETS_DIR)/v14.0/WebApplications
+NUGET_BUILDTASKS_REPO_DIR=$(topdir)/../external/nuget-buildtasks
+
+install-nuget-targets:
+ $(MKINSTALLDIRS) $(DESTDIR)$(NUGET_BUILDTASKS_TARGETS_DIR)
+ $(INSTALL_DATA) $(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/Microsoft.NuGet.targets $(DESTDIR)$(NUGET_BUILDTASKS_TARGETS_DIR)
+ $(INSTALL_DATA) $(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/Microsoft.NuGet.props $(DESTDIR)$(NUGET_BUILDTASKS_TARGETS_DIR)
+
+install-nuget-imports:
+ifeq (14.0, $(XBUILD_VERSION))
+ $(MKINSTALLDIRS) $(DESTDIR)$(XBUILD_BIN_DIR)/../Imports/Microsoft.Common.props/ImportBefore
+ $(MKINSTALLDIRS) $(DESTDIR)$(XBUILD_BIN_DIR)/../Microsoft.Common.targets/ImportAfter
+ $(INSTALL_DATA) $(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/ImportBeforeAfter/Microsoft.NuGet.ImportBefore.props $(DESTDIR)$(XBUILD_BIN_DIR)/../Imports/Microsoft.Common.props/ImportBefore
+ $(INSTALL_DATA) $(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/ImportBeforeAfter/Microsoft.NuGet.ImportAfter.targets $(DESTDIR)$(XBUILD_BIN_DIR)/../Microsoft.Common.targets/ImportAfter
+endif
+
+# The .NETPortable,Version=v5.0 framework contains no assemblies, and essentially just fills the requirement
+# for a framework moniker. When using it, assemblies are provided by NuGet packages such as .NETStandard.Library
+install-pcl5-framework:
+ $(MKINSTALLDIRS) $(DESTDIR)$(PCL5_FX_DIR)/RedistList
+ $(INSTALL_DATA) $(PCL5_FX_SRC)/FrameworkList.xml $(DESTDIR)$(PCL5_FX_DIR)/RedistList/FrameworkList.xml
+
+ $(MKINSTALLDIRS) $(DESTDIR)$(PCL5_FX_DIR)/SupportedFrameworks
+ $(INSTALL_DATA) "$(PCL5_FX_SRC)/.NET Framework 4.6.xml" "$(DESTDIR)$(PCL5_FX_DIR)/SupportedFrameworks/.NET Framework 4.6.xml"
+ $(INSTALL_DATA) "$(PCL5_FX_SRC)/ASP.NET Core 1.0.xml" "$(DESTDIR)$(PCL5_FX_DIR)/SupportedFrameworks/ASP.NET Core 1.0.xml"
+ $(INSTALL_DATA) "$(PCL5_FX_SRC)/Windows Universal 10.0.xml" "$(DESTDIR)$(PCL5_FX_DIR)/SupportedFrameworks/Windows Universal 10.0.xml"
EXTRA_DISTFILES = \
data/xbuild.rsp \
data/4.0/Microsoft.Common.targets \
data/12.0/Microsoft.Common.targets \
data/14.0/Microsoft.Common.targets \
+ data/14.0/Microsoft.Common.props \
data/2.0/Microsoft.CSharp.targets \
data/3.5/Microsoft.CSharp.targets \
data/4.0/Microsoft.CSharp.targets \
frameworks/net_4.5.2.xml \
frameworks/net_4.6.xml \
frameworks/net_4.6.1.xml \
- targets/Microsoft.Portable.CSharp_4.0.targets \
- targets/Microsoft.Portable.CSharp_4.5.targets \
- targets/Microsoft.Portable.VisualBasic_4.0.targets \
- targets/Microsoft.Portable.VisualBasic_4.5.targets \
- targets/Microsoft.Portable.Common.targets \
- targets/Microsoft.Portable.Core.targets \
- targets/Microsoft.Portable.Core.props \
- targets/Microsoft.WebApplication.targets \
+ targets/Microsoft.WebApplication.targets \
+ $(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/ImportBeforeAfter/Microsoft.NuGet.ImportBefore.props \
+ $(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/ImportBeforeAfter/Microsoft.NuGet.ImportAfter.targets \
+ $(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/Microsoft.NuGet.targets \
+ $(NUGET_BUILDTASKS_REPO_DIR)/src/Microsoft.NuGet.Build.Tasks/Microsoft.NuGet.props \
xbuild.make \
xbuild_test.make
-<Project DefaultTargets="Build" InitialTargets="_ValidateEssentialProperties" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" InitialTargets="_CheckForInvalidConfigurationAndPlatform" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ImportByWildcardBeforeMicrosoftCommonTargets Condition="'$(ImportByWildcardBeforeMicrosoftCommonTargets)' == ''">true</ImportByWildcardBeforeMicrosoftCommonTargets>
<ImportByWildcardAfterMicrosoftCommonTargets Condition="'$(ImportByWildcardAfterMicrosoftCommonTargets)' == ''">true</ImportByWildcardAfterMicrosoftCommonTargets>
<_OriginalPlatform>$(Platform)</_OriginalPlatform>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
+ </PropertyGroup>
+ <!-- in MSBuild, these properties are set in a separate file that is only imported for .NETFramework -->
+ <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<AddAdditionalExplicitAssemblyReferences Condition="'$(AddAdditionalExplicitAssemblyReferences)' == ''">true</AddAdditionalExplicitAssemblyReferences>
<AdditionalExplicitAssemblyReferences Condition="'$(AddAdditionalExplicitAssemblyReferences)' == 'true' and '$(TargetFrameworkVersion)' != 'v2.0' and '$(TargetFrameworkVersion)' != 'v3.0'">System.Core;$(AdditionalExplicitAssemblyReferences)</AdditionalExplicitAssemblyReferences>
</PropertyGroup>
<TargetingClr2Framework Condition="('$(TargetFrameworkIdentifier)' == '.NETFramework') and ('$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5')">true</TargetingClr2Framework>
</PropertyGroup>
- <Target Name="_ValidateEssentialProperties">
+ <Target Name="_CheckForInvalidConfigurationAndPlatform">
<Error Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' != 'true'"
Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
--- /dev/null
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ImportByWildcardBeforeMicrosoftCommonProps Condition="'$(ImportByWildcardBeforeMicrosoftCommonProps)' == ''">true</ImportByWildcardBeforeMicrosoftCommonProps>
+ <ImportByWildcardAfterMicrosoftCommonProps Condition="'$(ImportByWildcardAfterMicrosoftCommonProps)' == ''">true</ImportByWildcardAfterMicrosoftCommonProps>
+ </PropertyGroup>
+
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Imports\Microsoft.Common.props\ImportBefore\*"
+ Condition="'$(ImportByWildcardBeforeMicrosoftCommonProps)' == 'true' and Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Imports\Microsoft.Common.props\ImportBefore')"/>
+
+ <PropertyGroup>
+ <MicrosoftCommonPropsHasBeenImported>true</MicrosoftCommonPropsHasBeenImported>
+ </PropertyGroup>
+
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Imports\Microsoft.Common.props\ImportAfter\*"
+ Condition="'$(ImportByWildcardAfterMicrosoftCommonProps)' == 'true' and Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Imports\Microsoft.Common.props\ImportAfter')"/>
+</Project>
-<Project DefaultTargets="Build" InitialTargets="_ValidateEssentialProperties" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" InitialTargets="_CheckForInvalidConfigurationAndPlatform" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="'$(MicrosoftCommonPropsHasBeenImported)' != 'true' and Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+
<PropertyGroup>
<ImportByWildcardBeforeMicrosoftCommonTargets Condition="'$(ImportByWildcardBeforeMicrosoftCommonTargets)' == ''">true</ImportByWildcardBeforeMicrosoftCommonTargets>
<ImportByWildcardAfterMicrosoftCommonTargets Condition="'$(ImportByWildcardAfterMicrosoftCommonTargets)' == ''">true</ImportByWildcardAfterMicrosoftCommonTargets>
<_OriginalPlatform>$(Platform)</_OriginalPlatform>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
+ </PropertyGroup>
+ <!-- in MSBuild, these properties are set in a separate file that is only imported for .NETFramework -->
+ <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<AddAdditionalExplicitAssemblyReferences Condition="'$(AddAdditionalExplicitAssemblyReferences)' == ''">true</AddAdditionalExplicitAssemblyReferences>
<AdditionalExplicitAssemblyReferences Condition="'$(AddAdditionalExplicitAssemblyReferences)' == 'true' and '$(TargetFrameworkVersion)' != 'v2.0' and '$(TargetFrameworkVersion)' != 'v3.0'">System.Core;$(AdditionalExplicitAssemblyReferences)</AdditionalExplicitAssemblyReferences>
</PropertyGroup>
<TargetingClr2Framework Condition="('$(TargetFrameworkIdentifier)' == '.NETFramework') and ('$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5')">true</TargetingClr2Framework>
</PropertyGroup>
- <Target Name="_ValidateEssentialProperties">
+ <Target Name="_CheckForInvalidConfigurationAndPlatform">
<Error Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' != 'true'"
Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
-<Project DefaultTargets="Build" InitialTargets="_ValidateEssentialProperties" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" InitialTargets="_CheckForInvalidConfigurationAndPlatform" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ImportByWildcardBeforeMicrosoftCommonTargets Condition="'$(ImportByWildcardBeforeMicrosoftCommonTargets)' == ''">true</ImportByWildcardBeforeMicrosoftCommonTargets>
<ImportByWildcardAfterMicrosoftCommonTargets Condition="'$(ImportByWildcardAfterMicrosoftCommonTargets)' == ''">true</ImportByWildcardAfterMicrosoftCommonTargets>
<_OriginalPlatform>$(Platform)</_OriginalPlatform>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
+ </PropertyGroup>
+ <!-- in MSBuild, these properties are set in a separate file that is only imported for .NETFramework -->
+ <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<AddAdditionalExplicitAssemblyReferences Condition="'$(AddAdditionalExplicitAssemblyReferences)' == ''">true</AddAdditionalExplicitAssemblyReferences>
<AdditionalExplicitAssemblyReferences Condition="'$(AddAdditionalExplicitAssemblyReferences)' == 'true' and '$(TargetFrameworkVersion)' != 'v2.0' and '$(TargetFrameworkVersion)' != 'v3.0'">System.Core;$(AdditionalExplicitAssemblyReferences)</AdditionalExplicitAssemblyReferences>
</PropertyGroup>
<TargetingClr2Framework Condition="('$(TargetFrameworkIdentifier)' == '.NETFramework') and ('$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5')">true</TargetingClr2Framework>
</PropertyGroup>
- <Target Name="_ValidateEssentialProperties">
+ <Target Name="_CheckForInvalidConfigurationAndPlatform">
<Error Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' != 'true'"
Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+++ /dev/null
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="..\Microsoft.Portable.Core.props" />
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="..\Microsoft.Portable.Core.targets" />
-</Project>
+++ /dev/null
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="..\Microsoft.Portable.Core.props" />
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="..\Microsoft.Portable.Core.targets" />
-</Project>
+++ /dev/null
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="..\Microsoft.Portable.Core.props" />
- <Import Project="..\Microsoft.Portable.Core.targets" />
-</Project>
+++ /dev/null
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <AvailablePlatforms>Any CPU</AvailablePlatforms>
-
- <TargetPlatformIdentifier>Portable</TargetPlatformIdentifier>
- <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
- <TargetFrameworkMonikerDisplayName>.NET Portable Subset</TargetFrameworkMonikerDisplayName>
-
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
- <NoStdLib>true</NoStdLib>
-
- <ImplicitlyExpandTargetFramework Condition="'$(ImplicitlyExpandTargetFramework)' == '' ">true</ImplicitlyExpandTargetFramework>
- </PropertyGroup>
-</Project>
+++ /dev/null
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <ResolveReferencesDependsOn>
- $(ResolveReferencesDependsOn);
- ImplicitlyExpandTargetFramework;
- </ResolveReferencesDependsOn>
-
- <ImplicitlyExpandTargetFrameworkDependsOn>
- $(ImplicitlyExpandTargetFrameworkDependsOn);
- GetReferenceAssemblyPaths
- </ImplicitlyExpandTargetFrameworkDependsOn>
- </PropertyGroup>
-
- <Target Name="ImplicitlyExpandTargetFramework"
- Condition="'$(ImplicitlyExpandTargetFramework)' == 'true'"
- DependsOnTargets="$(ImplicitlyExpandTargetFrameworkDependsOn)">
-
- <ItemGroup>
- <ReferenceAssemblyPaths Include="$(_TargetFrameworkDirectories)"/>
- <ReferencePath Include="%(ReferenceAssemblyPaths.Identity)\*.dll">
- <CopyLocal>false</CopyLocal>
- <ResolvedFrom>ImplicitlyExpandTargetFramework</ResolvedFrom>
- <IsSystemReference>True</IsSystemReference>
- </ReferencePath>
- </ItemGroup>
- </Target>
-
-</Project>
+++ /dev/null
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="..\Microsoft.Portable.Core.props" />
- <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
- <Import Project="..\Microsoft.Portable.Core.targets" />
-</Project>
+++ /dev/null
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="..\Microsoft.Portable.Core.props" />
- <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
- <Import Project="..\Microsoft.Portable.Core.targets" />
-</Project>
<opcode name="mono_calli_extra_arg" input="VarPop" output="VarPush" args="InlineSig" o1="0xF0" o2="0x18" flow="call" />
<opcode name="mono_lddomain" input="Pop0" output="PushI" args="InlineNone" o1="0xF0" o2="0x19" flow="next" />
<opcode name="mono_atomic_store_i4" input="PopI+PopI" output="Push0" args="InlineI" o1="0xF0" o2="0x1A" flow="next" />
+<opcode name="mono_get_last_error" input="Pop0" output="PushI" args="InlineNone" o1="0xF0" o2="0x1B" flow="next" />
</opdesc>
OPDEF(CEE_MONO_CALLI_EXTRA_ARG, "mono_calli_extra_arg", VarPop, VarPush, InlineSig, X, 2, 0xF0, 0x18, CALL)
OPDEF(CEE_MONO_LDDOMAIN, "mono_lddomain", Pop0, PushI, InlineNone, X, 2, 0xF0, 0x19, NEXT)
OPDEF(CEE_MONO_ATOMIC_STORE_I4, "mono_atomic_store_i4", PopI+PopI, Push0, InlineI, X, 2, 0xF0, 0x1A, NEXT)
+OPDEF(CEE_MONO_GET_LAST_ERROR, "mono_get_last_error", Pop0, PushI, InlineNone, X, 2, 0xF0, 0x1B, NEXT)
#ifndef OPALIAS
#define _MONO_CIL_OPALIAS_DEFINED_
#define OPALIAS(a,s,r)
context.h \
error.h \
events.h \
- handles.h \
io.h \
io-trace.h \
io-layer.h \
events.c \
events.h \
event-private.h \
- handles.c \
- handles.h \
- handles-private.h \
io.c \
io.h \
io-portability.c \
wapi_glob.c \
wapi.h \
wapi-private.h \
+ wapi.c \
wthreads.c
#include <errno.h>
#include "mono/io-layer/wapi.h"
+#include "mono/io-layer/wapi-private.h"
#include "mono/utils/mono-once.h"
static pthread_key_t error_key;
static mono_once_t error_key_once=MONO_ONCE_INIT;
-extern gboolean _wapi_has_shut_down;
static void error_init(void)
{
#include <glib.h>
#include <pthread.h>
-extern struct _WapiHandleOps _wapi_event_ops;
-extern struct _WapiHandleOps _wapi_namedevent_ops;
-
-extern void _wapi_event_details (gpointer handle_info);
+#include "wapi-private.h"
struct _WapiHandle_event
{
struct _WapiHandle_namedevent
{
+ struct _WapiHandle_event e;
WapiSharedNamespace sharedns;
- gboolean manual;
- guint32 set_count;
};
+void
+_wapi_event_init (void);
+
#endif /* _WAPI_EVENT_PRIVATE_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/event-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
static void event_signal(gpointer handle);
static gboolean event_own (gpointer handle);
+static void event_details (gpointer data);
+static const gchar* event_typename (void);
+static gsize event_typesize (void);
static void namedevent_signal (gpointer handle);
static gboolean namedevent_own (gpointer handle);
+static void namedevent_details (gpointer data);
+static const gchar* namedevent_typename (void);
+static gsize namedevent_typesize (void);
-struct _WapiHandleOps _wapi_event_ops = {
+static MonoW32HandleOps _wapi_event_ops = {
NULL, /* close */
event_signal, /* signal */
event_own, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ event_details, /* details */
+ event_typename, /* typename */
+ event_typesize, /* typesize */
};
-struct _WapiHandleOps _wapi_namedevent_ops = {
+static MonoW32HandleOps _wapi_namedevent_ops = {
NULL, /* close */
namedevent_signal, /* signal */
namedevent_own, /* own */
NULL, /* is_owned */
+ NULL, /* special_wait */
+ NULL, /* prewait */
+ namedevent_details, /* details */
+ namedevent_typename, /* typename */
+ namedevent_typesize, /* typesize */
};
-static gboolean event_pulse (gpointer handle);
-static gboolean event_reset (gpointer handle);
-static gboolean event_set (gpointer handle);
+void
+_wapi_event_init (void)
+{
+ mono_w32handle_register_ops (MONO_W32HANDLE_EVENT, &_wapi_event_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDEVENT, &_wapi_namedevent_ops);
-static gboolean namedevent_pulse (gpointer handle);
-static gboolean namedevent_reset (gpointer handle);
-static gboolean namedevent_set (gpointer handle);
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_EVENT,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDEVENT,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+}
-static struct
+static const char* event_handle_type_to_string (MonoW32HandleType type)
{
- gboolean (*pulse)(gpointer handle);
- gboolean (*reset)(gpointer handle);
- gboolean (*set)(gpointer handle);
-} event_ops[WAPI_HANDLE_COUNT] = {
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {event_pulse, event_reset, event_set},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {namedevent_pulse, namedevent_reset, namedevent_set},
-};
+ switch (type) {
+ case MONO_W32HANDLE_EVENT: return "event";
+ case MONO_W32HANDLE_NAMEDEVENT: return "named event";
+ default:
+ g_assert_not_reached ();
+ }
+}
-void _wapi_event_details (gpointer handle_info)
+static gboolean event_handle_own (gpointer handle, MonoW32HandleType type)
{
- struct _WapiHandle_event *event = (struct _WapiHandle_event *)handle_info;
-
- g_print ("manual: %s", event->manual?"TRUE":"FALSE");
-}
+ struct _WapiHandle_event *event_handle;
+ gboolean ok;
+
+ ok = mono_w32handle_lookup (handle, type, (gpointer *)&event_handle);
+ if (!ok) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+ return FALSE;
+ }
-static mono_once_t event_ops_once=MONO_ONCE_INIT;
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
-static void event_ops_init (void)
-{
- _wapi_handle_register_capabilities (WAPI_HANDLE_EVENT,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL));
- _wapi_handle_register_capabilities (WAPI_HANDLE_NAMEDEVENT,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL));
+ if (!event_handle->manual) {
+ g_assert (event_handle->set_count > 0);
+ event_handle->set_count --;
+
+ if (event_handle->set_count == 0)
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
+ }
+
+ return TRUE;
}
static void event_signal(gpointer handle)
static gboolean event_own (gpointer handle)
{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up event handle %p", __func__,
- handle);
- return (FALSE);
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning event handle %p", __func__, handle);
-
- if(event_handle->manual==FALSE) {
- g_assert (event_handle->set_count > 0);
-
- if (--event_handle->set_count == 0) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
- }
-
- return(TRUE);
+ return event_handle_own (handle, MONO_W32HANDLE_EVENT);
}
static void namedevent_signal (gpointer handle)
/* NB, always called with the shared handle lock held */
static gboolean namedevent_own (gpointer handle)
{
- struct _WapiHandle_namedevent *namedevent_handle;
- gboolean ok;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning named event handle %p", __func__, handle);
+ return event_handle_own (handle, MONO_W32HANDLE_NAMEDEVENT);
+}
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
- (gpointer *)&namedevent_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named event handle %p",
- __func__, handle);
- return(FALSE);
- }
-
- if (namedevent_handle->manual == FALSE) {
- g_assert (namedevent_handle->set_count > 0);
-
- if (--namedevent_handle->set_count == 0) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
- }
-
- return (TRUE);
+static void event_details (gpointer data)
+{
+ struct _WapiHandle_event *event = (struct _WapiHandle_event *)data;
+ g_print ("manual: %s, set_count: %d",
+ event->manual ? "TRUE" : "FALSE", event->set_count);
}
-static gpointer event_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
- gboolean manual, gboolean initial)
+
+static void namedevent_details (gpointer data)
+{
+ struct _WapiHandle_namedevent *namedevent = (struct _WapiHandle_namedevent *)data;
+ g_print ("manual: %s, set_count: %d, name: \"%s\"",
+ namedevent->e.manual ? "TRUE" : "FALSE", namedevent->e.set_count, namedevent->sharedns.name);
+}
+
+static const gchar* event_typename (void)
+{
+ return "Event";
+}
+
+static gsize event_typesize (void)
+{
+ return sizeof (struct _WapiHandle_event);
+}
+
+static const gchar* namedevent_typename (void)
+{
+ return "N.Event";
+}
+
+static gsize namedevent_typesize (void)
+{
+ return sizeof (struct _WapiHandle_namedevent);
+}
+
+static gpointer event_handle_create (struct _WapiHandle_event *event_handle, MonoW32HandleType type, gboolean manual, gboolean initial)
{
- struct _WapiHandle_event event_handle = {0};
gpointer handle;
int thr_ret;
-
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if an event
- * was freshly created
- */
- SetLastError (ERROR_SUCCESS);
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating unnamed event", __func__);
-
- event_handle.manual = manual;
- event_handle.set_count = 0;
+ event_handle->manual = manual;
+ event_handle->set_count = (initial && !manual) ? 1 : 0;
- if (initial == TRUE) {
- if (manual == FALSE) {
- event_handle.set_count = 1;
- }
- }
-
- handle = _wapi_handle_new (WAPI_HANDLE_EVENT, &event_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating event handle", __func__);
+ handle = mono_w32handle_new (type, event_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
+ g_warning ("%s: error creating %s handle",
+ __func__, event_handle_type_to_string (type));
SetLastError (ERROR_GEN_FAILURE);
- return(NULL);
+ return NULL;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if (initial == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created new event handle %p", __func__, handle);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ if (initial)
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- return(handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+
+ return handle;
+}
+
+static gpointer event_create (gboolean manual, gboolean initial)
+{
+ struct _WapiHandle_event event_handle;
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+ __func__, event_handle_type_to_string (MONO_W32HANDLE_EVENT));
+ return event_handle_create (&event_handle, MONO_W32HANDLE_EVENT, manual, initial);
}
-static gpointer namedevent_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
- gboolean manual, gboolean initial,
- const gunichar2 *name G_GNUC_UNUSED)
+static gpointer namedevent_create (gboolean manual, gboolean initial, const gunichar2 *name G_GNUC_UNUSED)
{
- struct _WapiHandle_namedevent namedevent_handle = {{{0}}, 0};
gpointer handle;
gchar *utf8_name;
int thr_ret;
-
- /* w32 seems to guarantee that opening named objects can't
- * race each other
- */
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+ __func__, event_handle_type_to_string (MONO_W32HANDLE_NAMEDEVENT));
+
+ /* w32 seems to guarantee that opening named objects can't race each other */
thr_ret = _wapi_namespace_lock ();
g_assert (thr_ret == 0);
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if an event
- * was freshly created
- */
- SetLastError (ERROR_SUCCESS);
-
utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named event [%s]", __func__, utf8_name);
-
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDEVENT,
- utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
- /* The name has already been used for a different
- * object.
- */
+
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDEVENT, utf8_name);
+ if (handle == INVALID_HANDLE_VALUE) {
+ /* The name has already been used for a different object. */
+ handle = NULL;
SetLastError (ERROR_INVALID_HANDLE);
- goto cleanup;
} else if (handle) {
- /* Not an error, but this is how the caller is
- * informed that the event wasn't freshly created
- */
+ /* Not an error, but this is how the caller is informed that the event wasn't freshly created */
SetLastError (ERROR_ALREADY_EXISTS);
+
+ /* this is used as creating a new handle */
+ mono_w32handle_ref (handle);
} else {
- /* A new named event, so create both the private and
- * shared parts
- */
-
+ /* A new named event */
+ struct _WapiHandle_namedevent namedevent_handle;
+
strncpy (&namedevent_handle.sharedns.name [0], utf8_name, MAX_PATH);
namedevent_handle.sharedns.name [MAX_PATH] = '\0';
- namedevent_handle.manual = manual;
- namedevent_handle.set_count = 0;
-
- if (initial == TRUE) {
- if (manual == FALSE) {
- namedevent_handle.set_count = 1;
- }
- }
-
- handle = _wapi_handle_new (WAPI_HANDLE_NAMEDEVENT,
- &namedevent_handle);
-
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating event handle", __func__);
- SetLastError (ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- /* Set the initial state, as this is a completely new
- * handle
- */
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (initial == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ handle = event_handle_create ((struct _WapiHandle_event*) &namedevent_handle, MONO_W32HANDLE_NAMEDEVENT, manual, initial);
}
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning event handle %p", __func__, handle);
-
-cleanup:
g_free (utf8_name);
- _wapi_namespace_unlock (NULL);
-
- return handle;
+ thr_ret = _wapi_namespace_unlock (NULL);
+ g_assert (thr_ret == 0);
+ return handle;
}
gboolean manual, gboolean initial,
const gunichar2 *name G_GNUC_UNUSED)
{
- mono_once (&event_ops_once, event_ops_init);
-
- if (name == NULL) {
- return(event_create (security, manual, initial));
- } else {
- return(namedevent_create (security, manual, initial, name));
- }
-}
-
-static gboolean event_pulse (gpointer handle)
-{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up event handle %p", __func__,
- handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Pulsing event handle %p", __func__, handle);
-
- if (event_handle->manual == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
- } else {
- event_handle->set_count = 1;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (event_handle->manual == TRUE) {
- /* For a manual-reset event, we're about to try and
- * get the handle lock again, so give other threads a
- * chance
- */
- sched_yield ();
-
- /* Reset the handle signal state */
- /* I'm not sure whether or not we need a barrier here
- * to make sure that all threads waiting on the event
- * have proceeded. Currently we rely on broadcasting
- * a condition.
- */
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Obtained write lock on event handle %p",
- __func__, handle);
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- }
-
- return(TRUE);
-}
-
-static gboolean namedevent_pulse (gpointer handle)
-{
- struct _WapiHandle_namedevent *namedevent_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
- (gpointer *)&namedevent_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named event handle %p",
- __func__, handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Pulsing named event handle %p", __func__, handle);
-
- if (namedevent_handle->manual == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
- } else {
- namedevent_handle->set_count = 1;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (namedevent_handle->manual == TRUE) {
- /* For a manual-reset event, we're about to try and
- * get the handle lock again, so give other processes
- * a chance
- */
- _wapi_handle_spin (200);
-
- /* Reset the handle signal state */
- /* I'm not sure whether or not we need a barrier here
- * to make sure that all threads waiting on the event
- * have proceeded. Currently we rely on waiting for
- * twice the shared handle poll interval.
- */
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Obtained write lock on event handle %p",
- __func__, handle);
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- }
+ /* Need to blow away any old errors here, because code tests
+ * for ERROR_ALREADY_EXISTS on success (!) to see if an event
+ * was freshly created
+ */
+ SetLastError (ERROR_SUCCESS);
- return(TRUE);
+ return name ? namedevent_create (manual, initial, name) : event_create (manual, initial);
}
/**
*/
gboolean PulseEvent(gpointer handle)
{
- WapiHandleType type;
-
+ MonoW32HandleType type;
+ struct _WapiHandle_event *event_handle;
+ int thr_ret;
+
if (handle == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
-
- type = _wapi_handle_type (handle);
-
- if (event_ops[type].pulse == NULL) {
+
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_EVENT:
+ case MONO_W32HANDLE_NAMEDEVENT:
+ break;
+ default:
SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(event_ops[type].pulse (handle));
-}
-static gboolean event_reset (gpointer handle)
-{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up event handle %p",
- __func__, handle);
- return(FALSE);
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+ return FALSE;
}
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Resetting event handle %p", __func__, handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: pulsing %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if (_wapi_handle_issignalled (handle) == FALSE) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No need to reset event handle %p", __func__,
- handle);
+
+ if (!event_handle->manual) {
+ event_handle->set_count = 1;
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
} else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Obtained write lock on event handle %p",
- __func__, handle);
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
-
- event_handle->set_count = 0;
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- return(TRUE);
-}
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
-static gboolean namedevent_reset (gpointer handle)
-{
- struct _WapiHandle_namedevent *namedevent_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
- (gpointer *)&namedevent_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named event handle %p",
- __func__, handle);
- return(FALSE);
- }
+ /* For a manual-reset event, we're about to try and get the handle
+ * lock again, so give other threads a chance */
+ sched_yield ();
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Resetting named event handle %p", __func__, handle);
+ /* Reset the handle signal state */
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (_wapi_handle_issignalled (handle) == FALSE) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: No need to reset named event handle %p",
- __func__, handle);
- } else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Obtained write lock on named event handle %p",
- __func__, handle);
+ /* I'm not sure whether or not we need a barrier here to make sure
+ * that all threads waiting on the event have proceeded. Currently
+ * we rely on broadcasting a condition. */
+
+ thr_ret = mono_w32handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
}
-
- namedevent_handle->set_count = 0;
-
- thr_ret = _wapi_handle_unlock_handle (handle);
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
-
- return(TRUE);
+
+ return TRUE;
}
/**
*/
gboolean ResetEvent(gpointer handle)
{
- WapiHandleType type;
+ MonoW32HandleType type;
+ struct _WapiHandle_event *event_handle;
+ int thr_ret;
+
+ SetLastError (ERROR_SUCCESS);
if (handle == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- type = _wapi_handle_type (handle);
-
- if (event_ops[type].reset == NULL) {
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_EVENT:
+ case MONO_W32HANDLE_NAMEDEVENT:
+ break;
+ default:
SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(event_ops[type].reset (handle));
-}
-static gboolean event_set (gpointer handle)
-{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up event handle %p", __func__,
- handle);
- return(FALSE);
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+ return FALSE;
}
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Setting event handle %p", __func__, handle);
-
- if (event_handle->manual == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
- } else {
- event_handle->set_count = 1;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: resetting %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- return(TRUE);
-}
-static gboolean namedevent_set (gpointer handle)
-{
- struct _WapiHandle_namedevent *namedevent_handle;
- gboolean ok;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
- (gpointer *)&namedevent_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named event handle %p",
- __func__, handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Setting named event handle %p", __func__, handle);
-
- if (namedevent_handle->manual == TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ if (!mono_w32handle_issignalled (handle)) {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: no need to reset %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
} else {
- namedevent_handle->set_count = 1;
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: obtained write lock on %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
}
- thr_ret = _wapi_handle_unlock_handle (handle);
+ event_handle->set_count = 0;
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- return(TRUE);
+ return TRUE;
}
/**
*/
gboolean SetEvent(gpointer handle)
{
- WapiHandleType type;
+ MonoW32HandleType type;
+ struct _WapiHandle_event *event_handle;
+ int thr_ret;
if (handle == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- type = _wapi_handle_type (handle);
-
- if (event_ops[type].set == NULL) {
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_EVENT:
+ case MONO_W32HANDLE_NAMEDEVENT:
+ break;
+ default:
SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
+ return FALSE;
}
-
- return(event_ops[type].set (handle));
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&event_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+ return FALSE;
+ }
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: setting %s handle %p",
+ __func__, event_handle_type_to_string (type), handle);
+
+ thr_ret = mono_w32handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ if (!event_handle->manual) {
+ event_handle->set_count = 1;
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+ } else {
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
+ }
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ return TRUE;
}
gpointer OpenEvent (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, const gunichar2 *name)
gpointer handle;
gchar *utf8_name;
int thr_ret;
-
- mono_once (&event_ops_once, event_ops_init);
/* w32 seems to guarantee that opening named objects can't
* race each other
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named event [%s]", __func__, utf8_name);
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDEVENT,
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDEVENT,
utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
+ if (handle == INVALID_HANDLE_VALUE) {
/* The name has already been used for a different
* object.
*/
+++ /dev/null
-/*
- * handles-private.h: Internal operations on handles
- *
- * Author:
- * Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2006 Novell, Inc.
- */
-
-#ifndef _WAPI_HANDLES_PRIVATE_H_
-#define _WAPI_HANDLES_PRIVATE_H_
-
-#include <config.h>
-#include <glib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/shared.h>
-#include <mono/utils/atomic.h>
-
-#define _WAPI_PRIVATE_MAX_SLOTS (1024 * 16)
-#define _WAPI_PRIVATE_HANDLES(x) (_wapi_private_handles [x / _WAPI_HANDLE_INITIAL_COUNT][x % _WAPI_HANDLE_INITIAL_COUNT])
-#define _WAPI_PRIVATE_HAVE_SLOT(x) ((GPOINTER_TO_UINT (x) / _WAPI_PRIVATE_MAX_SLOTS) < _WAPI_PRIVATE_MAX_SLOTS && \
- _wapi_private_handles [GPOINTER_TO_UINT (x) / _WAPI_HANDLE_INITIAL_COUNT] != NULL)
-#define _WAPI_PRIVATE_VALID_SLOT(x) (((x) / _WAPI_HANDLE_INITIAL_COUNT) < _WAPI_PRIVATE_MAX_SLOTS)
-
-#undef DEBUG
-
-extern struct _WapiHandleUnshared *_wapi_private_handles [];
-
-extern guint32 _wapi_fd_reserve;
-extern gpointer _wapi_global_signal_handle;
-extern mono_mutex_t *_wapi_global_signal_mutex;
-extern mono_cond_t *_wapi_global_signal_cond;
-extern int _wapi_sem_id;
-extern gboolean _wapi_has_shut_down;
-
-extern pid_t _wapi_getpid (void);
-extern gpointer _wapi_handle_new (WapiHandleType type,
- gpointer handle_specific);
-extern gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
- gpointer handle_specific);
-extern gboolean _wapi_lookup_handle (gpointer handle, WapiHandleType type,
- gpointer *handle_specific);
-extern gpointer _wapi_search_handle (WapiHandleType type,
- gboolean (*check)(gpointer, gpointer),
- gpointer user_data,
- gpointer *handle_specific,
- gboolean search_shared);
-extern gpointer _wapi_search_handle_namespace (WapiHandleType type,
- gchar *utf8_name);
-extern void _wapi_handle_ref (gpointer handle);
-extern void _wapi_handle_unref (gpointer handle);
-extern void _wapi_handle_register_capabilities (WapiHandleType type,
- WapiHandleCapability caps);
-extern gboolean _wapi_handle_test_capabilities (gpointer handle,
- WapiHandleCapability caps);
-extern void _wapi_handle_ops_close (gpointer handle, gpointer data);
-extern void _wapi_handle_ops_signal (gpointer handle);
-extern gboolean _wapi_handle_ops_own (gpointer handle);
-extern gboolean _wapi_handle_ops_isowned (gpointer handle);
-extern guint32 _wapi_handle_ops_special_wait (gpointer handle,
- guint32 timeout,
- gboolean alertable);
-extern void _wapi_handle_ops_prewait (gpointer handle);
-
-extern gboolean _wapi_handle_count_signalled_handles (guint32 numhandles,
- gpointer *handles,
- gboolean waitall,
- guint32 *retcount,
- guint32 *lowest);
-extern void _wapi_handle_unlock_handles (guint32 numhandles,
- gpointer *handles);
-extern int _wapi_handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted);
-extern gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
- guint32 new_sharemode,
- guint32 new_access,
- guint32 *old_sharemode,
- guint32 *old_access,
- struct _WapiFileShare **info);
-extern void _wapi_handle_dump (void);
-extern void _wapi_handle_foreach (WapiHandleType type,
- gboolean (*on_each)(gpointer test, gpointer user),
- gpointer user_data);
-void _wapi_free_share_info (_WapiFileShare *share_info);
-
-static inline WapiHandleType _wapi_handle_type (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx) || !_WAPI_PRIVATE_HAVE_SLOT (idx)) {
- return(WAPI_HANDLE_UNUSED); /* An impossible type */
- }
-
- return(_WAPI_PRIVATE_HANDLES(idx).type);
-}
-
-static inline void _wapi_handle_set_signal_state (gpointer handle,
- gboolean state,
- gboolean broadcast)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- struct _WapiHandleUnshared *handle_data;
- int thr_ret;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- handle_data = &_WAPI_PRIVATE_HANDLES(idx);
-
-#ifdef DEBUG
- g_message ("%s: setting state of %p to %s (broadcast %s)", __func__,
- handle, state?"TRUE":"FALSE", broadcast?"TRUE":"FALSE");
-#endif
-
- if (state == TRUE) {
- /* Tell everyone blocking on a single handle */
-
- /* The condition the global signal cond is waiting on is the signalling of
- * _any_ handle. So lock it before setting the signalled state.
- */
- thr_ret = mono_os_mutex_lock (_wapi_global_signal_mutex);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_mutex_lock result %d for global signal mutex", thr_ret);
- g_assert (thr_ret == 0);
-
- /* This function _must_ be called with
- * handle->signal_mutex locked
- */
- handle_data->signalled=state;
-
- if (broadcast == TRUE) {
- thr_ret = mono_os_cond_broadcast (&handle_data->signal_cond);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_cond_broadcast result %d for handle %p", thr_ret, handle);
- g_assert (thr_ret == 0);
- } else {
- thr_ret = mono_os_cond_signal (&handle_data->signal_cond);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_cond_signal result %d for handle %p", thr_ret, handle);
- g_assert (thr_ret == 0);
- }
-
- /* Tell everyone blocking on multiple handles that something
- * was signalled
- */
- thr_ret = mono_os_cond_broadcast (_wapi_global_signal_cond);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_cond_broadcast result %d for handle %p", thr_ret, handle);
- g_assert (thr_ret == 0);
-
- thr_ret = mono_os_mutex_unlock (_wapi_global_signal_mutex);
- if (thr_ret != 0)
- g_warning ("Bad call to mono_os_mutex_unlock result %d for global signal mutex", thr_ret);
- g_assert (thr_ret == 0);
- } else {
- handle_data->signalled=state;
- }
-}
-
-static inline gboolean _wapi_handle_issignalled (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(FALSE);
- }
-
- return _WAPI_PRIVATE_HANDLES (idx).signalled;
-}
-
-static inline int _wapi_handle_lock_signal_mutex (void)
-{
-#ifdef DEBUG
- g_message ("%s: lock global signal mutex", __func__);
-#endif
-
- return(mono_os_mutex_lock (_wapi_global_signal_mutex));
-}
-
-/* the parameter makes it easier to call from a pthread cleanup handler */
-static inline int _wapi_handle_unlock_signal_mutex (void *unused)
-{
-#ifdef DEBUG
- g_message ("%s: unlock global signal mutex", __func__);
-#endif
-
- return(mono_os_mutex_unlock (_wapi_global_signal_mutex));
-}
-
-static inline int _wapi_handle_lock_handle (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
-
-#ifdef DEBUG
- g_message ("%s: locking handle %p", __func__, handle);
-#endif
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(0);
- }
-
- _wapi_handle_ref (handle);
-
- return(mono_os_mutex_lock (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex));
-}
-
-static inline int _wapi_handle_trylock_handle (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- int ret;
-
-#ifdef DEBUG
- g_message ("%s: locking handle %p", __func__, handle);
-#endif
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(0);
- }
-
- _wapi_handle_ref (handle);
-
- ret = mono_os_mutex_trylock (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
- if (ret != 0) {
- _wapi_handle_unref (handle);
- }
-
- return(ret);
-}
-
-static inline int _wapi_handle_unlock_handle (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- int ret;
-
-#ifdef DEBUG
- g_message ("%s: unlocking handle %p", __func__, handle);
-#endif
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(0);
- }
-
- ret = mono_os_mutex_unlock (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
-
- _wapi_handle_unref (handle);
-
- return(ret);
-}
-
-static inline void _wapi_handle_spin (guint32 ms)
-{
- struct timespec sleepytime;
-
- g_assert (ms < 1000);
-
- sleepytime.tv_sec = 0;
- sleepytime.tv_nsec = ms * 1000000;
-
- nanosleep (&sleepytime, NULL);
-}
-
-static inline int _wapi_namespace_lock (void)
-{
- return(_wapi_shm_sem_lock (_WAPI_SHARED_SEM_NAMESPACE));
-}
-
-/* This signature makes it easier to use in pthread cleanup handlers */
-static inline int _wapi_namespace_unlock (gpointer data G_GNUC_UNUSED)
-{
- return(_wapi_shm_sem_unlock (_WAPI_SHARED_SEM_NAMESPACE));
-}
-
-static inline void _wapi_handle_share_release (struct _WapiFileShare *info)
-{
- int thr_ret;
-
- g_assert (info->handle_refs > 0);
-
- /* Prevent new entries racing with us */
- thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert(thr_ret == 0);
-
- if (InterlockedDecrement ((gint32 *)&info->handle_refs) == 0) {
- _wapi_free_share_info (info);
- }
-
- thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-}
-
-#endif /* _WAPI_HANDLES_PRIVATE_H_ */
+++ /dev/null
-/*
- * handles.c: Generic and internal operations on handles
- *
- * Author:
- * Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2011 Novell, Inc.
- * Copyright 2011 Xamarin Inc
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#include <string.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UN_H
-# include <sys/un.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-# include <sys/mman.h>
-#endif
-#ifdef HAVE_DIRENT_H
-# include <dirent.h>
-#endif
-#include <sys/stat.h>
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
-
-#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/shared.h>
-#include <mono/io-layer/process-private.h>
-#include <mono/io-layer/io-trace.h>
-
-#include <mono/utils/mono-os-mutex.h>
-#include <mono/utils/mono-proclib.h>
-#include <mono/utils/mono-threads.h>
-#include <mono/utils/mono-once.h>
-#include <mono/utils/mono-logger-internals.h>
-#undef DEBUG_REFS
-
-static void (*_wapi_handle_ops_get_close_func (WapiHandleType type))(gpointer, gpointer);
-
-static WapiHandleCapability handle_caps[WAPI_HANDLE_COUNT] = { (WapiHandleCapability)0 };
-static struct _WapiHandleOps *handle_ops[WAPI_HANDLE_COUNT]={
- NULL,
- &_wapi_file_ops,
- &_wapi_console_ops,
- &_wapi_thread_ops,
- &_wapi_sem_ops,
- &_wapi_mutex_ops,
- &_wapi_event_ops,
-#ifndef DISABLE_SOCKETS
- &_wapi_socket_ops,
-#endif
- &_wapi_find_ops,
- &_wapi_process_ops,
- &_wapi_pipe_ops,
- &_wapi_namedmutex_ops,
- &_wapi_namedsem_ops,
- &_wapi_namedevent_ops,
-};
-
-static void _wapi_shared_details (gpointer handle_info);
-
-static void (*handle_details[WAPI_HANDLE_COUNT])(gpointer) = {
- NULL,
- _wapi_file_details,
- _wapi_console_details,
- _wapi_shared_details, /* thread */
- _wapi_sem_details,
- _wapi_mutex_details,
- _wapi_event_details,
- NULL, /* Nothing useful to see in a socket handle */
- NULL, /* Nothing useful to see in a find handle */
- _wapi_shared_details, /* process */
- _wapi_pipe_details,
- _wapi_shared_details, /* namedmutex */
- _wapi_shared_details, /* namedsem */
- _wapi_shared_details, /* namedevent */
-};
-
-const char *_wapi_handle_typename[] = {
- "Unused",
- "File",
- "Console",
- "Thread",
- "Sem",
- "Mutex",
- "Event",
- "Socket",
- "Find",
- "Process",
- "Pipe",
- "N.Mutex",
- "N.Sem",
- "N.Event",
- "Error!!"
-};
-
-/*
- * We can hold _WAPI_PRIVATE_MAX_SLOTS * _WAPI_HANDLE_INITIAL_COUNT handles.
- * If 4M handles are not enough... Oh, well... we will crash.
- */
-#define SLOT_INDEX(x) (x / _WAPI_HANDLE_INITIAL_COUNT)
-#define SLOT_OFFSET(x) (x % _WAPI_HANDLE_INITIAL_COUNT)
-
-struct _WapiHandleUnshared *_wapi_private_handles [_WAPI_PRIVATE_MAX_SLOTS];
-static guint32 _wapi_private_handle_count = 0;
-static guint32 _wapi_private_handle_slot_count = 0;
-
-/*
- * If SHM is disabled, this will point to a hash of _WapiFileShare structures, otherwise
- * it will be NULL. We use this instead of _wapi_fileshare_layout to avoid allocating a
- * 4MB array.
- */
-static GHashTable *file_share_hash;
-static mono_mutex_t file_share_hash_mutex;
-
-#define file_share_hash_lock() mono_os_mutex_lock (&file_share_hash_mutex)
-#define file_share_hash_unlock() mono_os_mutex_unlock (&file_share_hash_mutex)
-
-guint32 _wapi_fd_reserve;
-
-/*
- * This is an internal handle which is used for handling waiting for multiple handles.
- * Threads which wait for multiple handles wait on this one handle, and when a handle
- * is signalled, this handle is signalled too.
- */
-gpointer _wapi_global_signal_handle;
-
-/* Point to the mutex/cond inside _wapi_global_signal_handle */
-mono_mutex_t *_wapi_global_signal_mutex;
-mono_cond_t *_wapi_global_signal_cond;
-
-int _wapi_sem_id;
-gboolean _wapi_has_shut_down = FALSE;
-
-/* Use this instead of getpid(), to cope with linuxthreads. It's a
- * function rather than a variable lookup because we need to get at
- * this before share_init() might have been called.
- */
-static pid_t _wapi_pid;
-static mono_once_t pid_init_once = MONO_ONCE_INIT;
-
-static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles);
-
-static void pid_init (void)
-{
- _wapi_pid = getpid ();
-}
-
-pid_t _wapi_getpid (void)
-{
- mono_once (&pid_init_once, pid_init);
-
- return(_wapi_pid);
-}
-
-
-static mono_mutex_t scan_mutex;
-
-static void handle_cleanup (void)
-{
- int i, j, k;
-
- /* Every shared handle we were using ought really to be closed
- * by now, but to make sure just blow them all away. The
- * exiting finalizer thread in particular races us to the
- * program exit and doesn't always win, so it can be left
- * cluttering up the shared file. Anything else left over is
- * really a bug.
- */
- for(i = SLOT_INDEX (0); _wapi_private_handles[i] != NULL; i++) {
- for(j = SLOT_OFFSET (0); j < _WAPI_HANDLE_INITIAL_COUNT; j++) {
- struct _WapiHandleUnshared *handle_data = &_wapi_private_handles[i][j];
- gpointer handle = GINT_TO_POINTER (i*_WAPI_HANDLE_INITIAL_COUNT+j);
-
- for(k = handle_data->ref; k > 0; k--) {
- _wapi_handle_unref_full (handle, TRUE);
- }
- }
- }
-
- _wapi_shm_semaphores_remove ();
-
- if (file_share_hash) {
- g_hash_table_destroy (file_share_hash);
- mono_os_mutex_destroy (&file_share_hash_mutex);
- }
-
- for (i = 0; i < _WAPI_PRIVATE_MAX_SLOTS; ++i)
- g_free (_wapi_private_handles [i]);
-}
-
-int
-wapi_getdtablesize (void)
-{
- return eg_getdtablesize ();
-}
-
-/*
- * wapi_init:
- *
- * Initialize the io-layer.
- */
-void
-wapi_init (void)
-{
- g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
- == WAPI_HANDLE_COUNT);
-
- _wapi_fd_reserve = wapi_getdtablesize ();
-
- /* This is needed by the code in _wapi_handle_new_internal */
- _wapi_fd_reserve = (_wapi_fd_reserve + (_WAPI_HANDLE_INITIAL_COUNT - 1)) & ~(_WAPI_HANDLE_INITIAL_COUNT - 1);
-
- do {
- /*
- * The entries in _wapi_private_handles reserved for fds are allocated lazily to
- * save memory.
- */
- /*
- _wapi_private_handles [idx++] = g_new0 (struct _WapiHandleUnshared,
- _WAPI_HANDLE_INITIAL_COUNT);
- */
-
- _wapi_private_handle_count += _WAPI_HANDLE_INITIAL_COUNT;
- _wapi_private_handle_slot_count ++;
- } while(_wapi_fd_reserve > _wapi_private_handle_count);
-
- _wapi_shm_semaphores_init ();
-
- _wapi_io_init ();
- mono_os_mutex_init (&scan_mutex);
-
- _wapi_global_signal_handle = _wapi_handle_new (WAPI_HANDLE_EVENT, NULL);
-
- _wapi_global_signal_cond = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_cond;
- _wapi_global_signal_mutex = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_mutex;
-
- wapi_processes_init ();
-}
-
-void
-wapi_cleanup (void)
-{
- g_assert (_wapi_has_shut_down == FALSE);
-
- _wapi_has_shut_down = TRUE;
-
- _wapi_error_cleanup ();
- _wapi_thread_cleanup ();
- wapi_processes_cleanup ();
- handle_cleanup ();
-}
-
-static size_t _wapi_handle_struct_size (WapiHandleType type)
-{
- size_t type_size;
-
- switch (type) {
- case WAPI_HANDLE_FILE: case WAPI_HANDLE_CONSOLE: case WAPI_HANDLE_PIPE:
- type_size = sizeof (struct _WapiHandle_file);
- break;
- case WAPI_HANDLE_THREAD:
- type_size = sizeof (struct _WapiHandle_thread);
- break;
- case WAPI_HANDLE_SEM:
- type_size = sizeof (struct _WapiHandle_sem);
- break;
- case WAPI_HANDLE_MUTEX:
- type_size = sizeof (struct _WapiHandle_mutex);
- break;
- case WAPI_HANDLE_EVENT:
- type_size = sizeof (struct _WapiHandle_event);
- break;
- case WAPI_HANDLE_SOCKET:
- type_size = sizeof (struct _WapiHandle_socket);
- break;
- case WAPI_HANDLE_FIND:
- type_size = sizeof (struct _WapiHandle_find);
- break;
- case WAPI_HANDLE_PROCESS:
- type_size = sizeof (struct _WapiHandle_process);
- break;
- case WAPI_HANDLE_NAMEDMUTEX:
- type_size = sizeof (struct _WapiHandle_namedmutex);
- break;
- case WAPI_HANDLE_NAMEDSEM:
- type_size = sizeof (struct _WapiHandle_namedsem);
- break;
- case WAPI_HANDLE_NAMEDEVENT:
- type_size = sizeof (struct _WapiHandle_namedevent);
- break;
-
- default:
- g_error ("Unknown WapiHandleType: %d\n", type);
- }
-
- return type_size;
-}
-
-static void _wapi_handle_init (struct _WapiHandleUnshared *handle,
- WapiHandleType type, gpointer handle_specific)
-{
- int thr_ret;
- int type_size;
-
- g_assert (_wapi_has_shut_down == FALSE);
-
- handle->type = type;
- handle->signalled = FALSE;
- handle->ref = 1;
-
- thr_ret = mono_os_cond_init (&handle->signal_cond);
- g_assert (thr_ret == 0);
-
- thr_ret = mono_os_mutex_init (&handle->signal_mutex);
- g_assert (thr_ret == 0);
-
- if (handle_specific != NULL) {
- type_size = _wapi_handle_struct_size (type);
- memcpy (&handle->u, handle_specific,
- type_size);
- }
-}
-
-/*
- * _wapi_handle_new_internal:
- * @type: Init handle to this type
- *
- * Search for a free handle and initialize it. Return the handle on
- * success and 0 on failure. This is only called from
- * _wapi_handle_new, and scan_mutex must be held.
- */
-static guint32 _wapi_handle_new_internal (WapiHandleType type,
- gpointer handle_specific)
-{
- guint32 i, k, count;
- static guint32 last = 0;
- gboolean retry = FALSE;
-
- g_assert (_wapi_has_shut_down == FALSE);
-
- /* A linear scan should be fast enough. Start from the last
- * allocation, assuming that handles are allocated more often
- * than they're freed. Leave the space reserved for file
- * descriptors
- */
-
- if (last < _wapi_fd_reserve) {
- last = _wapi_fd_reserve;
- } else {
- retry = TRUE;
- }
-
-again:
- count = last;
- for(i = SLOT_INDEX (count); i < _wapi_private_handle_slot_count; i++) {
- if (_wapi_private_handles [i]) {
- for (k = SLOT_OFFSET (count); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- struct _WapiHandleUnshared *handle = &_wapi_private_handles [i][k];
-
- if(handle->type == WAPI_HANDLE_UNUSED) {
- last = count + 1;
-
- _wapi_handle_init (handle, type, handle_specific);
- return (count);
- }
- count++;
- }
- }
- }
-
- if(retry && last > _wapi_fd_reserve) {
- /* Try again from the beginning */
- last = _wapi_fd_reserve;
- goto again;
- }
-
- /* Will need to expand the array. The caller will sort it out */
-
- return(0);
-}
-
-gpointer
-_wapi_handle_new (WapiHandleType type, gpointer handle_specific)
-{
- guint32 handle_idx = 0;
- gpointer handle;
- int thr_ret;
-
- g_assert (_wapi_has_shut_down == FALSE);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating new handle of type %s", __func__,
- _wapi_handle_typename[type]);
-
- g_assert(!_WAPI_FD_HANDLE(type));
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- while ((handle_idx = _wapi_handle_new_internal (type, handle_specific)) == 0) {
- /* Try and expand the array, and have another go */
- int idx = SLOT_INDEX (_wapi_private_handle_count);
- if (idx >= _WAPI_PRIVATE_MAX_SLOTS) {
- break;
- }
-
- _wapi_private_handles [idx] = g_new0 (struct _WapiHandleUnshared,
- _WAPI_HANDLE_INITIAL_COUNT);
-
- _wapi_private_handle_count += _WAPI_HANDLE_INITIAL_COUNT;
- _wapi_private_handle_slot_count ++;
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- if (handle_idx == 0) {
- /* We ran out of slots */
- handle = _WAPI_HANDLE_INVALID;
- goto done;
- }
-
- /* Make sure we left the space for fd mappings */
- g_assert (handle_idx >= _wapi_fd_reserve);
-
- handle = GUINT_TO_POINTER (handle_idx);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Allocated new handle %p", __func__, handle);
-
-done:
- return(handle);
-}
-
-static void
-init_handles_slot (int idx)
-{
- int thr_ret;
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- if (_wapi_private_handles [idx] == NULL) {
- _wapi_private_handles [idx] = g_new0 (struct _WapiHandleUnshared,
- _WAPI_HANDLE_INITIAL_COUNT);
- g_assert (_wapi_private_handles [idx]);
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-}
-
-gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
- gpointer handle_specific)
-{
- struct _WapiHandleUnshared *handle;
- int thr_ret;
-
- g_assert (_wapi_has_shut_down == FALSE);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating new handle of type %s", __func__,
- _wapi_handle_typename[type]);
-
- g_assert(_WAPI_FD_HANDLE(type));
-
- if (fd >= _wapi_fd_reserve) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d is too big", __func__, fd);
-
- return(GUINT_TO_POINTER (_WAPI_HANDLE_INVALID));
- }
-
- /* Initialize the array entries on demand */
- if (_wapi_private_handles [SLOT_INDEX (fd)] == NULL)
- init_handles_slot (SLOT_INDEX (fd));
-
- handle = &_WAPI_PRIVATE_HANDLES(fd);
-
- if (handle->type != WAPI_HANDLE_UNUSED) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d is already in use!", __func__, fd);
- /* FIXME: clean up this handle? We can't do anything
- * with the fd, cos thats the new one
- */
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Assigning new fd handle %d", __func__, fd);
-
- /* Prevent file share entries racing with us, when the file
- * handle is only half initialised
- */
- thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert(thr_ret == 0);
-
- _wapi_handle_init (handle, type, handle_specific);
-
- thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-
- return(GUINT_TO_POINTER(fd));
-}
-
-gboolean
-_wapi_lookup_handle (gpointer handle, WapiHandleType type,
- gpointer *handle_specific)
-{
- struct _WapiHandleUnshared *handle_data;
- guint32 handle_idx = GPOINTER_TO_UINT(handle);
-
- if (!_WAPI_PRIVATE_VALID_SLOT (handle_idx)) {
- return(FALSE);
- }
-
- /* Initialize the array entries on demand */
- if (_wapi_private_handles [SLOT_INDEX (handle_idx)] == NULL)
- init_handles_slot (SLOT_INDEX (handle_idx));
-
- handle_data = &_WAPI_PRIVATE_HANDLES(handle_idx);
-
- if (handle_data->type != type) {
- return(FALSE);
- }
-
- if (handle_specific == NULL) {
- return(FALSE);
- }
-
- *handle_specific = &handle_data->u;
-
- return(TRUE);
-}
-
-void
-_wapi_handle_foreach (WapiHandleType type,
- gboolean (*on_each)(gpointer test, gpointer user),
- gpointer user_data)
-{
- struct _WapiHandleUnshared *handle_data = NULL;
- gpointer ret = NULL;
- guint32 i, k;
- int thr_ret;
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- for (i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
- if (_wapi_private_handles [i]) {
- for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- handle_data = &_wapi_private_handles [i][k];
-
- if (handle_data->type == type) {
- ret = GUINT_TO_POINTER (i * _WAPI_HANDLE_INITIAL_COUNT + k);
- if (on_each (ret, user_data) == TRUE)
- break;
- }
- }
- }
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-}
-
-/* This might list some shared handles twice if they are already
- * opened by this process, and the check function returns FALSE the
- * first time. Shared handles that are created during the search are
- * unreffed if the check function returns FALSE, so callers must not
- * rely on the handle persisting (unless the check function returns
- * TRUE)
- * The caller owns the returned handle.
- */
-gpointer _wapi_search_handle (WapiHandleType type,
- gboolean (*check)(gpointer test, gpointer user),
- gpointer user_data,
- gpointer *handle_specific,
- gboolean search_shared)
-{
- struct _WapiHandleUnshared *handle_data = NULL;
- gpointer ret = NULL;
- guint32 i, k;
- gboolean found = FALSE;
- int thr_ret;
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- for (i = SLOT_INDEX (0); !found && i < _wapi_private_handle_slot_count; i++) {
- if (_wapi_private_handles [i]) {
- for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- handle_data = &_wapi_private_handles [i][k];
-
- if (handle_data->type == type) {
- ret = GUINT_TO_POINTER (i * _WAPI_HANDLE_INITIAL_COUNT + k);
- if (check (ret, user_data) == TRUE) {
- _wapi_handle_ref (ret);
- found = TRUE;
- break;
- }
- }
- }
- }
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- if (!found) {
- ret = NULL;
- goto done;
- }
-
- if(handle_specific != NULL) {
- *handle_specific = &handle_data->u;
- }
-
-done:
- return(ret);
-}
-
-/* Returns the offset of the metadata array, or _WAPI_HANDLE_INVALID on error, or NULL for
- * not found
- */
-gpointer _wapi_search_handle_namespace (WapiHandleType type,
- gchar *utf8_name)
-{
- struct _WapiHandleUnshared *handle_data;
- guint32 i, k;
- gpointer ret = NULL;
- int thr_ret;
-
- g_assert(_WAPI_SHARED_NAMESPACE(type));
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Lookup for handle named [%s] type %s", __func__,
- utf8_name, _wapi_handle_typename[type]);
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- for(i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
- if (!_wapi_private_handles [i])
- continue;
- for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- WapiSharedNamespace *sharedns;
-
- handle_data = &_wapi_private_handles [i][k];
-
- /* Check mutex, event, semaphore, timer, job and
- * file-mapping object names. So far only mutex,
- * semaphore and event are implemented.
- */
- if (!_WAPI_SHARED_NAMESPACE (handle_data->type)) {
- continue;
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: found a shared namespace handle at 0x%x (type %s)", __func__, i, _wapi_handle_typename[handle_data->type]);
-
- sharedns=(WapiSharedNamespace *)&handle_data->u;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is [%s]", __func__, sharedns->name);
-
- if (strcmp (sharedns->name, utf8_name) == 0) {
- if (handle_data->type != type) {
- /* Its the wrong type, so fail now */
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle 0x%x matches name but is wrong type: %s", __func__, i, _wapi_handle_typename[handle_data->type]);
- ret = _WAPI_HANDLE_INVALID;
- goto done;
- } else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle 0x%x matches name and type", __func__, i);
- ret = handle_data;
- goto done;
- }
- }
- }
- }
-
-done:
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- return(ret);
-}
-
-void _wapi_handle_ref (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- struct _WapiHandleUnshared *handle_data;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Attempting to ref invalid private handle %p", __func__, handle);
- return;
- }
-
- if (_wapi_handle_type (handle) == WAPI_HANDLE_UNUSED) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Attempting to ref unused handle %p", __func__, handle);
- return;
- }
-
- handle_data = &_WAPI_PRIVATE_HANDLES(idx);
-
- InterlockedIncrement ((gint32 *)&handle_data->ref);
-
-#ifdef DEBUG_REFS
- g_message ("%s: %s handle %p ref now %d", __func__,
- _wapi_handle_typename[_WAPI_PRIVATE_HANDLES (idx).type],
- handle,
- _WAPI_PRIVATE_HANDLES(idx).ref);
-#endif
-}
-
-/* The handle must not be locked on entry to this function */
-static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- gboolean destroy = FALSE, early_exit = FALSE;
- int thr_ret;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- if (_wapi_handle_type (handle) == WAPI_HANDLE_UNUSED) {
- g_warning ("%s: Attempting to unref unused handle %p",
- __func__, handle);
- return;
- }
-
- /* Possible race condition here if another thread refs the
- * handle between here and setting the type to UNUSED. I
- * could lock a mutex, but I'm not sure that allowing a handle
- * reference to reach 0 isn't an application bug anyway.
- */
- destroy = (InterlockedDecrement ((gint32 *)&_WAPI_PRIVATE_HANDLES(idx).ref) ==0);
-
-#ifdef DEBUG_REFS
- g_message ("%s: %s handle %p ref now %d (destroy %s)", __func__,
- _wapi_handle_typename[_WAPI_PRIVATE_HANDLES (idx).type],
- handle,
- _WAPI_PRIVATE_HANDLES(idx).ref, destroy?"TRUE":"FALSE");
-#endif
-
- if(destroy==TRUE) {
- /* Need to copy the handle info, reset the slot in the
- * array, and _only then_ call the close function to
- * avoid race conditions (eg file descriptors being
- * closed, and another file being opened getting the
- * same fd racing the memset())
- */
- struct _WapiHandleUnshared handle_data;
- WapiHandleType type = _WAPI_PRIVATE_HANDLES(idx).type;
- void (*close_func)(gpointer, gpointer) = _wapi_handle_ops_get_close_func (type);
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Destroying handle %p", __func__, handle);
-
- memcpy (&handle_data, &_WAPI_PRIVATE_HANDLES(idx),
- sizeof (struct _WapiHandleUnshared));
-
- memset (&_WAPI_PRIVATE_HANDLES(idx).u, '\0',
- sizeof(_WAPI_PRIVATE_HANDLES(idx).u));
-
- _WAPI_PRIVATE_HANDLES(idx).type = WAPI_HANDLE_UNUSED;
-
- /* Destroy the mutex and cond var. We hope nobody
- * tried to grab them between the handle unlock and
- * now, but pthreads doesn't have a
- * "unlock_and_destroy" atomic function.
- */
- thr_ret = mono_os_mutex_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
- /*WARNING gross hack to make cleanup not crash when exiting without the whole runtime teardown.*/
- if (thr_ret == EBUSY && ignore_private_busy_handles) {
- early_exit = TRUE;
- } else {
- if (thr_ret != 0)
- g_error ("Error destroying handle %p mutex due to %d\n", handle, thr_ret);
-
- thr_ret = mono_os_cond_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_cond);
- if (thr_ret == EBUSY && ignore_private_busy_handles)
- early_exit = TRUE;
- else if (thr_ret != 0)
- g_error ("Error destroying handle %p cond var due to %d\n", handle, thr_ret);
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- if (early_exit)
- return;
-
- if (close_func != NULL) {
- close_func (handle, &handle_data.u);
- }
- }
-}
-
-void _wapi_handle_unref (gpointer handle)
-{
- _wapi_handle_unref_full (handle, FALSE);
-}
-
-void _wapi_handle_register_capabilities (WapiHandleType type,
- WapiHandleCapability caps)
-{
- handle_caps[type] = caps;
-}
-
-gboolean _wapi_handle_test_capabilities (gpointer handle,
- WapiHandleCapability caps)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(FALSE);
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing 0x%x against 0x%x (%d)", __func__,
- handle_caps[type], caps, handle_caps[type] & caps);
-
- return((handle_caps[type] & caps) != 0);
-}
-
-static void (*_wapi_handle_ops_get_close_func (WapiHandleType type))(gpointer, gpointer)
-{
- if (handle_ops[type] != NULL &&
- handle_ops[type]->close != NULL) {
- return (handle_ops[type]->close);
- }
-
- return (NULL);
-}
-
-void _wapi_handle_ops_close (gpointer handle, gpointer data)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL &&
- handle_ops[type]->close != NULL) {
- handle_ops[type]->close (handle, data);
- }
-}
-
-void _wapi_handle_ops_signal (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL && handle_ops[type]->signal != NULL) {
- handle_ops[type]->signal (handle);
- }
-}
-
-gboolean _wapi_handle_ops_own (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(FALSE);
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL && handle_ops[type]->own_handle != NULL) {
- return(handle_ops[type]->own_handle (handle));
- } else {
- return(FALSE);
- }
-}
-
-gboolean _wapi_handle_ops_isowned (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(FALSE);
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL && handle_ops[type]->is_owned != NULL) {
- return(handle_ops[type]->is_owned (handle));
- } else {
- return(FALSE);
- }
-}
-
-guint32 _wapi_handle_ops_special_wait (gpointer handle, guint32 timeout, gboolean alertable)
-{
- guint32 idx = GPOINTER_TO_UINT(handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return(WAIT_FAILED);
- }
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- if (handle_ops[type] != NULL &&
- handle_ops[type]->special_wait != NULL) {
- return(handle_ops[type]->special_wait (handle, timeout, alertable));
- } else {
- return(WAIT_FAILED);
- }
-}
-
-void _wapi_handle_ops_prewait (gpointer handle)
-{
- guint32 idx = GPOINTER_TO_UINT (handle);
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
- return;
- }
-
- type = _WAPI_PRIVATE_HANDLES (idx).type;
-
- if (handle_ops[type] != NULL &&
- handle_ops[type]->prewait != NULL) {
- handle_ops[type]->prewait (handle);
- }
-}
-
-
-/**
- * CloseHandle:
- * @handle: The handle to release
- *
- * Closes and invalidates @handle, releasing any resources it
- * consumes. When the last handle to a temporary or non-persistent
- * object is closed, that object can be deleted. Closing the same
- * handle twice is an error.
- *
- * Return value: %TRUE on success, %FALSE otherwise.
- */
-gboolean CloseHandle(gpointer handle)
-{
- if (handle == NULL) {
- /* Problem: because we map file descriptors to the
- * same-numbered handle we can't tell the difference
- * between a bogus handle and the handle to stdin.
- * Assume that it's the console handle if that handle
- * exists...
- */
- if (_WAPI_PRIVATE_HANDLES (0).type != WAPI_HANDLE_CONSOLE) {
- SetLastError (ERROR_INVALID_PARAMETER);
- return(FALSE);
- }
- }
- if (handle == _WAPI_HANDLE_INVALID){
- SetLastError (ERROR_INVALID_PARAMETER);
- return(FALSE);
- }
-
- _wapi_handle_unref (handle);
-
- return(TRUE);
-}
-
-/* Lots more to implement here, but this is all we need at the moment */
-gboolean DuplicateHandle (gpointer srcprocess, gpointer src,
- gpointer targetprocess, gpointer *target,
- guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 options G_GNUC_UNUSED)
-{
- if (srcprocess != _WAPI_PROCESS_CURRENT ||
- targetprocess != _WAPI_PROCESS_CURRENT) {
- /* Duplicating other process's handles is not supported */
- SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
-
- if (src == _WAPI_PROCESS_CURRENT) {
- *target = _wapi_process_duplicate ();
- } else if (src == _WAPI_THREAD_CURRENT) {
- g_assert_not_reached ();
- } else {
- _wapi_handle_ref (src);
- *target = src;
- }
-
- return(TRUE);
-}
-
-gboolean _wapi_handle_count_signalled_handles (guint32 numhandles,
- gpointer *handles,
- gboolean waitall,
- guint32 *retcount,
- guint32 *lowest)
-{
- guint32 count, i, iter=0;
- gboolean ret;
- int thr_ret;
- WapiHandleType type;
-
- /* Lock all the handles, with backoff */
-again:
- for(i=0; i<numhandles; i++) {
- gpointer handle = handles[i];
- guint32 idx = GPOINTER_TO_UINT(handle);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempting to lock %p", __func__, handle);
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- thr_ret = _wapi_handle_trylock_handle (handle);
-
- if (thr_ret != 0) {
- /* Bummer */
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempt failed for %p: %s", __func__,
- handle, strerror (thr_ret));
-
- while (i--) {
- handle = handles[i];
- idx = GPOINTER_TO_UINT(handle);
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- }
-
- /* If iter ever reaches 100 the nanosleep will
- * return EINVAL immediately, but we have a
- * design flaw if that happens.
- */
- iter++;
- if(iter==100) {
- g_warning ("%s: iteration overflow!",
- __func__);
- iter=1;
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Backing off for %d ms", __func__,
- iter*10);
- _wapi_handle_spin (10 * iter);
-
- goto again;
- }
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Locked all handles", __func__);
-
- count=0;
- *lowest=numhandles;
-
- for(i=0; i<numhandles; i++) {
- gpointer handle = handles[i];
- guint32 idx = GPOINTER_TO_UINT(handle);
-
- type = _WAPI_PRIVATE_HANDLES(idx).type;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Checking handle %p", __func__, handle);
-
- if(((_wapi_handle_test_capabilities (handle, WAPI_HANDLE_CAP_OWN)==TRUE) &&
- (_wapi_handle_ops_isowned (handle) == TRUE)) ||
- (_wapi_handle_issignalled (handle))) {
- count++;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %p signalled", __func__,
- handle);
- if(*lowest>i) {
- *lowest=i;
- }
- }
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %d event handles signalled", __func__, count);
-
- if ((waitall == TRUE && count == numhandles) ||
- (waitall == FALSE && count > 0)) {
- ret=TRUE;
- } else {
- ret=FALSE;
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning %d", __func__, ret);
-
- *retcount=count;
-
- return(ret);
-}
-
-void _wapi_handle_unlock_handles (guint32 numhandles, gpointer *handles)
-{
- guint32 i;
- int thr_ret;
-
- for(i=0; i<numhandles; i++) {
- gpointer handle = handles[i];
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, handle);
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- }
-}
-
-static void
-signal_handle_and_unref (gpointer handle)
-{
- mono_cond_t *cond;
- mono_mutex_t *mutex;
- guint32 idx;
-
- g_assert (handle);
-
- /* If we reach here, then interrupt token is set to the flag value, which
- * means that the target thread is either
- * - before the first CAS in timedwait, which means it won't enter the wait.
- * - it is after the first CAS, so it is already waiting, or it will enter
- * the wait, and it will be interrupted by the broadcast. */
- idx = GPOINTER_TO_UINT (handle);
- cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
- mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
-
- mono_os_mutex_lock (mutex);
- mono_os_cond_broadcast (cond);
- mono_os_mutex_unlock (mutex);
-
- _wapi_handle_unref (handle);
-}
-
-int
-_wapi_handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted)
-{
- guint32 idx;
- int res;
- mono_cond_t *cond;
- mono_mutex_t *mutex;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: waiting for %p (type %s)", __func__, handle,
- _wapi_handle_typename[_wapi_handle_type (handle)]);
-
- if (alerted)
- *alerted = FALSE;
-
- idx = GPOINTER_TO_UINT(handle);
-
- if (alerted) {
- mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
- if (*alerted)
- return 0;
- _wapi_handle_ref (handle);
- }
-
- cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
- mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
-
- if (!poll) {
- res = mono_os_cond_timedwait (cond, mutex, timeout);
- } else {
- /* This is needed when waiting for process handles */
- if (!alerted) {
- /*
- * pthread_cond_(timed)wait() can return 0 even if the condition was not
- * signalled. This happens at least on Darwin. We surface this, i.e., we
- * get spurious wake-ups.
- *
- * http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
- */
- res = mono_os_cond_timedwait (cond, mutex, timeout);
- } else {
- if (timeout < 100) {
- /* Real timeout is less than 100ms time */
- res = mono_os_cond_timedwait (cond, mutex, timeout);
- } else {
- res = mono_os_cond_timedwait (cond, mutex, 100);
-
- /* Mask the fake timeout, this will cause
- * another poll if the cond was not really signaled
- */
- if (res == ETIMEDOUT)
- res = 0;
- }
- }
- }
-
- if (alerted) {
- mono_thread_info_uninstall_interrupt (alerted);
- if (!*alerted) {
- /* if it is alerted, then the handle is unref in the interrupt callback */
- _wapi_handle_unref (handle);
- }
- }
-
- return res;
-}
-
-void
-_wapi_free_share_info (_WapiFileShare *share_info)
-{
- file_share_hash_lock ();
- g_hash_table_remove (file_share_hash, share_info);
- file_share_hash_unlock ();
- /* The hashtable dtor frees share_info */
-}
-
-static gint
-wapi_share_info_equal (gconstpointer ka, gconstpointer kb)
-{
- const _WapiFileShare *s1 = (const _WapiFileShare *)ka;
- const _WapiFileShare *s2 = (const _WapiFileShare *)kb;
-
- return (s1->device == s2->device && s1->inode == s2->inode) ? 1 : 0;
-}
-
-static guint
-wapi_share_info_hash (gconstpointer data)
-{
- const _WapiFileShare *s = (const _WapiFileShare *)data;
-
- return s->inode;
-}
-
-gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
- guint32 new_sharemode,
- guint32 new_access,
- guint32 *old_sharemode,
- guint32 *old_access,
- struct _WapiFileShare **share_info)
-{
- struct _WapiFileShare *file_share;
- int thr_ret;
- gboolean exists = FALSE;
-
- /* Prevent new entries racing with us */
- thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert (thr_ret == 0);
-
- _WapiFileShare tmp;
-
- /*
- * Instead of allocating a 4MB array, we use a hash table to keep track of this
- * info. This is needed even if SHM is disabled, to track sharing inside
- * the current process.
- */
- if (!file_share_hash) {
- file_share_hash = g_hash_table_new_full (wapi_share_info_hash, wapi_share_info_equal, NULL, g_free);
- mono_os_mutex_init_recursive (&file_share_hash_mutex);
- }
-
- tmp.device = device;
- tmp.inode = inode;
-
- file_share_hash_lock ();
-
- file_share = (_WapiFileShare *)g_hash_table_lookup (file_share_hash, &tmp);
- if (file_share) {
- *old_sharemode = file_share->sharemode;
- *old_access = file_share->access;
- *share_info = file_share;
-
- InterlockedIncrement ((gint32 *)&file_share->handle_refs);
- exists = TRUE;
- } else {
- file_share = g_new0 (_WapiFileShare, 1);
-
- file_share->device = device;
- file_share->inode = inode;
- file_share->opened_by_pid = _wapi_getpid ();
- file_share->sharemode = new_sharemode;
- file_share->access = new_access;
- file_share->handle_refs = 1;
- *share_info = file_share;
-
- g_hash_table_insert (file_share_hash, file_share, file_share);
- }
-
- file_share_hash_unlock ();
-
- thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-
- return(exists);
-}
-
-void _wapi_handle_dump (void)
-{
- struct _WapiHandleUnshared *handle_data;
- guint32 i, k;
- int thr_ret;
-
- thr_ret = mono_os_mutex_lock (&scan_mutex);
- g_assert (thr_ret == 0);
-
- for(i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
- if (_wapi_private_handles [i]) {
- for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
- handle_data = &_wapi_private_handles [i][k];
-
- if (handle_data->type == WAPI_HANDLE_UNUSED) {
- continue;
- }
-
- g_print ("%3x [%7s] %s %d ",
- i * _WAPI_HANDLE_INITIAL_COUNT + k,
- _wapi_handle_typename[handle_data->type],
- handle_data->signalled?"Sg":"Un",
- handle_data->ref);
- if (handle_details[handle_data->type])
- handle_details[handle_data->type](&handle_data->u);
- g_print ("\n");
- }
- }
- }
-
- thr_ret = mono_os_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
-}
-
-static void _wapi_shared_details (gpointer handle_info)
-{
- struct _WapiHandle_shared_ref *shared = (struct _WapiHandle_shared_ref *)handle_info;
-
- g_print ("offset: 0x%x", shared->offset);
-}
+++ /dev/null
-/*
- * handles.h: Generic operations on handles
- *
- * Author:
- * Dick Porter (dick@ximian.com)
- *
- * (C) 2002 Ximian, Inc.
- */
-
-#ifndef _WAPI_HANDLES_H_
-#define _WAPI_HANDLES_H_
-
-#define INVALID_HANDLE_VALUE (gpointer)-1
-
-G_BEGIN_DECLS
-
-extern gboolean CloseHandle (gpointer handle);
-extern gboolean DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target, guint32 access, gboolean inherit, guint32 options);
-
-extern void wapi_init (void);
-extern void wapi_cleanup (void);
-
-int wapi_getdtablesize (void);
-
-G_END_DECLS
-
-#endif /* _WAPI_HANDLES_H_ */
#include <mono/io-layer/io.h>
#include <mono/io-layer/wapi-private.h>
-extern struct _WapiHandleOps _wapi_file_ops;
-extern struct _WapiHandleOps _wapi_console_ops;
-extern struct _WapiHandleOps _wapi_find_ops;
-extern struct _WapiHandleOps _wapi_pipe_ops;
-
extern gboolean _wapi_lock_file_region (int fd, off_t offset, off_t length);
extern gboolean _wapi_unlock_file_region (int fd, off_t offset, off_t length);
-extern void _wapi_file_details (gpointer handle_info);
-extern void _wapi_console_details (gpointer handle_info);
-extern void _wapi_pipe_details (gpointer handle_info);
extern gpointer _wapi_stdhandle_create (int fd, const gchar *name);
/* Currently used for both FILE, CONSOLE and PIPE handle types. This may
#ifdef DISABLE_IO_LAYER_TRACE
#define MONO_TRACE(...)
#else
+#include "mono/utils/mono-logger-internals.h"
#define MONO_TRACE(...) mono_trace (__VA_ARGS__)
#endif
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/io-private.h>
#include <mono/io-layer/timefuncs-private.h>
#include <mono/io-layer/thread-private.h>
#include <mono/utils/strenc.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
+
+/*
+ * If SHM is disabled, this will point to a hash of _WapiFileShare structures, otherwise
+ * it will be NULL. We use this instead of _wapi_fileshare_layout to avoid allocating a
+ * 4MB array.
+ */
+static GHashTable *file_share_hash;
+static mono_mutex_t file_share_hash_mutex;
+
+#define file_share_hash_lock() mono_os_mutex_lock (&file_share_hash_mutex)
+#define file_share_hash_unlock() mono_os_mutex_unlock (&file_share_hash_mutex)
+
+static void
+_wapi_handle_share_release (_WapiFileShare *share_info)
+{
+ int thr_ret;
+
+ g_assert (share_info->handle_refs > 0);
+
+ /* Prevent new entries racing with us */
+ thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
+ g_assert(thr_ret == 0);
+
+ if (InterlockedDecrement ((gint32 *)&share_info->handle_refs) == 0) {
+ file_share_hash_lock ();
+ g_hash_table_remove (file_share_hash, share_info);
+ file_share_hash_unlock ();
+ }
+
+ thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
+ g_assert (thr_ret == 0);
+}
+
+static gint
+wapi_share_info_equal (gconstpointer ka, gconstpointer kb)
+{
+ const _WapiFileShare *s1 = (const _WapiFileShare *)ka;
+ const _WapiFileShare *s2 = (const _WapiFileShare *)kb;
+
+ return (s1->device == s2->device && s1->inode == s2->inode) ? 1 : 0;
+}
+
+static guint
+wapi_share_info_hash (gconstpointer data)
+{
+ const _WapiFileShare *s = (const _WapiFileShare *)data;
+
+ return s->inode;
+}
+
+static gboolean
+_wapi_handle_get_or_set_share (guint64 device, guint64 inode, guint32 new_sharemode, guint32 new_access,
+ guint32 *old_sharemode, guint32 *old_access, struct _WapiFileShare **share_info)
+{
+ struct _WapiFileShare *file_share;
+ int thr_ret;
+ gboolean exists = FALSE;
+
+ /* Prevent new entries racing with us */
+ thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
+ g_assert (thr_ret == 0);
+
+ _WapiFileShare tmp;
+
+ /*
+ * Instead of allocating a 4MB array, we use a hash table to keep track of this
+ * info. This is needed even if SHM is disabled, to track sharing inside
+ * the current process.
+ */
+ if (!file_share_hash) {
+ file_share_hash = g_hash_table_new_full (wapi_share_info_hash, wapi_share_info_equal, NULL, g_free);
+ mono_os_mutex_init_recursive (&file_share_hash_mutex);
+ }
+
+ tmp.device = device;
+ tmp.inode = inode;
+
+ file_share_hash_lock ();
+
+ file_share = (_WapiFileShare *)g_hash_table_lookup (file_share_hash, &tmp);
+ if (file_share) {
+ *old_sharemode = file_share->sharemode;
+ *old_access = file_share->access;
+ *share_info = file_share;
+
+ InterlockedIncrement ((gint32 *)&file_share->handle_refs);
+ exists = TRUE;
+ } else {
+ file_share = g_new0 (_WapiFileShare, 1);
+
+ file_share->device = device;
+ file_share->inode = inode;
+ file_share->opened_by_pid = _wapi_getpid ();
+ file_share->sharemode = new_sharemode;
+ file_share->access = new_access;
+ file_share->handle_refs = 1;
+ *share_info = file_share;
+
+ g_hash_table_insert (file_share_hash, file_share, file_share);
+ }
+
+ file_share_hash_unlock ();
+
+ thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
+ g_assert (thr_ret == 0);
+
+ return(exists);
+}
static void file_close (gpointer handle, gpointer data);
+static void file_details (gpointer data);
+static const gchar* file_typename (void);
+static gsize file_typesize (void);
static WapiFileType file_getfiletype(void);
static gboolean file_read(gpointer handle, gpointer buffer,
guint32 numbytes, guint32 *bytesread,
static guint32 GetDriveTypeFromPath (const gchar *utf8_root_path_name);
/* File handle is only signalled for overlapped IO */
-struct _WapiHandleOps _wapi_file_ops = {
+static MonoW32HandleOps _wapi_file_ops = {
file_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ file_details, /* details */
+ file_typename, /* typename */
+ file_typesize, /* typesize */
};
-void _wapi_file_details (gpointer handle_info)
-{
- struct _WapiHandle_file *file = (struct _WapiHandle_file *)handle_info;
-
- g_print ("[%20s] acc: %c%c%c, shr: %c%c%c, attrs: %5u",
- file->filename,
- file->fileaccess&GENERIC_READ?'R':'.',
- file->fileaccess&GENERIC_WRITE?'W':'.',
- file->fileaccess&GENERIC_EXECUTE?'X':'.',
- file->sharemode&FILE_SHARE_READ?'R':'.',
- file->sharemode&FILE_SHARE_WRITE?'W':'.',
- file->sharemode&FILE_SHARE_DELETE?'D':'.',
- file->attrs);
-}
-
static void console_close (gpointer handle, gpointer data);
+static void console_details (gpointer data);
+static const gchar* console_typename (void);
+static gsize console_typesize (void);
static WapiFileType console_getfiletype(void);
static gboolean console_read(gpointer handle, gpointer buffer,
guint32 numbytes, guint32 *bytesread,
/* Console is mostly the same as file, except it can block waiting for
* input or output
*/
-struct _WapiHandleOps _wapi_console_ops = {
+static MonoW32HandleOps _wapi_console_ops = {
console_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ console_details, /* details */
+ console_typename, /* typename */
+ console_typesize, /* typesize */
};
-void _wapi_console_details (gpointer handle_info)
-{
- _wapi_file_details (handle_info);
-}
+static const gchar* find_typename (void);
+static gsize find_typesize (void);
-/* Find handle has no ops.
- */
-struct _WapiHandleOps _wapi_find_ops = {
+static MonoW32HandleOps _wapi_find_ops = {
NULL, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ NULL, /* details */
+ find_typename, /* typename */
+ find_typesize, /* typesize */
};
static void pipe_close (gpointer handle, gpointer data);
+static void pipe_details (gpointer data);
+static const gchar* pipe_typename (void);
+static gsize pipe_typesize (void);
static WapiFileType pipe_getfiletype (void);
static gboolean pipe_read (gpointer handle, gpointer buffer, guint32 numbytes,
guint32 *bytesread, WapiOverlapped *overlapped);
/* Pipe handles
*/
-struct _WapiHandleOps _wapi_pipe_ops = {
+static MonoW32HandleOps _wapi_pipe_ops = {
pipe_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ pipe_details, /* details */
+ pipe_typename, /* typename */
+ pipe_typesize, /* typesize */
};
-void _wapi_pipe_details (gpointer handle_info)
-{
- _wapi_file_details (handle_info);
-}
-
static const struct {
/* File, console and pipe handles */
WapiFileType (*getfiletype)(void);
const WapiFileTime *create_time,
const WapiFileTime *last_access,
const WapiFileTime *last_write);
-} io_ops[WAPI_HANDLE_COUNT]={
+} io_ops[MONO_W32HANDLE_COUNT]={
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
/* file */
{file_getfiletype,
NULL, NULL, NULL, NULL, NULL, NULL},
};
-static mono_once_t io_ops_once=MONO_ONCE_INIT;
static gboolean lock_while_writing = FALSE;
-static void io_ops_init (void)
-{
-/* _wapi_handle_register_capabilities (WAPI_HANDLE_FILE, */
-/* WAPI_HANDLE_CAP_WAIT); */
-/* _wapi_handle_register_capabilities (WAPI_HANDLE_CONSOLE, */
-/* WAPI_HANDLE_CAP_WAIT); */
-
- if (g_getenv ("MONO_STRICT_IO_EMULATION") != NULL) {
- lock_while_writing = TRUE;
- }
-}
-
/* Some utility functions.
*/
close (fd);
}
+static void file_details (gpointer data)
+{
+ struct _WapiHandle_file *file = (struct _WapiHandle_file *)data;
+
+ g_print ("[%20s] acc: %c%c%c, shr: %c%c%c, attrs: %5u",
+ file->filename,
+ file->fileaccess&GENERIC_READ?'R':'.',
+ file->fileaccess&GENERIC_WRITE?'W':'.',
+ file->fileaccess&GENERIC_EXECUTE?'X':'.',
+ file->sharemode&FILE_SHARE_READ?'R':'.',
+ file->sharemode&FILE_SHARE_WRITE?'W':'.',
+ file->sharemode&FILE_SHARE_DELETE?'D':'.',
+ file->attrs);
+}
+
+static const gchar* file_typename (void)
+{
+ return "File";
+}
+
+static gsize file_typesize (void)
+{
+ return sizeof (struct _WapiHandle_file);
+}
+
static WapiFileType file_getfiletype(void)
{
return(FILE_TYPE_DISK);
gboolean ok;
int fd, ret;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
int ret, fd;
off_t current_pos = 0;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
int whence, fd;
guint32 ret;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
off_t pos;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
int ret;
int fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
guint64 create_ticks, access_ticks, write_ticks;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
guint64 access_ticks, write_ticks;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
}
}
+static void console_details (gpointer data)
+{
+ file_details (data);
+}
+
+static const gchar* console_typename (void)
+{
+ return "Console";
+}
+
+static gsize console_typesize (void)
+{
+ return sizeof (struct _WapiHandle_file);
+}
+
static WapiFileType console_getfiletype(void)
{
return(FILE_TYPE_CHAR);
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
(gpointer *)&console_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up console handle %p", __func__,
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
(gpointer *)&console_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up console handle %p", __func__,
return(TRUE);
}
+static const gchar* find_typename (void)
+{
+ return "Find";
+}
+
+static gsize find_typesize (void)
+{
+ return sizeof (struct _WapiHandle_find);
+}
+
static void pipe_close (gpointer handle, gpointer data)
{
struct _WapiHandle_file *pipe_handle = (struct _WapiHandle_file*)data;
close (fd);
}
+static void pipe_details (gpointer data)
+{
+ file_details (data);
+}
+
+static const gchar* pipe_typename (void)
+{
+ return "Pipe";
+}
+
+static gsize pipe_typesize (void)
+{
+ return sizeof (struct _WapiHandle_file);
+}
+
static WapiFileType pipe_getfiletype(void)
{
return(FILE_TYPE_PIPE);
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_PIPE,
(gpointer *)&pipe_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up pipe handle %p", __func__,
gboolean ok;
int ret, fd;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_PIPE,
(gpointer *)&pipe_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up pipe handle %p", __func__,
mode_t perms=0666;
gchar *filename;
int fd, ret;
- WapiHandleType handle_type;
+ MonoW32HandleType handle_type;
struct stat statbuf;
-
- mono_once (&io_ops_once, io_ops_init);
if (attrs & FILE_ATTRIBUTE_TEMPORARY)
perms = 0600;
return(INVALID_HANDLE_VALUE);
}
- if (fd >= _wapi_fd_reserve) {
+ if (fd >= mono_w32handle_fd_reserve) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
SetLastError (ERROR_TOO_MANY_OPEN_FILES);
#define S_ISFIFO(m) ((m & S_IFIFO) != 0)
#endif
if (S_ISFIFO (statbuf.st_mode)) {
- handle_type = WAPI_HANDLE_PIPE;
+ handle_type = MONO_W32HANDLE_PIPE;
/* maintain invariant that pipes have no filename */
file_handle.filename = NULL;
g_free (filename);
filename = NULL;
} else if (S_ISCHR (statbuf.st_mode)) {
- handle_type = WAPI_HANDLE_CONSOLE;
+ handle_type = MONO_W32HANDLE_CONSOLE;
} else {
- handle_type = WAPI_HANDLE_FILE;
+ handle_type = MONO_W32HANDLE_FILE;
}
- handle = _wapi_handle_new_fd (handle_type, fd, &file_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new_fd (handle_type, fd, &file_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating file handle", __func__);
g_free (filename);
close (fd);
{
struct _WapiHandle_file *file_handle;
gpointer handle;
- int thr_ret, fd;
+ int fd;
const gchar *name;
gboolean ok;
handle = GINT_TO_POINTER (fd);
- thr_ret = mono_os_mutex_lock (&stdhandle_mutex);
- g_assert (thr_ret == 0);
+ mono_os_mutex_lock (&stdhandle_mutex);
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
(gpointer *)&file_handle);
if (ok == FALSE) {
/* Need to create this console handle */
}
} else {
/* Add a reference to this handle */
- _wapi_handle_ref (handle);
+ mono_w32handle_ref (handle);
}
done:
- thr_ret = mono_os_mutex_unlock (&stdhandle_mutex);
- g_assert (thr_ret == 0);
+ mono_os_mutex_unlock (&stdhandle_mutex);
return(handle);
}
gboolean ReadFile(gpointer handle, gpointer buffer, guint32 numbytes,
guint32 *bytesread, WapiOverlapped *overlapped)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if(io_ops[type].readfile==NULL) {
SetLastError (ERROR_INVALID_HANDLE);
gboolean WriteFile(gpointer handle, gconstpointer buffer, guint32 numbytes,
guint32 *byteswritten, WapiOverlapped *overlapped)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if(io_ops[type].writefile==NULL) {
SetLastError (ERROR_INVALID_HANDLE);
*/
gboolean FlushFileBuffers(gpointer handle)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if(io_ops[type].flushfile==NULL) {
SetLastError (ERROR_INVALID_HANDLE);
*/
gboolean SetEndOfFile(gpointer handle)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].setendoffile == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
guint32 SetFilePointer(gpointer handle, gint32 movedistance,
gint32 *highmovedistance, WapiSeekMethod method)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].seek == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
*/
WapiFileType GetFileType(gpointer handle)
{
- WapiHandleType type;
-
- if (!_WAPI_PRIVATE_HAVE_SLOT (handle)) {
- SetLastError (ERROR_INVALID_HANDLE);
- return(FILE_TYPE_UNKNOWN);
- }
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].getfiletype == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
*/
guint32 GetFileSize(gpointer handle, guint32 *highsize)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].getfilesize == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
gboolean GetFileTime(gpointer handle, WapiFileTime *create_time,
WapiFileTime *last_access, WapiFileTime *last_write)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].getfiletime == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
const WapiFileTime *last_access,
const WapiFileTime *last_write)
{
- WapiHandleType type;
+ MonoW32HandleType type;
- type = _wapi_handle_type (handle);
+ type = mono_w32handle_get_type (handle);
if (io_ops[type].setfiletime == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
find_handle.num = result;
find_handle.count = 0;
- handle = _wapi_handle_new (WAPI_HANDLE_FIND, &find_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new (MONO_W32HANDLE_FIND, &find_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating find handle", __func__);
g_free (dir_part);
g_free (entry_part);
int thr_ret;
gboolean ret = FALSE;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FIND,
(gpointer *)&find_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up find handle %p", __func__,
return(FALSE);
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
retry:
g_free (utf16_basename);
cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
return(ret);
return(FALSE);
}
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND,
+ ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FIND,
(gpointer *)&find_handle);
if(ok==FALSE) {
g_warning ("%s: error looking up find handle %p", __func__,
return(FALSE);
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
g_strfreev (find_handle->namelist);
g_free (find_handle->dir_part);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
return(TRUE);
}
int filedes[2];
int ret;
- mono_once (&io_ops_once, io_ops_init);
-
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating pipe", __func__);
ret=pipe (filedes);
return(FALSE);
}
- if (filedes[0] >= _wapi_fd_reserve ||
- filedes[1] >= _wapi_fd_reserve) {
+ if (filedes[0] >= mono_w32handle_fd_reserve ||
+ filedes[1] >= mono_w32handle_fd_reserve) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
SetLastError (ERROR_TOO_MANY_OPEN_FILES);
pipe_read_handle.fd = filedes [0];
pipe_read_handle.fileaccess = GENERIC_READ;
- read_handle = _wapi_handle_new_fd (WAPI_HANDLE_PIPE, filedes[0],
+ read_handle = mono_w32handle_new_fd (MONO_W32HANDLE_PIPE, filedes[0],
&pipe_read_handle);
- if (read_handle == _WAPI_HANDLE_INVALID) {
+ if (read_handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating pipe read handle", __func__);
close (filedes[0]);
close (filedes[1]);
pipe_write_handle.fd = filedes [1];
pipe_write_handle.fileaccess = GENERIC_WRITE;
- write_handle = _wapi_handle_new_fd (WAPI_HANDLE_PIPE, filedes[1],
+ write_handle = mono_w32handle_new_fd (MONO_W32HANDLE_PIPE, filedes[1],
&pipe_write_handle);
- if (write_handle == _WAPI_HANDLE_INVALID) {
+ if (write_handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating pipe write handle", __func__);
- _wapi_handle_unref (read_handle);
+ mono_w32handle_unref (read_handle);
close (filedes[0]);
close (filedes[1]);
}
#endif
-
void
_wapi_io_init (void)
{
mono_os_mutex_init (&stdhandle_mutex);
+
+ mono_w32handle_register_ops (MONO_W32HANDLE_FILE, &_wapi_file_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_CONSOLE, &_wapi_console_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_FIND, &_wapi_find_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_PIPE, &_wapi_pipe_ops);
+
+/* mono_w32handle_register_capabilities (MONO_W32HANDLE_FILE, */
+/* MONO_W32HANDLE_CAP_WAIT); */
+/* mono_w32handle_register_capabilities (MONO_W32HANDLE_CONSOLE, */
+/* MONO_W32HANDLE_CAP_WAIT); */
+
+ if (g_getenv ("MONO_STRICT_IO_EMULATION"))
+ lock_while_writing = TRUE;
+}
+
+void
+_wapi_io_cleanup (void)
+{
+ if (file_share_hash) {
+ g_hash_table_destroy (file_share_hash);
+ mono_os_mutex_destroy (&file_share_hash_mutex);
+ }
}
extern void _wapi_io_init (void);
+extern void _wapi_io_cleanup (void);
G_END_DECLS
#include <errno.h>
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/io-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
gboolean
_wapi_lock_file_region (int fd, off_t offset, off_t length)
off_t offset, length;
int fd = GPOINTER_TO_UINT(handle);
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
off_t offset, length;
int fd = GPOINTER_TO_UINT(handle);
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up file handle %p", __func__,
#include <pthread.h>
#include <sys/types.h>
-extern struct _WapiHandleOps _wapi_mutex_ops;
-extern struct _WapiHandleOps _wapi_namedmutex_ops;
-
-extern void _wapi_mutex_details (gpointer handle_info);
+#include "wapi-private.h"
struct _WapiHandle_mutex
{
struct _WapiHandle_namedmutex
{
+ struct _WapiHandle_mutex m;
WapiSharedNamespace sharedns;
- pthread_t tid;
- guint32 recursion;
};
+void
+_wapi_mutex_init (void);
+
extern void _wapi_mutex_abandon (gpointer data, pid_t pid, pthread_t tid);
#endif /* _WAPI_MUTEX_PRIVATE_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
static void mutex_signal(gpointer handle);
static gboolean mutex_own (gpointer handle);
static gboolean mutex_is_owned (gpointer handle);
+static void mutex_prewait (gpointer handle);
+static void mutex_details (gpointer data);
+static const gchar* mutex_typename (void);
+static gsize mutex_typesize (void);
static void namedmutex_signal (gpointer handle);
static gboolean namedmutex_own (gpointer handle);
static gboolean namedmutex_is_owned (gpointer handle);
static void namedmutex_prewait (gpointer handle);
+static void namedmutex_details (gpointer data);
+static const gchar* namedmutex_typename (void);
+static gsize namedmutex_typesize (void);
-struct _WapiHandleOps _wapi_mutex_ops = {
+static MonoW32HandleOps _wapi_mutex_ops = {
NULL, /* close */
mutex_signal, /* signal */
mutex_own, /* own */
mutex_is_owned, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ mutex_prewait, /* prewait */
+ mutex_details, /* details */
+ mutex_typename, /* typename */
+ mutex_typesize, /* typesize */
};
-void _wapi_mutex_details (gpointer handle_info)
-{
- struct _WapiHandle_mutex *mut = (struct _WapiHandle_mutex *)handle_info;
-
-#ifdef PTHREAD_POINTER_ID
- g_print ("own: %5p, count: %5u", mut->tid, mut->recursion);
-#else
- g_print ("own: %5ld, count: %5u", mut->tid, mut->recursion);
-#endif
-}
-
-struct _WapiHandleOps _wapi_namedmutex_ops = {
+static MonoW32HandleOps _wapi_namedmutex_ops = {
NULL, /* close */
namedmutex_signal, /* signal */
namedmutex_own, /* own */
namedmutex_is_owned, /* is_owned */
NULL, /* special_wait */
- namedmutex_prewait /* prewait */
+ namedmutex_prewait, /* prewait */
+ namedmutex_details, /* details */
+ namedmutex_typename, /* typename */
+ namedmutex_typesize, /* typesize */
};
-static gboolean mutex_release (gpointer handle);
-static gboolean namedmutex_release (gpointer handle);
-
-static struct
+void
+_wapi_mutex_init (void)
{
- gboolean (*release)(gpointer handle);
-} mutex_ops[WAPI_HANDLE_COUNT] = {
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {mutex_release},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {namedmutex_release},
-};
-
-static mono_once_t mutex_ops_once=MONO_ONCE_INIT;
+ mono_w32handle_register_ops (MONO_W32HANDLE_MUTEX, &_wapi_mutex_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDMUTEX, &_wapi_namedmutex_ops);
-static void mutex_ops_init (void)
-{
- _wapi_handle_register_capabilities (WAPI_HANDLE_MUTEX,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL | WAPI_HANDLE_CAP_OWN));
- _wapi_handle_register_capabilities (WAPI_HANDLE_NAMEDMUTEX,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL | WAPI_HANDLE_CAP_OWN));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_MUTEX,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL | MONO_W32HANDLE_CAP_OWN));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDMUTEX,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL | MONO_W32HANDLE_CAP_OWN));
}
-static void mutex_signal(gpointer handle)
+static const char* mutex_handle_type_to_string (MonoW32HandleType type)
{
- ReleaseMutex(handle);
+ switch (type) {
+ case MONO_W32HANDLE_MUTEX: return "mutex";
+ case MONO_W32HANDLE_NAMEDMUTEX: return "named mutex";
+ default:
+ g_assert_not_reached ();
+ }
}
-static gboolean mutex_own (gpointer handle)
+static gboolean
+mutex_handle_own (gpointer handle, MonoW32HandleType type)
{
struct _WapiHandle_mutex *mutex_handle;
- gboolean ok;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return(FALSE);
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p", __func__, mutex_handle_type_to_string (type), handle);
+ return FALSE;
}
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p, tid %p, recursion %u",
+ __func__, mutex_handle_type_to_string (type), handle, (gpointer) mutex_handle->tid, mutex_handle->recursion);
+
_wapi_thread_own_mutex (handle);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning mutex handle %p", __func__, handle);
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
mutex_handle->tid = pthread_self ();
mutex_handle->recursion++;
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p locked %d times by %ld", __func__,
- handle, mutex_handle->recursion, mutex_handle->tid);
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
- return(TRUE);
+ return TRUE;
}
-static gboolean mutex_is_owned (gpointer handle)
+static gboolean
+mutex_handle_is_owned (gpointer handle, MonoW32HandleType type)
{
struct _WapiHandle_mutex *mutex_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return(FALSE);
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p", __func__, mutex_handle_type_to_string (type), handle);
+ return FALSE;
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership mutex handle %p", __func__, handle);
- if (mutex_handle->recursion > 0 && pthread_equal (mutex_handle->tid, pthread_self ())) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p owned by %ld", __func__,
- handle, pthread_self ());
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
- return(TRUE);
+ if (mutex_handle->recursion > 0 && pthread_equal (mutex_handle->tid, pthread_self ())) {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p owned by %p",
+ __func__, mutex_handle_type_to_string (type), handle, (gpointer) pthread_self ());
+ return TRUE;
} else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p not owned by %ld, but locked %d times by %ld", __func__,
- handle, pthread_self (), mutex_handle->recursion, mutex_handle->tid);
-
- return(FALSE);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p not owned by %p, but locked %d times by %p",
+ __func__, mutex_handle_type_to_string (type), handle, (gpointer) pthread_self (), mutex_handle->recursion, (gpointer) mutex_handle->tid);
+ return FALSE;
}
}
-static void namedmutex_signal (gpointer handle)
+static void mutex_signal(gpointer handle)
{
ReleaseMutex(handle);
}
-/* NB, always called with the shared handle lock held */
-static gboolean namedmutex_own (gpointer handle)
+static gboolean mutex_own (gpointer handle)
{
- struct _WapiHandle_namedmutex *namedmutex_handle;
- gboolean ok;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning named mutex handle %p", __func__, handle);
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&namedmutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named mutex handle %p",
- __func__, handle);
- return(FALSE);
- }
-
- _wapi_thread_own_mutex (handle);
-
- namedmutex_handle->tid = pthread_self ();
- namedmutex_handle->recursion++;
-
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p locked %d times by %ld", __func__,
- handle, namedmutex_handle->recursion, namedmutex_handle->tid);
-
- return(TRUE);
+ return mutex_handle_own (handle, MONO_W32HANDLE_MUTEX);
}
-static gboolean namedmutex_is_owned (gpointer handle)
+static gboolean mutex_is_owned (gpointer handle)
{
- struct _WapiHandle_namedmutex *namedmutex_handle;
- gboolean ok;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&namedmutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return(FALSE);
- }
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing ownership mutex handle %p", __func__, handle);
+ return mutex_handle_is_owned (handle, MONO_W32HANDLE_MUTEX);
+}
- if (namedmutex_handle->recursion > 0 && pthread_equal (namedmutex_handle->tid, pthread_self ())) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p owned by %ld", __func__,
- handle, pthread_self ());
+static void namedmutex_signal (gpointer handle)
+{
+ ReleaseMutex(handle);
+}
- return(TRUE);
- } else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: mutex handle %p not owned by %ld, but locked %d times by %ld", __func__,
- handle, pthread_self (), namedmutex_handle->recursion, namedmutex_handle->tid);
+/* NB, always called with the shared handle lock held */
+static gboolean namedmutex_own (gpointer handle)
+{
+ return mutex_handle_own (handle, MONO_W32HANDLE_NAMEDMUTEX);
+}
- return(FALSE);
- }
+static gboolean namedmutex_is_owned (gpointer handle)
+{
+ return mutex_handle_is_owned (handle, MONO_W32HANDLE_NAMEDMUTEX);
}
-/* The shared state is not locked when prewait methods are called */
-static void namedmutex_prewait (gpointer handle)
+static void mutex_handle_prewait (gpointer handle, MonoW32HandleType type)
{
/* If the mutex is not currently owned, do nothing and let the
* usual wait carry on. If it is owned, check that the owner
* and assume that process exited abnormally and failed to
* clean up.
*/
- struct _WapiHandle_namedmutex *namedmutex_handle;
- gboolean ok;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&namedmutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named mutex handle %p",
- __func__, handle);
+ struct _WapiHandle_mutex *mutex_handle;
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
return;
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Checking ownership of named mutex handle %p", __func__,
- handle);
- if (namedmutex_handle->recursion == 0) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Named mutex handle %p not owned", __func__,
- handle);
- } else {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Named mutex handle %p owned by this process", __func__,
- handle);
- }
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: pre-waiting %s handle %p, owned? %s",
+ __func__, mutex_handle_type_to_string (type), handle, mutex_handle->recursion != 0 ? "true" : "false");
}
-static void mutex_abandon (gpointer handle, pid_t pid, pthread_t tid)
+/* The shared state is not locked when prewait methods are called */
+static void mutex_prewait (gpointer handle)
{
- struct _WapiHandle_mutex *mutex_handle;
- gboolean ok;
- int thr_ret;
+ mutex_handle_prewait (handle, MONO_W32HANDLE_MUTEX);
+}
+
+/* The shared state is not locked when prewait methods are called */
+static void namedmutex_prewait (gpointer handle)
+{
+ mutex_handle_prewait (handle, MONO_W32HANDLE_NAMEDMUTEX);
+}
+
+static void mutex_details (gpointer data)
+{
+ struct _WapiHandle_mutex *mut = (struct _WapiHandle_mutex *)data;
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return;
- }
+#ifdef PTHREAD_POINTER_ID
+ g_print ("own: %5p, count: %5u", mut->tid, mut->recursion);
+#else
+ g_print ("own: %5ld, count: %5u", mut->tid, mut->recursion);
+#endif
+}
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
+static void namedmutex_details (gpointer data)
+{
+ struct _WapiHandle_namedmutex *namedmut = (struct _WapiHandle_namedmutex *)data;
- if (pthread_equal (mutex_handle->tid, tid)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Mutex handle %p abandoned!", __func__,
- handle);
+#ifdef PTHREAD_POINTER_ID
+ g_print ("own: %5p, count: %5u, name: \"%s\"",
+ namedmut->m.tid, namedmut->m.recursion, namedmut->sharedns.name);
+#else
+ g_print ("own: %5ld, count: %5u, name: \"%s\"",
+ namedmut->m.tid, namedmut->m.recursion, namedmut->sharedns.name);
+#endif
+}
- mutex_handle->recursion = 0;
- mutex_handle->tid = 0;
-
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
+static const gchar* mutex_typename (void)
+{
+ return "Mutex";
+}
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+static gsize mutex_typesize (void)
+{
+ return sizeof (struct _WapiHandle_mutex);
+}
+
+static const gchar* namedmutex_typename (void)
+{
+ return "N.Mutex";
+}
+
+static gsize namedmutex_typesize (void)
+{
+ return sizeof (struct _WapiHandle_namedmutex);
}
-static void namedmutex_abandon (gpointer handle, pid_t pid, pthread_t tid)
+/* When a thread exits, any mutexes it still holds need to be signalled. */
+void _wapi_mutex_abandon (gpointer handle, pid_t pid, pthread_t tid)
{
- struct _WapiHandle_namedmutex *mutex_handle;
- gboolean ok;
+ MonoW32HandleType type;
+ struct _WapiHandle_mutex *mutex_handle;
int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&mutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named mutex handle %p",
- __func__, handle);
+
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_MUTEX:
+ case MONO_W32HANDLE_NAMEDMUTEX:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
return;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandon %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if (pthread_equal (mutex_handle->tid, tid)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Mutex handle %p abandoned!", __func__,
- handle);
+ if (pthread_equal (mutex_handle->tid, tid)) {
mutex_handle->recursion = 0;
mutex_handle->tid = 0;
-
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-}
-/* When a thread exits, any mutexes it still holds need to be
- * signalled. This function must not be called with the shared handle
- * lock held, as namedmutex_abandon () will try to acquire it
- */
-void _wapi_mutex_abandon (gpointer data, pid_t pid, pthread_t tid)
-{
- WapiHandleType type = _wapi_handle_type (data);
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
- if (type == WAPI_HANDLE_MUTEX) {
- mutex_abandon (data, pid, tid);
- } else if (type == WAPI_HANDLE_NAMEDMUTEX) {
- namedmutex_abandon (data, pid, tid);
- } else {
- g_assert_not_reached ();
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandoned %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
}
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
}
-static gpointer mutex_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
- gboolean owned)
+static gpointer mutex_handle_create (struct _WapiHandle_mutex *mutex_handle, MonoW32HandleType type, gboolean owned)
{
- struct _WapiHandle_mutex mutex_handle = {0};
gpointer handle;
int thr_ret;
-
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if a mutex
- * was freshly created
- */
- SetLastError (ERROR_SUCCESS);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating unnamed mutex", __func__);
-
- handle = _wapi_handle_new (WAPI_HANDLE_MUTEX, &mutex_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating mutex handle", __func__);
+
+ mutex_handle->tid = 0;
+ mutex_handle->recursion = 0;
+
+ handle = mono_w32handle_new (type, mutex_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
+ g_warning ("%s: error creating %s handle",
+ __func__, mutex_handle_type_to_string (type));
SetLastError (ERROR_GEN_FAILURE);
- return(NULL);
+ return NULL;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if(owned==TRUE) {
- mutex_own (handle);
- } else {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning mutex handle %p", __func__, handle);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ if (owned)
+ mutex_handle_own (handle, type);
+ else
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
-
- return(handle);
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+
+ return handle;
+}
+
+static gpointer mutex_create (gboolean owned)
+{
+ struct _WapiHandle_mutex mutex_handle;
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+ __func__, mutex_handle_type_to_string (MONO_W32HANDLE_MUTEX));
+ return mutex_handle_create (&mutex_handle, MONO_W32HANDLE_MUTEX, owned);
}
-static gpointer namedmutex_create (WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned,
- const gunichar2 *name)
+static gpointer namedmutex_create (gboolean owned, const gunichar2 *name)
{
- struct _WapiHandle_namedmutex namedmutex_handle = {{{0}}, 0};
gpointer handle;
gchar *utf8_name;
int thr_ret;
- /* w32 seems to guarantee that opening named objects can't
- * race each other
- */
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle",
+ __func__, mutex_handle_type_to_string (MONO_W32HANDLE_NAMEDMUTEX));
+
+ /* w32 seems to guarantee that opening named objects can't race each other */
thr_ret = _wapi_namespace_lock ();
g_assert (thr_ret == 0);
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if a mutex
- * was freshly created
- */
- SetLastError (ERROR_SUCCESS);
-
utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named mutex [%s]", __func__, utf8_name);
-
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDMUTEX,
- utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
- /* The name has already been used for a different
- * object.
- */
+
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDMUTEX, utf8_name);
+ if (handle == INVALID_HANDLE_VALUE) {
+ /* The name has already been used for a different object. */
+ handle = NULL;
SetLastError (ERROR_INVALID_HANDLE);
- goto cleanup;
} else if (handle) {
- /* Not an error, but this is how the caller is
- * informed that the mutex wasn't freshly created
- */
+ /* Not an error, but this is how the caller is informed that the mutex wasn't freshly created */
SetLastError (ERROR_ALREADY_EXISTS);
+
+ /* this is used as creating a new handle */
+ mono_w32handle_ref (handle);
} else {
- /* A new named mutex, so create both the private and
- * shared parts
- */
-
+ /* A new named mutex */
+ struct _WapiHandle_namedmutex namedmutex_handle;
+
strncpy (&namedmutex_handle.sharedns.name [0], utf8_name, MAX_PATH);
namedmutex_handle.sharedns.name [MAX_PATH] = '\0';
- handle = _wapi_handle_new (WAPI_HANDLE_NAMEDMUTEX,
- &namedmutex_handle);
-
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating mutex handle", __func__);
- SetLastError (ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- /* Set the initial state, as this is a completely new
- * handle
- */
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (owned == TRUE) {
- namedmutex_own (handle);
- } else {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ handle = mutex_handle_create ((struct _WapiHandle_mutex*) &namedmutex_handle, MONO_W32HANDLE_NAMEDMUTEX, owned);
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning mutex handle %p", __func__, handle);
-cleanup:
g_free (utf8_name);
- _wapi_namespace_unlock (NULL);
-
+ thr_ret = _wapi_namespace_unlock (NULL);
+ g_assert (thr_ret == 0);
+
return handle;
}
*
* Return value: A new handle, or %NULL on error.
*/
-gpointer CreateMutex(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned,
- const gunichar2 *name)
+gpointer CreateMutex(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean owned, const gunichar2 *name)
{
- mono_once (&mutex_ops_once, mutex_ops_init);
+ /* Need to blow away any old errors here, because code tests
+ * for ERROR_ALREADY_EXISTS on success (!) to see if a mutex
+ * was freshly created */
+ SetLastError (ERROR_SUCCESS);
- if (name == NULL) {
- return(mutex_create (security, owned));
- } else {
- return(namedmutex_create (security, owned, name));
- }
+ return name ? namedmutex_create (owned, name) : mutex_create (owned);
}
-static gboolean mutex_release (gpointer handle)
+/**
+ * ReleaseMutex:
+ * @handle: The mutex handle.
+ *
+ * Releases ownership if the mutex handle @handle.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise. This function
+ * fails if the calling thread does not own the mutex @handle.
+ */
+gboolean ReleaseMutex(gpointer handle)
{
+ MonoW32HandleType type;
struct _WapiHandle_mutex *mutex_handle;
- gboolean ok;
- pthread_t tid = pthread_self ();
+ pthread_t tid;
int thr_ret;
- gboolean ret = FALSE;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_MUTEX,
- (gpointer *)&mutex_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up mutex handle %p", __func__,
- handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Releasing mutex handle %p", __func__, handle);
+ gboolean ret;
- if (!pthread_equal (mutex_handle->tid, tid)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: We don't own mutex handle %p (owned by %ld, me %ld)", __func__,
- handle, mutex_handle->tid, tid);
-
- goto cleanup;
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return FALSE;
}
- ret = TRUE;
-
- /* OK, we own this mutex */
- mutex_handle->recursion--;
-
- if(mutex_handle->recursion==0) {
- _wapi_thread_disown_mutex (handle);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking mutex handle %p", __func__, handle);
- mutex_handle->tid=0;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_MUTEX:
+ case MONO_W32HANDLE_NAMEDMUTEX:
+ break;
+ default:
+ SetLastError (ERROR_INVALID_HANDLE);
+ return FALSE;
}
-cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- return(ret);
-}
-
-static gboolean namedmutex_release (gpointer handle)
-{
- struct _WapiHandle_namedmutex *mutex_handle;
- gboolean ok;
- pthread_t tid = pthread_self ();
- int thr_ret;
- gboolean ret = FALSE;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDMUTEX,
- (gpointer *)&mutex_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up named mutex handle %p",
- __func__, handle);
- return(FALSE);
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+ return FALSE;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: releasing %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Releasing mutex handle %p", __func__, handle);
+
+ tid = pthread_self ();
if (!pthread_equal (mutex_handle->tid, tid)) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: We don't own mutex handle %p (owned by %ld, me %ld)", __func__,
- handle, mutex_handle->tid, tid);
+ ret = FALSE;
- goto cleanup;
- }
- ret = TRUE;
-
- /* OK, we own this mutex */
- mutex_handle->recursion--;
-
- if(mutex_handle->recursion==0) {
- _wapi_thread_disown_mutex (handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: we don't own %s handle %p (owned by %ld, me %ld)",
+ __func__, mutex_handle_type_to_string (type), handle, mutex_handle->tid, tid);
+ } else {
+ ret = TRUE;
+
+ /* OK, we own this mutex */
+ mutex_handle->recursion--;
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Unlocking mutex handle %p", __func__, handle);
+ if (mutex_handle->recursion == 0) {
+ _wapi_thread_disown_mutex (handle);
- mutex_handle->tid=0;
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking %s handle %p",
+ __func__, mutex_handle_type_to_string (type), handle);
+
+ mutex_handle->tid = 0;
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
+ }
}
-cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
-
- return(ret);
-}
-
-/**
- * ReleaseMutex:
- * @handle: The mutex handle.
- *
- * Releases ownership if the mutex handle @handle.
- *
- * Return value: %TRUE on success, %FALSE otherwise. This function
- * fails if the calling thread does not own the mutex @handle.
- */
-gboolean ReleaseMutex(gpointer handle)
-{
- WapiHandleType type;
- if (handle == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
-
- type = _wapi_handle_type (handle);
-
- if (mutex_ops[type].release == NULL) {
- SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
-
- return(mutex_ops[type].release (handle));
+ return ret;
}
gpointer OpenMutex (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, const gunichar2 *name)
gchar *utf8_name;
int thr_ret;
- mono_once (&mutex_ops_once, mutex_ops_init);
-
/* w32 seems to guarantee that opening named objects can't
* race each other
*/
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named mutex [%s]", __func__, utf8_name);
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDMUTEX,
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDMUTEX,
utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
+ if (handle == INVALID_HANDLE_VALUE) {
/* The name has already been used for a different
* object.
*/
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/io-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
static guint32
convert_from_flags(int flags)
file_handle.sharemode=0;
file_handle.attrs=0;
- handle = _wapi_handle_new_fd (WAPI_HANDLE_CONSOLE, fd, &file_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new_fd (MONO_W32HANDLE_CONSOLE, fd, &file_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating file handle", __func__);
SetLastError (ERROR_GEN_FAILURE);
return(INVALID_HANDLE_VALUE);
#define WAPI_PID_TO_HANDLE(pid) GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + (pid))
#define WAPI_HANDLE_TO_PID(handle) (GPOINTER_TO_UINT ((handle)) - _WAPI_PROCESS_UNHANDLED)
-void wapi_processes_init (void);
+void _wapi_processes_init (void);
extern gpointer _wapi_process_duplicate (void);
extern void wapi_processes_cleanup (void);
-extern struct _WapiHandleOps _wapi_process_ops;
-
/*
* MonoProcess describes processes we create.
* It contains a semaphore that can be waited on in order to wait
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/threads.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-proclib.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
/* The process' environment strings */
#if defined(__APPLE__)
static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertable);
static void process_close (gpointer handle, gpointer data);
+static void process_details (gpointer data);
+static const gchar* process_typename (void);
+static gsize process_typesize (void);
static gboolean is_pid_valid (pid_t pid);
#if !(defined(USE_OSX_LOADER) || defined(USE_BSD_LOADER) || defined(USE_HAIKU_LOADER))
open_process_map (int pid, const char *mode);
#endif
-struct _WapiHandleOps _wapi_process_ops = {
+static MonoW32HandleOps _wapi_process_ops = {
process_close, /* close_shared */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
process_wait, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ process_details, /* details */
+ process_typename, /* typename */
+ process_typesize, /* typesize */
};
#if HAVE_SIGACTION
WapiHandle_process *process_data;
gboolean ret;
- ret = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
+ ret = mono_w32handle_lookup (handle, MONO_W32HANDLE_PROCESS,
(gpointer *)&process_data);
if (!ret)
return NULL;
process_set_defaults (&process_handle);
- handle = _wapi_handle_new (WAPI_HANDLE_PROCESS, &process_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new (MONO_W32HANDLE_PROCESS, &process_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating process handle", __func__);
ret = FALSE;
}
/* Close all file descriptors */
- for (i = wapi_getdtablesize () - 1; i > 2; i--)
+ for (i = mono_w32handle_fd_reserve - 1; i > 2; i--)
close (i);
#ifdef DEBUG_ENABLED
process_handle_data = lookup_process_handle (handle);
if (!process_handle_data) {
g_warning ("%s: error looking up process handle %p", __func__, handle);
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
} else {
process_handle_data->id = pid;
mono_process = (struct MonoProcess *) g_malloc0 (sizeof (struct MonoProcess));
mono_process->pid = pid;
mono_process->handle_count = 1;
- if (mono_os_sem_init (&mono_process->exit_sem, 0) != 0) {
- /* If we can't create the exit semaphore, we just don't add anything
- * to our list of mono processes. Waiting on the process will return
- * immediately. */
- g_warning ("%s: could not create exit semaphore for process.", strerror (errno));
- g_free (mono_process);
- } else {
- /* Keep the process handle artificially alive until the process
- * exits so that the information in the handle isn't lost. */
- _wapi_handle_ref (handle);
- mono_process->handle = handle;
+ mono_os_sem_init (&mono_process->exit_sem, 0);
- process_handle_data->mono_process = mono_process;
+ /* Keep the process handle artificially alive until the process
+ * exits so that the information in the handle isn't lost. */
+ mono_w32handle_ref (handle);
+ mono_process->handle = handle;
- mono_os_mutex_lock (&mono_processes_mutex);
- mono_process->next = mono_processes;
- mono_processes = mono_process;
- mono_os_mutex_unlock (&mono_processes_mutex);
- }
+ process_handle_data->mono_process = mono_process;
+
+ mono_os_mutex_lock (&mono_processes_mutex);
+ mono_process->next = mono_processes;
+ mono_processes = mono_process;
+ mono_os_mutex_unlock (&mono_processes_mutex);
if (process_info != NULL) {
process_info->hProcess = handle;
}
if (fork_failed)
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
if (startup_pipe [1] != -1) {
/* Write 1 byte, doesn't matter what */
}
void
-wapi_processes_init (void)
+_wapi_processes_init (void)
{
pid_t pid = _wapi_getpid ();
WapiHandle_process process_handle = {0};
- _wapi_handle_register_capabilities (WAPI_HANDLE_PROCESS,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SPECIAL_WAIT));
+ mono_w32handle_register_ops (MONO_W32HANDLE_PROCESS, &_wapi_process_ops);
+
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_PROCESS,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SPECIAL_WAIT));
process_handle.id = pid;
process_set_defaults (&process_handle);
process_set_name (&process_handle);
- current_process = _wapi_handle_new (WAPI_HANDLE_PROCESS,
+ current_process = mono_w32handle_new (MONO_W32HANDLE_PROCESS,
&process_handle);
g_assert (current_process);
gpointer
_wapi_process_duplicate (void)
{
- _wapi_handle_ref (current_process);
+ mono_w32handle_ref (current_process);
return current_process;
}
* unsignalled
*/
if (checking_pid == wanted_pid &&
- !_wapi_handle_issignalled (handle)) {
+ !mono_w32handle_issignalled (handle)) {
/* If the handle is blown away in the window between
- * returning TRUE here and _wapi_search_handle pinging
+ * returning TRUE here and mono_w32handle_search pinging
* the timestamp, the search will continue
*/
return TRUE;
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: looking for process %d", __func__, pid);
- handle = _wapi_search_handle (WAPI_HANDLE_PROCESS,
+ handle = mono_w32handle_search (MONO_W32HANDLE_PROCESS,
process_open_compare,
GUINT_TO_POINTER (pid), NULL, TRUE);
if (handle == 0) {
}
}
- /* _wapi_search_handle () already added a ref */
+ /* mono_w32handle_search () already added a ref */
return handle;
}
*/
process_wait (process, 0, TRUE);
- if (_wapi_handle_issignalled (process))
+ if (mono_w32handle_issignalled (process))
*code = process_handle->exitstatus;
else
*code = STILL_ACTIVE;
/* A process handle is only signalled if the process has
* exited. Otherwise exit_time isn't set
*/
- if (_wapi_handle_issignalled (process))
+ if (mono_w32handle_issignalled (process))
*exit_time = process_handle->exit_time;
#ifdef HAVE_GETRUSAGE
mp->handle = NULL;
mono_os_mutex_unlock (&mono_processes_mutex);
if (unref_handle)
- _wapi_handle_unref (unref_handle);
+ mono_w32handle_unref (unref_handle);
}
}
mono_processes_cleanup ();
}
+static void process_details (gpointer data)
+{
+ WapiHandle_process *process_handle = (WapiHandle_process *) data;
+ g_print ("id: %d, exited: %s, exitstatus: %d",
+ process_handle->id, process_handle->exited ? "true" : "false", process_handle->exitstatus);
+}
+
+static const gchar* process_typename (void)
+{
+ return "Process";
+}
+
+static gsize process_typesize (void)
+{
+ return sizeof (WapiHandle_process);
+}
+
#if HAVE_SIGACTION
MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, siginfo_t *info, void *context))
{
ret = mono_os_sem_wait (&mp->exit_sem, alertable ? MONO_SEM_FLAGS_ALERTABLE : MONO_SEM_FLAGS_NONE);
}
- if (ret == -1 && errno != EINTR && errno != ETIMEDOUT) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): sem_timedwait failure: %s",
- __func__, handle, timeout, g_strerror (errno));
- /* Should we return a failure here? */
- }
-
- if (ret == 0) {
+ if (ret == MONO_SEM_TIMEDWAIT_RET_SUCCESS) {
/* Success, process has exited */
mono_os_sem_post (&mp->exit_sem);
break;
}
- if (timeout == 0) {
+ if (ret == MONO_SEM_TIMEDWAIT_RET_TIMEDOUT) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_TIMEOUT (timeout = 0)", __func__, handle, timeout);
return WAIT_TIMEOUT;
}
return WAIT_TIMEOUT;
}
- if (alertable && _wapi_thread_cur_apc_pending ()) {
+ if (alertable && ret == MONO_SEM_TIMEDWAIT_RET_ALERTED) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout);
return WAIT_IO_COMPLETION;
}
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): Setting pid %d signalled, exit status %d",
__func__, handle, timeout, process_handle->id, process_handle->exitstatus);
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
return WAIT_OBJECT_0;
}
#endif
#include <glib.h>
-#include <mono/io-layer/handles.h>
#include <mono/io-layer/access.h>
#include <mono/io-layer/versioninfo.h>
#include <config.h>
#include <glib.h>
-extern struct _WapiHandleOps _wapi_sem_ops;
-extern struct _WapiHandleOps _wapi_namedsem_ops;
-
-extern void _wapi_sem_details (gpointer handle_info);
+#include "wapi-private.h"
/* emulate sem_t, so that we can prod the internal state more easily */
struct _WapiHandle_sem
struct _WapiHandle_namedsem
{
+ struct _WapiHandle_sem s;
WapiSharedNamespace sharedns;
- guint32 val;
- gint32 max;
};
+void
+_wapi_semaphore_init (void);
+
#endif /* _WAPI_SEMAPHORE_PRIVATE_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/semaphore-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
static void sema_signal(gpointer handle);
static gboolean sema_own (gpointer handle);
+static void sema_details (gpointer data);
+static const gchar* sema_typename (void);
+static gsize sema_typesize (void);
static void namedsema_signal (gpointer handle);
static gboolean namedsema_own (gpointer handle);
+static void namedsema_details (gpointer data);
+static const gchar* namedsema_typename (void);
+static gsize namedsema_typesize (void);
-struct _WapiHandleOps _wapi_sem_ops = {
+static MonoW32HandleOps _wapi_sem_ops = {
NULL, /* close */
sema_signal, /* signal */
sema_own, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ sema_details, /* details */
+ sema_typename, /* typename */
+ sema_typesize, /* typesize */
};
-void _wapi_sem_details (gpointer handle_info)
-{
- struct _WapiHandle_sem *sem = (struct _WapiHandle_sem *)handle_info;
-
- g_print ("val: %5u, max: %5d", sem->val, sem->max);
-}
-
-struct _WapiHandleOps _wapi_namedsem_ops = {
+static MonoW32HandleOps _wapi_namedsem_ops = {
NULL, /* close */
namedsema_signal, /* signal */
namedsema_own, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ namedsema_details, /* details */
+ namedsema_typename, /* typename */
+ namedsema_typesize, /* typesize */
};
-static gboolean sem_release (gpointer handle, gint32 count, gint32 *prev);
-static gboolean namedsem_release (gpointer handle, gint32 count, gint32 *prev);
-
-static struct
+void
+_wapi_semaphore_init (void)
{
- gboolean (*release)(gpointer handle, gint32 count, gint32 *prev);
-} sem_ops[WAPI_HANDLE_COUNT] = {
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {sem_release},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {NULL},
- {namedsem_release},
-};
-
-static mono_once_t sem_ops_once=MONO_ONCE_INIT;
+ mono_w32handle_register_ops (MONO_W32HANDLE_SEM, &_wapi_sem_ops);
+ mono_w32handle_register_ops (MONO_W32HANDLE_NAMEDSEM, &_wapi_namedsem_ops);
-static void sem_ops_init (void)
-{
- _wapi_handle_register_capabilities (WAPI_HANDLE_SEM,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL));
- _wapi_handle_register_capabilities (WAPI_HANDLE_NAMEDSEM,
- (WapiHandleCapability)(WAPI_HANDLE_CAP_WAIT | WAPI_HANDLE_CAP_SIGNAL));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_SEM,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_NAMEDSEM,
+ (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
}
-static void sema_signal(gpointer handle)
+static const char* sem_handle_type_to_string (MonoW32HandleType type)
{
- ReleaseSemaphore(handle, 1, NULL);
+ switch (type) {
+ case MONO_W32HANDLE_SEM: return "sem";
+ case MONO_W32HANDLE_NAMEDSEM: return "named sem";
+ default:
+ g_assert_not_reached ();
+ }
}
-static gboolean sema_own (gpointer handle)
+static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type)
{
struct _WapiHandle_sem *sem_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_SEM,
- (gpointer *)&sem_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up sem handle %p", __func__,
- handle);
- return(FALSE);
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
+ g_warning ("%s: error looking up %s handle %p",
+ __func__, sem_handle_type_to_string (type), handle);
+ return FALSE;
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning sem handle %p", __func__, handle);
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning %s handle %p",
+ __func__, sem_handle_type_to_string (type), handle);
sem_handle->val--;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sem %p val now %d", __func__, handle, sem_handle->val);
- if(sem_handle->val==0) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
+ if (sem_handle->val == 0)
+ mono_w32handle_set_signal_state (handle, FALSE, FALSE);
+
+ return TRUE;
+}
- return(TRUE);
+static void sema_signal(gpointer handle)
+{
+ ReleaseSemaphore(handle, 1, NULL);
+}
+
+static gboolean sema_own (gpointer handle)
+{
+ return sem_handle_own (handle, MONO_W32HANDLE_SEM);
}
static void namedsema_signal (gpointer handle)
/* NB, always called with the shared handle lock held */
static gboolean namedsema_own (gpointer handle)
{
- struct _WapiHandle_namedsem *namedsem_handle;
- gboolean ok;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: owning named sem handle %p", __func__, handle);
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDSEM,
- (gpointer *)&namedsem_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up named sem handle %p",
- __func__, handle);
- return (FALSE);
- }
-
- namedsem_handle->val--;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: named sem %p val now %d", __func__, handle,
- namedsem_handle->val);
+ return sem_handle_own (handle, MONO_W32HANDLE_NAMEDSEM);
+}
- if (namedsem_handle->val == 0) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- }
-
- return (TRUE);
+static void sema_details (gpointer data)
+{
+ struct _WapiHandle_sem *sem = (struct _WapiHandle_sem *)data;
+ g_print ("val: %5u, max: %5d", sem->val, sem->max);
+}
+
+static void namedsema_details (gpointer data)
+{
+ struct _WapiHandle_namedsem *namedsem = (struct _WapiHandle_namedsem *)data;
+ g_print ("val: %5u, max: %5d, name: \"%s\"", namedsem->s.val, namedsem->s.max, namedsem->sharedns.name);
+}
+
+static const gchar* sema_typename (void)
+{
+ return "Semaphore";
+}
+
+static gsize sema_typesize (void)
+{
+ return sizeof (struct _WapiHandle_sem);
+}
+
+static const gchar* namedsema_typename (void)
+{
+ return "N.Semaphore";
+}
+
+static gsize namedsema_typesize (void)
+{
+ return sizeof (struct _WapiHandle_namedsem);
}
-static gpointer sem_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
- gint32 initial, gint32 max)
+
+static gpointer sem_handle_create (struct _WapiHandle_sem *sem_handle, MonoW32HandleType type, gint32 initial, gint32 max)
{
- struct _WapiHandle_sem sem_handle = {0};
gpointer handle;
int thr_ret;
-
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if a
- * semaphore was freshly created
- */
- SetLastError (ERROR_SUCCESS);
-
- sem_handle.val = initial;
- sem_handle.max = max;
- handle = _wapi_handle_new (WAPI_HANDLE_SEM, &sem_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating semaphore handle", __func__);
+ sem_handle->val = initial;
+ sem_handle->max = max;
+
+ handle = mono_w32handle_new (type, sem_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
+ g_warning ("%s: error creating %s handle",
+ __func__, sem_handle_type_to_string (type));
SetLastError (ERROR_GEN_FAILURE);
- return(NULL);
+ return NULL;
}
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
-
- if (initial != 0) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Created semaphore handle %p initial %d max %d",
- __func__, handle, initial, max);
+ if (initial != 0)
+ mono_w32handle_set_signal_state (handle, TRUE, FALSE);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- return(handle);
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: created %s handle %p",
+ __func__, sem_handle_type_to_string (type), handle);
+
+ return handle;
+}
+
+static gpointer sem_create (gint32 initial, gint32 max)
+{
+ struct _WapiHandle_sem sem_handle;
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle, initial %d max %d",
+ __func__, sem_handle_type_to_string (MONO_W32HANDLE_SEM), initial, max);
+ return sem_handle_create (&sem_handle, MONO_W32HANDLE_SEM, initial, max);
}
-static gpointer namedsem_create (WapiSecurityAttributes *security G_GNUC_UNUSED, gint32 initial, gint32 max, const gunichar2 *name G_GNUC_UNUSED)
+static gpointer namedsem_create (gint32 initial, gint32 max, const gunichar2 *name)
{
- struct _WapiHandle_namedsem namedsem_handle = {{{0}}, 0};
gpointer handle;
gchar *utf8_name;
int thr_ret;
-
- /* w32 seems to guarantee that opening named objects can't
- * race each other
- */
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle, initial %d max %d name \"%s\"",
+ __func__, sem_handle_type_to_string (MONO_W32HANDLE_NAMEDSEM), initial, max, name);
+
+ /* w32 seems to guarantee that opening named objects can't race each other */
thr_ret = _wapi_namespace_lock ();
g_assert (thr_ret == 0);
-
- /* Need to blow away any old errors here, because code tests
- * for ERROR_ALREADY_EXISTS on success (!) to see if a
- * semaphore was freshly created
- */
- SetLastError (ERROR_SUCCESS);
utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named sem [%s]", __func__, utf8_name);
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDSEM,
- utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
- /* The name has already been used for a different
- * object.
- */
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating named sem name [%s] initial %d max %d", __func__, utf8_name, initial, max);
+
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDSEM, utf8_name);
+ if (handle == INVALID_HANDLE_VALUE) {
+ /* The name has already been used for a different object. */
+ handle = NULL;
SetLastError (ERROR_INVALID_HANDLE);
- goto cleanup;
} else if (handle) {
- /* Not an error, but this is how the caller is
- * informed that the semaphore wasn't freshly created
- */
+ /* Not an error, but this is how the caller is informed that the semaphore wasn't freshly created */
SetLastError (ERROR_ALREADY_EXISTS);
+
+ /* this is used as creating a new handle */
+ mono_w32handle_ref (handle);
} else {
- /* A new named semaphore, so create both the private
- * and shared parts
- */
-
+ /* A new named semaphore */
+ struct _WapiHandle_namedsem namedsem_handle;
+
strncpy (&namedsem_handle.sharedns.name [0], utf8_name, MAX_PATH);
namedsem_handle.sharedns.name [MAX_PATH] = '\0';
-
- namedsem_handle.val = initial;
- namedsem_handle.max = max;
- handle = _wapi_handle_new (WAPI_HANDLE_NAMEDSEM,
- &namedsem_handle);
-
- if (handle == _WAPI_HANDLE_INVALID) {
- g_warning ("%s: error creating named sem handle", __func__);
- SetLastError (ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- /* Set the initial state, as this is a completely new
- * handle
- */
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- if (initial != 0) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
- }
-
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ handle = sem_handle_create ((struct _WapiHandle_sem*) &namedsem_handle, MONO_W32HANDLE_NAMEDSEM, initial, max);
}
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named sem handle %p", __func__, handle);
-cleanup:
g_free (utf8_name);
-
- _wapi_namespace_unlock (NULL);
-
+
+ thr_ret = _wapi_namespace_unlock (NULL);
+ g_assert (thr_ret == 0);
+
return handle;
}
*/
gpointer CreateSemaphore(WapiSecurityAttributes *security G_GNUC_UNUSED, gint32 initial, gint32 max, const gunichar2 *name)
{
- mono_once (&sem_ops_once, sem_ops_init);
-
if (max <= 0) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: max <= 0", __func__);
return(NULL);
}
- if (name == NULL) {
- return (sem_create (security, initial, max));
- } else {
- return (namedsem_create (security, initial, max, name));
- }
-}
-
-static gboolean sem_release (gpointer handle, gint32 count, gint32 *prevcount)
-{
- struct _WapiHandle_sem *sem_handle;
- gboolean ok;
- gboolean ret=FALSE;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SEM,
- (gpointer *)&sem_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up sem handle %p", __func__,
- handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sem %p val %d count %d", __func__, handle,
- sem_handle->val, count);
-
- /* Do this before checking for count overflow, because overflowing max
- * is a listed technique for finding the current value
- */
- if (prevcount != NULL) {
- *prevcount = sem_handle->val;
- }
-
- /* No idea why max is signed, but thats the spec :-( */
- if (sem_handle->val + count > (guint32)sem_handle->max) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sem %p max value would be exceeded: max %d current %d count %d", __func__, handle, sem_handle->max, sem_handle->val, count);
-
- goto end;
- }
-
- sem_handle->val += count;
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
-
- ret = TRUE;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: sem %p val now %d", __func__, handle, sem_handle->val);
-
-end:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
-
- return(ret);
-}
-
-static gboolean namedsem_release (gpointer handle, gint32 count,
- gint32 *prevcount)
-{
- struct _WapiHandle_namedsem *sem_handle;
- gboolean ok;
- gboolean ret=FALSE;
- int thr_ret;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDSEM,
- (gpointer *)&sem_handle);
- if (ok == FALSE) {
- g_warning ("%s: error looking up sem handle %p", __func__,
- handle);
- return(FALSE);
- }
-
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: named sem %p val %d count %d", __func__, handle,
- sem_handle->val, count);
-
- /* Do this before checking for count overflow, because overflowing max
- * is a listed technique for finding the current value
+ /* Need to blow away any old errors here, because code tests
+ * for ERROR_ALREADY_EXISTS on success (!) to see if a
+ * semaphore was freshly created
*/
- if (prevcount != NULL) {
- *prevcount = sem_handle->val;
- }
-
- /* No idea why max is signed, but thats the spec :-( */
- if (sem_handle->val + count > (guint32)sem_handle->max) {
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: named sem %p max value would be exceeded: max %d current %d count %d", __func__, handle, sem_handle->max, sem_handle->val, count);
-
- goto end;
- }
-
- sem_handle->val += count;
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
-
- ret = TRUE;
-
- MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: named sem %p val now %d", __func__, handle,
- sem_handle->val);
-
-end:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ SetLastError (ERROR_SUCCESS);
- return(ret);
+ return name ? namedsem_create (initial, max, name) : sem_create (initial, max);
}
/**
*/
gboolean ReleaseSemaphore(gpointer handle, gint32 count, gint32 *prevcount)
{
- WapiHandleType type;
-
- if (handle == NULL) {
+ MonoW32HandleType type;
+ struct _WapiHandle_sem *sem_handle;
+ int thr_ret;
+ gboolean ret;
+
+ if (!handle) {
SetLastError (ERROR_INVALID_HANDLE);
- return (FALSE);
+ return FALSE;
}
-
- type = _wapi_handle_type (handle);
-
- if (sem_ops[type].release == NULL) {
+
+ switch (type = mono_w32handle_get_type (handle)) {
+ case MONO_W32HANDLE_SEM:
+ case MONO_W32HANDLE_NAMEDSEM:
+ break;
+ default:
SetLastError (ERROR_INVALID_HANDLE);
- return (FALSE);
+ return FALSE;
}
-
- return (sem_ops[type].release (handle, count, prevcount));
+
+ if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
+ g_warning ("%s: error looking up sem handle %p", __func__, handle);
+ return FALSE;
+ }
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: releasing %s handle %p",
+ __func__, sem_handle_type_to_string (type), handle);
+
+ thr_ret = mono_w32handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ /* Do this before checking for count overflow, because overflowing
+ * max is a listed technique for finding the current value */
+ if (prevcount)
+ *prevcount = sem_handle->val;
+
+ /* No idea why max is signed, but thats the spec :-( */
+ if (sem_handle->val + count > (guint32)sem_handle->max) {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p val %d count %d max %d, max value would be exceeded",
+ __func__, sem_handle_type_to_string (type), handle, sem_handle->val, count, sem_handle->max, count);
+
+ ret = FALSE;
+ } else {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %s handle %p val %d count %d max %d",
+ __func__, sem_handle_type_to_string (type), handle, sem_handle->val, count, sem_handle->max, count);
+
+ sem_handle->val += count;
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
+
+ ret = TRUE;
+ }
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ return ret;
}
gpointer OpenSemaphore (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED,
gchar *utf8_name;
int thr_ret;
- mono_once (&sem_ops_once, sem_ops_init);
-
/* w32 seems to guarantee that opening named objects can't
* race each other
*/
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named sem [%s]", __func__, utf8_name);
- handle = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDSEM,
+ handle = _wapi_search_handle_namespace (MONO_W32HANDLE_NAMEDSEM,
utf8_name);
- if (handle == _WAPI_HANDLE_INVALID) {
+ if (handle == INVALID_HANDLE_VALUE) {
/* The name has already been used for a different
* object.
*/
mono_os_mutex_init (&noshm_sems [i]);
}
-void
-_wapi_shm_semaphores_remove (void)
-{
- /* Nothing */
-}
-
int
_wapi_shm_sem_lock (int sem)
{
DEBUGLOG ("%s: locking nosem %d", __func__, sem);
- return mono_os_mutex_lock (&noshm_sems[sem]);
+ mono_os_mutex_lock (&noshm_sems[sem]);
+ return 0;
}
int
_wapi_shm_sem_unlock (int sem)
{
DEBUGLOG ("%s: unlocking nosem %d", __func__, sem);
- return mono_os_mutex_unlock (&noshm_sems[sem]);
+ mono_os_mutex_unlock (&noshm_sems[sem]);
+ return 0;
}
#define _WAPI_SHARED_H_
extern void _wapi_shm_semaphores_init (void);
-extern void _wapi_shm_semaphores_remove (void);
extern int _wapi_shm_sem_lock (int sem);
extern int _wapi_shm_sem_trylock (int sem);
extern int _wapi_shm_sem_unlock (int sem);
#include <config.h>
#include <glib.h>
-extern struct _WapiHandleOps _wapi_socket_ops;
+#include "wapi-private.h"
struct _WapiHandle_socket
{
int still_readable;
};
+void
+_wapi_socket_init (void);
+
#endif /* _WAPI_SOCKET_PRIVATE_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/socket-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/socket-wrappers.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-poll.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
static guint32 in_cleanup = 0;
static void socket_close (gpointer handle, gpointer data);
+static void socket_details (gpointer data);
+static const gchar* socket_typename (void);
+static gsize socket_typesize (void);
-struct _WapiHandleOps _wapi_socket_ops = {
+static MonoW32HandleOps _wapi_socket_ops = {
socket_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ socket_details, /* details */
+ socket_typename, /* typename */
+ socket_typesize, /* typesize */
};
-static mono_once_t socket_ops_once=MONO_ONCE_INIT;
-
-static void socket_ops_init (void)
+void
+_wapi_socket_init (void)
{
- /* No capabilities to register */
+ mono_w32handle_register_ops (MONO_W32HANDLE_SOCKET, &_wapi_socket_ops);
}
static void socket_close (gpointer handle, gpointer data)
socket_handle->saved_error = 0;
}
+static void socket_details (gpointer data)
+{
+ /* FIXME: do something */
+}
+
+static const gchar* socket_typename (void)
+{
+ return "Socket";
+}
+
+static gsize socket_typesize (void)
+{
+ return sizeof (struct _WapiHandle_socket);
+}
+
static gboolean
-cleanup_close (gpointer handle, gpointer data)
+cleanup_close (gpointer handle, gpointer data, gpointer user_data)
{
- _wapi_handle_ops_close (handle, NULL);
- return TRUE;
+ if (mono_w32handle_get_type (handle) == MONO_W32HANDLE_SOCKET)
+ mono_w32handle_ops_close (handle, data);
+
+ return FALSE;
}
void _wapi_cleanup_networking(void)
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: cleaning up", __func__);
in_cleanup = 1;
- _wapi_handle_foreach (WAPI_HANDLE_SOCKET, cleanup_close, NULL);
+ mono_w32handle_foreach (cleanup_close, NULL);
in_cleanup = 0;
}
{
gpointer handle = GUINT_TO_POINTER (fd);
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(0);
}
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
return(0);
}
return(INVALID_SOCKET);
}
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(INVALID_SOCKET);
}
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p",
return(INVALID_SOCKET);
}
- if (new_fd >= _wapi_fd_reserve) {
+ if (new_fd >= mono_w32handle_fd_reserve) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big", __func__);
WSASetLastError (WSASYSCALLFAILURE);
new_socket_handle.protocol = socket_handle->protocol;
new_socket_handle.still_readable = 1;
- new_handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, new_fd,
+ new_handle = mono_w32handle_new_fd (MONO_W32HANDLE_SOCKET, new_fd,
&new_socket_handle);
- if(new_handle == _WAPI_HANDLE_INVALID) {
+ if(new_handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating socket handle", __func__);
WSASetLastError (ERROR_GEN_FAILURE);
return(INVALID_SOCKET);
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gboolean ok;
gint errnum;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
* But don't do this for EWOULDBLOCK (bug 317315)
*/
if (errnum != WSAEWOULDBLOCK) {
- ok = _wapi_lookup_handle (handle,
- WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle,
+ MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
/* ECONNRESET means the socket was closed by another thread */
errnum = errno_to_WSA (so_error, __func__);
/* Need to save this socket error */
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p", __func__, handle);
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
struct _WapiHandle_socket *socket_handle;
gboolean ok;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
}
if (optname == SO_ERROR) {
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p",
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gboolean ok;
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
* still_readable != 1 then shutdown
* (SHUT_RD|SHUT_RDWR) has been called locally.
*/
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE || socket_handle->still_readable != 1) {
ret = -1;
gboolean ok;
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
if (ret == 0) {
/* see _wapi_recvfrom */
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE || socket_handle->still_readable != 1) {
ret = -1;
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
#endif
struct timeval tv;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
if (how == SHUT_RD ||
how == SHUT_RDWR) {
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p",
return(INVALID_SOCKET);
}
- if (fd >= _wapi_fd_reserve) {
+ if (fd >= mono_w32handle_fd_reserve) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: File descriptor is too big (%d >= %d)",
- __func__, fd, _wapi_fd_reserve);
+ __func__, fd, mono_w32handle_fd_reserve);
WSASetLastError (WSASYSCALLFAILURE);
close (fd);
}
- mono_once (&socket_ops_once, socket_ops_init);
-
- handle = _wapi_handle_new_fd (WAPI_HANDLE_SOCKET, fd, &socket_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new_fd (MONO_W32HANDLE_SOCKET, fd, &socket_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating socket handle", __func__);
WSASetLastError (WSASYSCALLFAILURE);
close (fd);
gpointer handle = GUINT_TO_POINTER (fd);
int newsock, ret;
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_SOCKET,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_SOCKET,
(gpointer *)&socket_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up socket handle %p", __func__,
gpointer sock = GUINT_TO_POINTER (socket);
gint ret;
- if (_wapi_handle_type (sock) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (sock) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return FALSE;
}
int ret;
gchar *buffer = NULL;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return SOCKET_ERROR;
}
gpointer handle = GUINT_TO_POINTER (fd);
int ret;
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(SOCKET_ERROR);
}
return;
}
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return;
}
return(0);
}
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return(0);
}
return;
}
- if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) {
+ if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) {
WSASetLastError (WSAENOTSOCK);
return;
}
#include <glib.h>
#include <pthread.h>
+#include "wapi-private.h"
+
/* There doesn't seem to be a defined symbol for this */
#define _WAPI_THREAD_CURRENT (gpointer)0xFFFFFFFE
-extern struct _WapiHandleOps _wapi_thread_ops;
-
struct _WapiHandle_thread
{
pthread_t id;
typedef struct _WapiHandle_thread WapiHandle_thread;
+void
+_wapi_thread_init (void);
+
extern gboolean _wapi_thread_cur_apc_pending (void);
extern void _wapi_thread_own_mutex (gpointer mutex);
extern void _wapi_thread_disown_mutex (gpointer mutex);
#include <glib.h>
-#include <mono/io-layer/handles.h>
#include <mono/io-layer/io.h>
#include <mono/io-layer/status.h>
#include <mono/io-layer/processes.h>
#include <errno.h>
#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-logger-internals.h>
#include <mono/utils/mono-time.h>
+#include <mono/utils/w32handle.h>
static gboolean own_if_signalled(gpointer handle)
{
gboolean ret = FALSE;
- if (_wapi_handle_issignalled (handle)) {
- _wapi_handle_ops_own (handle);
+ if (mono_w32handle_issignalled (handle)) {
+ mono_w32handle_ops_own (handle);
ret = TRUE;
}
{
gboolean ret = FALSE;
- if (_wapi_handle_ops_isowned (handle)) {
- _wapi_handle_ops_own (handle);
+ if (mono_w32handle_ops_isowned (handle)) {
+ mono_w32handle_ops_own (handle);
ret = TRUE;
}
int thr_ret;
gboolean apc_pending = FALSE;
gpointer current_thread = wapi_get_current_thread_handle ();
- gint64 now, end;
+ gint64 wait_start, timeout_in_ticks;
if (current_thread == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(WAIT_FAILED);
}
- if (_wapi_handle_test_capabilities (handle,
- WAPI_HANDLE_CAP_WAIT) == FALSE) {
+ if (mono_w32handle_test_capabilities (handle,
+ MONO_W32HANDLE_CAP_WAIT) == FALSE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p can't be waited for", __func__,
handle);
return(WAIT_FAILED);
}
- _wapi_handle_ops_prewait (handle);
+ mono_w32handle_ops_prewait (handle);
- if (_wapi_handle_test_capabilities (handle, WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
+ if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p has special wait", __func__, handle);
- ret = _wapi_handle_ops_special_wait (handle, timeout, alertable);
+ ret = mono_w32handle_ops_specialwait (handle, timeout, alertable);
if (alertable && _wapi_thread_cur_apc_pending ())
ret = WAIT_IO_COMPLETION;
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handle %p", __func__, handle);
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
- if (_wapi_handle_test_capabilities (handle,
- WAPI_HANDLE_CAP_OWN) == TRUE) {
+ if (mono_w32handle_test_capabilities (handle,
+ MONO_W32HANDLE_CAP_OWN) == TRUE) {
if (own_if_owned (handle) == TRUE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already owned", __func__,
handle);
goto done;
}
- if (timeout != INFINITE)
- end = mono_100ns_ticks () + timeout * 1000 * 10;
+ if (timeout != INFINITE) {
+ wait_start = mono_100ns_ticks ();
+ timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
+ }
do {
/* Check before waiting on the condition, just in case
*/
- _wapi_handle_ops_prewait (handle);
+ mono_w32handle_ops_prewait (handle);
if (own_if_signalled (handle)) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__,
}
if (timeout == INFINITE) {
- waited = _wapi_handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &apc_pending : NULL);
+ waited = mono_w32handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &apc_pending : NULL);
} else {
- now = mono_100ns_ticks ();
- if (end < now) {
+ gint64 elapsed = mono_100ns_ticks () - wait_start;
+ if (elapsed >= timeout_in_ticks) {
ret = WAIT_TIMEOUT;
goto done;
}
- waited = _wapi_handle_timedwait_signal_handle (handle, (end - now) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL);
+ waited = mono_w32handle_timedwait_signal_handle (handle, (timeout_in_ticks - elapsed) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL);
}
if(waited==0 && !apc_pending) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, handle);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
return(ret);
int thr_ret;
gboolean apc_pending = FALSE;
gpointer current_thread = wapi_get_current_thread_handle ();
- gint64 now, end;
+ gint64 wait_start, timeout_in_ticks;
if (current_thread == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(WAIT_FAILED);
}
- if (_wapi_handle_test_capabilities (signal_handle,
- WAPI_HANDLE_CAP_SIGNAL)==FALSE) {
+ if (mono_w32handle_test_capabilities (signal_handle,
+ MONO_W32HANDLE_CAP_SIGNAL)==FALSE) {
return(WAIT_FAILED);
}
- if (_wapi_handle_test_capabilities (wait,
- WAPI_HANDLE_CAP_WAIT)==FALSE) {
+ if (mono_w32handle_test_capabilities (wait,
+ MONO_W32HANDLE_CAP_WAIT)==FALSE) {
return(WAIT_FAILED);
}
- _wapi_handle_ops_prewait (wait);
+ mono_w32handle_ops_prewait (wait);
- if (_wapi_handle_test_capabilities (wait, WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
+ if (mono_w32handle_test_capabilities (wait, MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
g_warning ("%s: handle %p has special wait, implement me!!",
__func__, wait);
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handle %p", __func__, wait);
- thr_ret = _wapi_handle_lock_handle (wait);
+ thr_ret = mono_w32handle_lock_handle (wait);
g_assert (thr_ret == 0);
- _wapi_handle_ops_signal (signal_handle);
+ mono_w32handle_ops_signal (signal_handle);
- if (_wapi_handle_test_capabilities (wait, WAPI_HANDLE_CAP_OWN)==TRUE) {
+ if (mono_w32handle_test_capabilities (wait, MONO_W32HANDLE_CAP_OWN)==TRUE) {
if (own_if_owned (wait)) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already owned", __func__,
wait);
goto done;
}
- if (timeout != INFINITE)
- end = mono_100ns_ticks () + timeout * 1000 * 10;
-
+ if (timeout != INFINITE) {
+ wait_start = mono_100ns_ticks ();
+ timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
+ }
do {
/* Check before waiting on the condition, just in case
*/
- _wapi_handle_ops_prewait (wait);
+ mono_w32handle_ops_prewait (wait);
if (own_if_signalled (wait)) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__, wait);
}
if (timeout == INFINITE) {
- waited = _wapi_handle_timedwait_signal_handle (wait, INFINITE, FALSE, alertable ? &apc_pending : NULL);
+ waited = mono_w32handle_timedwait_signal_handle (wait, INFINITE, FALSE, alertable ? &apc_pending : NULL);
} else {
- now = mono_100ns_ticks ();
- if (end < now) {
+ gint64 elapsed = mono_100ns_ticks () - wait_start;
+ if (elapsed >= timeout_in_ticks) {
ret = WAIT_TIMEOUT;
goto done;
}
- waited = _wapi_handle_timedwait_signal_handle (wait, (end - now) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL);
+ waited = mono_w32handle_timedwait_signal_handle (wait, (timeout_in_ticks - elapsed) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL);
}
if (waited==0 && !apc_pending) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, wait);
- thr_ret = _wapi_handle_unlock_handle (wait);
+ thr_ret = mono_w32handle_unlock_handle (wait);
g_assert (thr_ret == 0);
return(ret);
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handles", __func__);
- done = _wapi_handle_count_signalled_handles (numobjects, handles,
+ done = mono_w32handle_count_signalled_handles (numobjects, handles,
waitall, count, lowest);
if (done == TRUE) {
if (waitall == TRUE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handles", __func__);
- _wapi_handle_unlock_handles (numobjects, handles);
+ mono_w32handle_unlock_handles (numobjects, handles);
return(done);
}
gboolean poll;
gpointer sorted_handles [MAXIMUM_WAIT_OBJECTS];
gboolean apc_pending = FALSE;
- gint64 now, end;
+ gint64 wait_start, timeout_in_ticks;
if (current_thread == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
break;
}
- if (_wapi_handle_test_capabilities (handles[i], WAPI_HANDLE_CAP_WAIT) == FALSE) {
+ if (mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_WAIT) == FALSE) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %p can't be waited for",
__func__, handles[i]);
}
sorted_handles [i] = handles [i];
- _wapi_handle_ops_prewait (handles[i]);
+ mono_w32handle_ops_prewait (handles[i]);
}
qsort (sorted_handles, numobjects, sizeof (gpointer), g_direct_equal);
poll = FALSE;
for (i = 0; i < numobjects; ++i)
- if (_wapi_handle_type (handles [i]) == WAPI_HANDLE_PROCESS)
+ if (mono_w32handle_get_type (handles [i]) == MONO_W32HANDLE_PROCESS)
/* Can't wait for a process handle + another handle without polling */
poll = TRUE;
return WAIT_TIMEOUT;
}
- if (timeout != INFINITE)
- end = mono_100ns_ticks () + timeout * 1000 * 10;
+ if (timeout != INFINITE) {
+ wait_start = mono_100ns_ticks ();
+ timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
+ }
/* Have to wait for some or all handles to become signalled
*/
* disappear from under us while we're waiting in the loop
* (not lock, as we don't want exclusive access here)
*/
- _wapi_handle_ref (handles[i]);
+ mono_w32handle_ref (handles[i]);
}
while(1) {
* special-wait handles that aren't already signalled
*/
for (i = 0; i < numobjects; i++) {
- _wapi_handle_ops_prewait (handles[i]);
+ mono_w32handle_ops_prewait (handles[i]);
- if (_wapi_handle_test_capabilities (handles[i], WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE && _wapi_handle_issignalled (handles[i]) == FALSE) {
- _wapi_handle_ops_special_wait (handles[i], 0, alertable);
+ if (mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE && mono_w32handle_issignalled (handles[i]) == FALSE) {
+ mono_w32handle_ops_specialwait (handles[i], 0, alertable);
}
}
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking signal mutex", __func__);
- thr_ret = _wapi_handle_lock_signal_mutex ();
+ thr_ret = mono_w32handle_lock_signal_mutex ();
g_assert (thr_ret == 0);
/* Check the signalled state of handles inside the critical section */
if (waitall) {
done = TRUE;
for (i = 0; i < numobjects; i++)
- if (!_wapi_handle_issignalled (handles [i]))
+ if (!mono_w32handle_issignalled (handles [i]))
done = FALSE;
} else {
done = FALSE;
for (i = 0; i < numobjects; i++)
- if (_wapi_handle_issignalled (handles [i]))
+ if (mono_w32handle_issignalled (handles [i]))
done = TRUE;
}
if (!done) {
/* Enter the wait */
if (timeout == INFINITE) {
- ret = _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, INFINITE, poll, &apc_pending);
+ ret = mono_w32handle_timedwait_signal (INFINITE, poll, &apc_pending);
} else {
- now = mono_100ns_ticks ();
- if (end < now) {
+ gint64 elapsed = mono_100ns_ticks () - wait_start;
+ if (elapsed >= timeout_in_ticks) {
ret = WAIT_TIMEOUT;
} else {
- ret = _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, (end - now) / 10 / 1000, poll, &apc_pending);
+ ret = mono_w32handle_timedwait_signal ((timeout_in_ticks - elapsed) / 10 / 1000, poll, &apc_pending);
}
}
} else {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking signal mutex", __func__);
- thr_ret = _wapi_handle_unlock_signal_mutex (NULL);
+ thr_ret = mono_w32handle_unlock_signal_mutex ();
g_assert (thr_ret == 0);
if (alertable && apc_pending) {
for (i = 0; i < numobjects; i++) {
/* Unref everything we reffed above */
- _wapi_handle_unref (handles[i]);
+ mono_w32handle_unref (handles[i]);
}
return retval;
#include <sys/stat.h>
#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/handles.h>
#include <mono/io-layer/io.h>
+#include <mono/io-layer/shared.h>
#include <mono/utils/mono-os-mutex.h>
-/* Increment this whenever an incompatible change is made to the
- * shared handle structure.
- */
-#define _WAPI_HANDLE_VERSION 12
-
-typedef enum {
- WAPI_HANDLE_UNUSED=0,
- WAPI_HANDLE_FILE,
- WAPI_HANDLE_CONSOLE,
- WAPI_HANDLE_THREAD,
- WAPI_HANDLE_SEM,
- WAPI_HANDLE_MUTEX,
- WAPI_HANDLE_EVENT,
- WAPI_HANDLE_SOCKET,
- WAPI_HANDLE_FIND,
- WAPI_HANDLE_PROCESS,
- WAPI_HANDLE_PIPE,
- WAPI_HANDLE_NAMEDMUTEX,
- WAPI_HANDLE_NAMEDSEM,
- WAPI_HANDLE_NAMEDEVENT,
- WAPI_HANDLE_COUNT
-} WapiHandleType;
-
-extern const char *_wapi_handle_typename[];
-
-#define _WAPI_FD_HANDLE(type) (type == WAPI_HANDLE_FILE || \
- type == WAPI_HANDLE_CONSOLE || \
- type == WAPI_HANDLE_SOCKET || \
- type == WAPI_HANDLE_PIPE)
-
-#define _WAPI_SHARED_NAMESPACE(type) (type == WAPI_HANDLE_NAMEDMUTEX || \
- type == WAPI_HANDLE_NAMEDSEM || \
- type == WAPI_HANDLE_NAMEDEVENT)
+extern gboolean _wapi_has_shut_down;
typedef struct
{
gchar name[MAX_PATH + 1];
} WapiSharedNamespace;
-typedef enum {
- WAPI_HANDLE_CAP_WAIT=0x01,
- WAPI_HANDLE_CAP_SIGNAL=0x02,
- WAPI_HANDLE_CAP_OWN=0x04,
- WAPI_HANDLE_CAP_SPECIAL_WAIT=0x08
-} WapiHandleCapability;
-
-struct _WapiHandleOps
-{
- void (*close)(gpointer handle, gpointer data);
-
- /* SignalObjectAndWait */
- void (*signal)(gpointer signal);
-
- /* Called by WaitForSingleObject and WaitForMultipleObjects,
- * with the handle locked (shared handles aren't locked.)
- * Returns TRUE if ownership was established, false otherwise.
- */
- gboolean (*own_handle)(gpointer handle);
-
- /* Called by WaitForSingleObject and WaitForMultipleObjects, if the
- * handle in question is "ownable" (ie mutexes), to see if the current
- * thread already owns this handle
- */
- gboolean (*is_owned)(gpointer handle);
-
- /* Called by WaitForSingleObject and WaitForMultipleObjects,
- * if the handle in question needs a special wait function
- * instead of using the normal handle signal mechanism.
- * Returns the WaitForSingleObject return code.
- */
- guint32 (*special_wait)(gpointer handle, guint32 timeout, gboolean alertable);
-
- /* Called by WaitForSingleObject and WaitForMultipleObjects,
- * if the handle in question needs some preprocessing before the
- * signal wait.
- */
- void (*prewait)(gpointer handle);
-};
-
#include <mono/io-layer/event-private.h>
#include <mono/io-layer/io-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/io-layer/socket-private.h>
#include <mono/io-layer/thread-private.h>
#include <mono/io-layer/process-private.h>
+#include <mono/utils/w32handle.h>
struct _WapiHandle_shared_ref
{
guint32 offset;
};
-#define _WAPI_HANDLE_INITIAL_COUNT 256
-
-struct _WapiHandleUnshared
-{
- WapiHandleType type;
- guint ref;
- gboolean signalled;
- mono_mutex_t signal_mutex;
- mono_cond_t signal_cond;
-
- union
- {
- struct _WapiHandle_event event;
- struct _WapiHandle_file file;
- struct _WapiHandle_find find;
- struct _WapiHandle_mutex mutex;
- struct _WapiHandle_sem sem;
- struct _WapiHandle_socket sock;
- struct _WapiHandle_thread thread;
- struct _WapiHandle_process process;
- struct _WapiHandle_shared_ref shared;
- struct _WapiHandle_namedmutex namedmutex;
- struct _WapiHandle_namedsem namedsem;
- struct _WapiHandle_namedevent namedevent;
- } u;
-};
-
#define _WAPI_SHARED_SEM_NAMESPACE 0
/*#define _WAPI_SHARED_SEM_COLLECTION 1*/
#define _WAPI_SHARED_SEM_FILESHARE 2
typedef struct _WapiFileShare _WapiFileShare;
-#define _WAPI_HANDLE_INVALID (gpointer)-1
+pid_t
+_wapi_getpid (void);
+
+gpointer
+_wapi_search_handle_namespace (MonoW32HandleType type, gchar *utf8_name);
+
+static inline int _wapi_namespace_lock (void)
+{
+ return(_wapi_shm_sem_lock (_WAPI_SHARED_SEM_NAMESPACE));
+}
+
+/* This signature makes it easier to use in pthread cleanup handlers */
+static inline int _wapi_namespace_unlock (gpointer data G_GNUC_UNUSED)
+{
+ return(_wapi_shm_sem_unlock (_WAPI_SHARED_SEM_NAMESPACE));
+}
#endif /* _WAPI_PRIVATE_H_ */
--- /dev/null
+
+#include "wapi.h"
+
+#include "process-private.h"
+#include "thread-private.h"
+#include "io-trace.h"
+
+#include "mono/utils/mono-lazy-init.h"
+#include "mono/utils/w32handle.h"
+
+gboolean _wapi_has_shut_down = FALSE;
+
+void
+wapi_init (void)
+{
+ _wapi_shm_semaphores_init ();
+ _wapi_io_init ();
+ _wapi_processes_init ();
+ _wapi_thread_init ();
+ _wapi_semaphore_init ();
+ _wapi_mutex_init ();
+ _wapi_event_init ();
+ _wapi_socket_init ();
+}
+
+void
+wapi_cleanup (void)
+{
+ g_assert (_wapi_has_shut_down == FALSE);
+ _wapi_has_shut_down = TRUE;
+
+ _wapi_error_cleanup ();
+ _wapi_thread_cleanup ();
+ wapi_processes_cleanup ();
+ _wapi_io_cleanup ();
+}
+
+/* Use this instead of getpid(), to cope with linuxthreads. It's a
+ * function rather than a variable lookup because we need to get at
+ * this before share_init() might have been called. */
+static mono_lazy_init_t _wapi_pid_init_lazy = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
+static pid_t _wapi_pid;
+
+static void
+_wapi_pid_init (void)
+{
+ _wapi_pid = getpid ();
+}
+
+pid_t
+_wapi_getpid (void)
+{
+ mono_lazy_initialize (&_wapi_pid_init_lazy, _wapi_pid_init);
+ return _wapi_pid;
+}
+
+static gboolean
+_WAPI_SHARED_NAMESPACE (MonoW32HandleType type)
+{
+ switch (type) {
+ case MONO_W32HANDLE_NAMEDMUTEX:
+ case MONO_W32HANDLE_NAMEDSEM:
+ case MONO_W32HANDLE_NAMEDEVENT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+typedef struct {
+ gpointer ret;
+ MonoW32HandleType type;
+ gchar *utf8_name;
+} _WapiSearchHandleNamespaceData;
+
+static gboolean mono_w32handle_search_namespace_callback (gpointer handle, gpointer data, gpointer user_data)
+{
+ _WapiSearchHandleNamespaceData *search_data;
+ MonoW32HandleType type;
+ WapiSharedNamespace *sharedns;
+
+ type = mono_w32handle_get_type (handle);
+ if (!_WAPI_SHARED_NAMESPACE (type))
+ return FALSE;
+
+ search_data = (_WapiSearchHandleNamespaceData*) user_data;
+
+ switch (type) {
+ case MONO_W32HANDLE_NAMEDMUTEX: sharedns = &((struct _WapiHandle_namedmutex*) data)->sharedns; break;
+ case MONO_W32HANDLE_NAMEDSEM: sharedns = &((struct _WapiHandle_namedsem*) data)->sharedns; break;
+ case MONO_W32HANDLE_NAMEDEVENT: sharedns = &((struct _WapiHandle_namedevent*) data)->sharedns; break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (strcmp (sharedns->name, search_data->utf8_name) == 0) {
+ if (type != search_data->type) {
+ /* Its the wrong type, so fail now */
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p matches name but is wrong type: %s",
+ __func__, handle, mono_w32handle_ops_typename (type));
+ search_data->ret = INVALID_HANDLE_VALUE;
+ } else {
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p matches name and type",
+ __func__, handle);
+ search_data->ret = handle;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Returns the offset of the metadata array, or INVALID_HANDLE_VALUE on error, or NULL for
+ * not found
+ */
+gpointer _wapi_search_handle_namespace (MonoW32HandleType type, gchar *utf8_name)
+{
+ _WapiSearchHandleNamespaceData search_data;
+
+ g_assert(_WAPI_SHARED_NAMESPACE(type));
+
+ MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Lookup for handle named [%s] type %s",
+ __func__, utf8_name, mono_w32handle_ops_typename (type));
+
+ search_data.ret = NULL;
+ search_data.type = type;
+ search_data.utf8_name = utf8_name;
+ mono_w32handle_foreach (mono_w32handle_search_namespace_callback, &search_data);
+ return search_data.ret;
+}
+
+/* Lots more to implement here, but this is all we need at the moment */
+gboolean
+DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target,
+ guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 options G_GNUC_UNUSED)
+{
+ if (srcprocess != _WAPI_PROCESS_CURRENT || targetprocess != _WAPI_PROCESS_CURRENT) {
+ /* Duplicating other process's handles is not supported */
+ SetLastError (ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (src == _WAPI_PROCESS_CURRENT) {
+ *target = _wapi_process_duplicate ();
+ } else if (src == _WAPI_THREAD_CURRENT) {
+ g_assert_not_reached ();
+ } else {
+ mono_w32handle_ref (src);
+ *target = src;
+ }
+
+ return TRUE;
+}
+
+/**
+ * CloseHandle:
+ * @handle: The handle to release
+ *
+ * Closes and invalidates @handle, releasing any resources it
+ * consumes. When the last handle to a temporary or non-persistent
+ * object is closed, that object can be deleted. Closing the same
+ * handle twice is an error.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise.
+ */
+gboolean CloseHandle(gpointer handle)
+{
+ if (handle == INVALID_HANDLE_VALUE){
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ if (handle == (gpointer)0 && mono_w32handle_get_type (handle) != MONO_W32HANDLE_CONSOLE) {
+ /* Problem: because we map file descriptors to the
+ * same-numbered handle we can't tell the difference
+ * between a bogus handle and the handle to stdin.
+ * Assume that it's the console handle if that handle
+ * exists...
+ */
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ mono_w32handle_unref (handle);
+ return TRUE;
+}
#include <mono/io-layer/wapi-remap.h>
#include <mono/io-layer/types.h>
#include <mono/io-layer/macros.h>
-#include <mono/io-layer/handles.h>
#include <mono/io-layer/io.h>
#include <mono/io-layer/access.h>
#include <mono/io-layer/context.h>
#include <mono/io-layer/versioninfo.h>
#include <mono/io-layer/wait.h>
+void
+wapi_init (void);
+
+void
+wapi_cleanup (void);
+
+gboolean
+CloseHandle (gpointer handle);
+
+gboolean
+DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target,
+ guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 options G_GNUC_UNUSED);
+
#endif /* _WAPI_WAPI_H_ */
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/thread-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
+#include <mono/utils/w32handle.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
-struct _WapiHandleOps _wapi_thread_ops = {
+static void thread_details (gpointer data);
+static const gchar* thread_typename (void);
+static gsize thread_typesize (void);
+
+static MonoW32HandleOps _wapi_thread_ops = {
NULL, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
NULL, /* special_wait */
- NULL /* prewait */
+ NULL, /* prewait */
+ thread_details, /* details */
+ thread_typename, /* typename */
+ thread_typesize, /* typesize */
};
-static mono_once_t thread_ops_once = MONO_ONCE_INIT;
+void
+_wapi_thread_init (void)
+{
+ mono_w32handle_register_ops (MONO_W32HANDLE_THREAD, &_wapi_thread_ops);
+
+ mono_w32handle_register_capabilities (MONO_W32HANDLE_THREAD, MONO_W32HANDLE_CAP_WAIT);
+}
+
+static void thread_details (gpointer data)
+{
+ WapiHandle_thread *thread = (WapiHandle_thread*) data;
+ g_print ("id: %p, owned_mutexes: %d, priority: %d",
+ thread->id, thread->owned_mutexes->len, thread->priority);
+}
+
+static const gchar* thread_typename (void)
+{
+ return "Thread";
+}
-static void
-thread_ops_init (void)
+static gsize thread_typesize (void)
{
- _wapi_handle_register_capabilities (WAPI_HANDLE_THREAD,
- WAPI_HANDLE_CAP_WAIT);
+ return sizeof (WapiHandle_thread);
}
void
WapiHandle_thread *thread;
gboolean ok;
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
+ ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
(gpointer *)&thread);
g_assert (ok);
return thread;
pid_t pid = _wapi_getpid ();
pthread_t tid = pthread_self ();
- if (_wapi_handle_issignalled (handle) ||
- _wapi_handle_type (handle) == WAPI_HANDLE_UNUSED) {
+ if (mono_w32handle_issignalled (handle) ||
+ mono_w32handle_get_type (handle) == MONO_W32HANDLE_UNUSED) {
/* We must have already deliberately finished with
* this thread, so don't do any more now
*/
}
g_ptr_array_free (thread_handle->owned_mutexes, TRUE);
- thr_ret = _wapi_handle_lock_handle (handle);
+ thr_ret = mono_w32handle_lock_handle (handle);
g_assert (thr_ret == 0);
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ mono_w32handle_set_signal_state (handle, TRUE, TRUE);
- thr_ret = _wapi_handle_unlock_handle (handle);
+ thr_ret = mono_w32handle_unlock_handle (handle);
g_assert (thr_ret == 0);
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Recording thread handle %p id %ld status as %d",
__func__, handle, thread_handle->id, exitstatus);
/* The thread is no longer active, so unref it */
- _wapi_handle_unref (handle);
+ mono_w32handle_unref (handle);
}
/*
WapiHandle_thread thread_handle = {0}, *thread;
gpointer handle;
- mono_once (&thread_ops_once, thread_ops_init);
-
thread_handle.owned_mutexes = g_ptr_array_new ();
- handle = _wapi_handle_new (WAPI_HANDLE_THREAD, &thread_handle);
- if (handle == _WAPI_HANDLE_INVALID) {
+ handle = mono_w32handle_new (MONO_W32HANDLE_THREAD, &thread_handle);
+ if (handle == INVALID_HANDLE_VALUE) {
g_warning ("%s: error creating thread handle", __func__);
SetLastError (ERROR_GEN_FAILURE);
* Hold a reference while the thread is active, because we use
* the handle to store thread exit information
*/
- _wapi_handle_ref (handle);
+ mono_w32handle_ref (handle);
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: started thread id %ld", __func__, thread->id);
void
wapi_ref_thread_handle (gpointer handle)
{
- _wapi_handle_ref (handle);
+ mono_w32handle_ref (handle);
}
gpointer
thread = get_current_thread ();
- _wapi_handle_ref (mutex);
+ mono_w32handle_ref (mutex);
g_ptr_array_add (thread->owned_mutexes, mutex);
}
thread = get_current_thread ();
- _wapi_handle_unref (mutex);
+ mono_w32handle_unref (mutex);
g_ptr_array_remove (thread->owned_mutexes, mutex);
}
wapi_init_thread_info_priority (gpointer handle, gint32 priority)
{
struct _WapiHandle_thread *thread_handle = NULL;
- gboolean ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
+ gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
(gpointer *)&thread_handle);
if (ok == TRUE)
struct _WapiHandle_thread *thread_handle = NULL;
int policy;
struct sched_param param;
- gboolean ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
+ gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
(gpointer *)&thread_handle);
if (ok == FALSE)
posix_priority,
rv;
struct sched_param param;
- gboolean ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
+ gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
(gpointer *)&thread_handle);
if (ok == FALSE) {
verify.h
EXTRA_DIST = $(win32_sources) $(unix_sources) $(null_sources) runtime.h \
- threadpool-ms-io-poll.c threadpool-ms-io-epoll.c threadpool-ms-io-kqueue.c
+ threadpool-ms-io-poll.c threadpool-ms-io-epoll.c threadpool-ms-io-kqueue.c sgen-dynarray.h
#include <mono/utils/atomic.h>
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/w32handle.h>
#ifdef HOST_WIN32
#include <direct.h>
#endif
{
MonoError error;
MonoAppDomain *ad = NULL;
+
#ifdef DISABLE_APPDOMAINS
+ mono_error_init (&error);
mono_error_set_not_supported (&error, "AppDomain creation is not supported on this runtime.");
#else
char *fname;
return location;
}
-static gboolean
-ensure_directory_exists (const char *filename)
-{
-#ifdef HOST_WIN32
- gchar *dir_utf8 = g_path_get_dirname (filename);
- gunichar2 *p;
- gunichar2 *dir_utf16 = NULL;
- int retval;
-
- if (!dir_utf8 || !dir_utf8 [0])
- return FALSE;
-
- dir_utf16 = g_utf8_to_utf16 (dir_utf8, strlen (dir_utf8), NULL, NULL, NULL);
- g_free (dir_utf8);
-
- if (!dir_utf16)
- return FALSE;
-
- p = dir_utf16;
-
- /* make life easy and only use one directory seperator */
- while (*p != '\0')
- {
- if (*p == '/')
- *p = '\\';
- p++;
- }
-
- p = dir_utf16;
-
- /* get past C:\ )*/
- while (*p++ != '\\')
- {
- }
-
- while (1) {
- BOOL bRet = FALSE;
- p = wcschr (p, '\\');
- if (p)
- *p = '\0';
- retval = _wmkdir (dir_utf16);
- if (retval != 0 && errno != EEXIST) {
- g_free (dir_utf16);
- return FALSE;
- }
- if (!p)
- break;
- *p++ = '\\';
- }
-
- g_free (dir_utf16);
- return TRUE;
-#else
- char *p;
- gchar *dir = g_path_get_dirname (filename);
- int retval;
- struct stat sbuf;
-
- if (!dir || !dir [0]) {
- g_free (dir);
- return FALSE;
- }
-
- if (stat (dir, &sbuf) == 0 && S_ISDIR (sbuf.st_mode)) {
- g_free (dir);
- return TRUE;
- }
-
- p = dir;
- while (*p == '/')
- p++;
-
- while (1) {
- p = strchr (p, '/');
- if (p)
- *p = '\0';
- retval = mkdir (dir, 0777);
- if (retval != 0 && errno != EEXIST) {
- g_free (dir);
- return FALSE;
- }
- if (!p)
- break;
- *p++ = '/';
- }
-
- g_free (dir);
- return TRUE;
-#endif
-}
-
static gboolean
private_file_needs_copying (const char *src, struct stat *sbuf_src, char *dest)
{
return NULL;
}
- if (ensure_directory_exists (shadow) == FALSE) {
+ if (g_ensure_directory_exists (shadow) == FALSE) {
g_free (shadow);
mono_error_set_execution_engine (oerror, "Failed to create shadow copy (ensure directory exists).");
return NULL;
sibling_target_len = strlen (sibling_target);
copy_result = shadow_copy_sibling (sibling_source, sibling_source_len, ".mdb", sibling_target, sibling_target_len, 7);
- if (copy_result == TRUE)
+ if (copy_result)
copy_result = shadow_copy_sibling (sibling_source, sibling_source_len, ".config", sibling_target, sibling_target_len, 7);
g_free (sibling_source);
g_free (sibling_target);
- if (copy_result == FALSE) {
+ if (!copy_result) {
g_free (shadow);
mono_error_set_execution_engine (oerror, "Failed to create shadow copy of sibling data (CopyFile).");
return NULL;
#define WINFX_KEY "31bf3856ad364e35"
#define ECMA_KEY "b77a5c561934e089"
#define MSFINAL_KEY "b03f5f7f11d50a3a"
+#define COMPACTFRAMEWORK_KEY "969db8053d3322ac"
typedef struct {
const char *name;
} KeyRemapEntry;
static KeyRemapEntry key_remap_table[] = {
+ { "CustomMarshalers", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
{ "Microsoft.CSharp", WINFX_KEY, MSFINAL_KEY },
+ { "Microsoft.VisualBasic", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
{ "System", SILVERLIGHT_KEY, ECMA_KEY },
+ { "System", COMPACTFRAMEWORK_KEY, ECMA_KEY },
{ "System.ComponentModel.Composition", WINFX_KEY, ECMA_KEY },
{ "System.ComponentModel.DataAnnotations", "ddd0da4d3e678217", WINFX_KEY },
{ "System.Core", SILVERLIGHT_KEY, ECMA_KEY },
+ { "System.Core", COMPACTFRAMEWORK_KEY, ECMA_KEY },
+ { "System.Data", COMPACTFRAMEWORK_KEY, ECMA_KEY },
+ { "System.Data.DataSetExtensions", COMPACTFRAMEWORK_KEY, ECMA_KEY },
+ { "System.Drawing", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
+ { "System.Messaging", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
// FIXME: MS uses MSFINAL_KEY for .NET 4.5
{ "System.Net", SILVERLIGHT_KEY, MSFINAL_KEY },
{ "System.Numerics", WINFX_KEY, ECMA_KEY },
{ "System.Runtime.Serialization", SILVERLIGHT_KEY, ECMA_KEY },
+ { "System.Runtime.Serialization", COMPACTFRAMEWORK_KEY, ECMA_KEY },
{ "System.ServiceModel", WINFX_KEY, ECMA_KEY },
+ { "System.ServiceModel", COMPACTFRAMEWORK_KEY, ECMA_KEY },
{ "System.ServiceModel.Web", SILVERLIGHT_KEY, WINFX_KEY },
+ { "System.Web.Services", COMPACTFRAMEWORK_KEY, MSFINAL_KEY },
{ "System.Windows", SILVERLIGHT_KEY, MSFINAL_KEY },
+ { "System.Windows.Forms", COMPACTFRAMEWORK_KEY, ECMA_KEY },
{ "System.Xml", SILVERLIGHT_KEY, ECMA_KEY },
+ { "System.Xml", COMPACTFRAMEWORK_KEY, ECMA_KEY },
{ "System.Xml.Linq", WINFX_KEY, ECMA_KEY },
+ { "System.Xml.Linq", COMPACTFRAMEWORK_KEY, ECMA_KEY },
{ "System.Xml.Serialization", WINFX_KEY, ECMA_KEY }
};
#define CLI_FLAGS_ILONLY 0x01
#define CLI_FLAGS_32BITREQUIRED 0x02
#define CLI_FLAGS_STRONGNAMESIGNED 0x8
-#define CLI_FLAGS_PREFERRED32BIT 0x10
#define CLI_FLAGS_TRACKDEBUGDATA 0x00010000
+#define CLI_FLAGS_PREFERRED32BIT 0x00020000
guint32 ch_flags;
guint32 ch_entry_point;
};
/* Additional details about a MonoGenericParam */
+/* Keep in sync with managed Mono.RuntimeStructs.GenericParamInfo */
typedef struct {
MonoClass *pklass; /* The corresponding `MonoClass'. */
const char *name;
mono_unload_interface_id (MonoClass *klass);
GPtrArray*
-mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoException **ex);
+mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error);
char*
mono_class_full_name (MonoClass *klass);
klass = search_modules (image, name_space, name, error);
if (klass || !is_ok (error))
return klass;
- }
-
- if (!token)
return NULL;
+ }
if (mono_metadata_token_table (token) == MONO_TABLE_EXPORTEDTYPE) {
MonoTableInfo *t = &image->tables [MONO_TABLE_EXPORTEDTYPE];
#include <metadata/threads.h>
#include <metadata/profiler-private.h>
#include <mono/metadata/coree.h>
+#include <mono/utils/w32handle.h>
//#define DEBUG_DOMAIN_UNLOAD 1
#endif
#ifndef HOST_WIN32
+ mono_w32handle_init ();
wapi_init ();
#endif
#ifndef HOST_WIN32
wapi_cleanup ();
+ mono_w32handle_cleanup ();
#endif
}
#include <mono/metadata/marshal.h>
#include <mono/utils/strenc.h>
#include <utils/mono-io-portability.h>
+#include <mono/utils/w32handle.h>
#undef DEBUG
#endif
-void _wapi_handle_dump (void);
+void mono_w32handle_dump (void);
void ves_icall_System_IO_MonoIO_DumpHandles (void)
{
#ifndef HOST_WIN32
- _wapi_handle_dump ();
+ mono_w32handle_dump ();
#endif
}
void mono_gc_add_memory_pressure (gint64 value);
MONO_API int mono_gc_register_root (char *start, size_t size, MonoGCDescriptor descr, MonoGCRootSource source, const char *msg);
void mono_gc_deregister_root (char* addr);
-int mono_gc_finalizers_for_domain (MonoDomain *domain, MonoObject **out_array, int out_size);
+void mono_gc_finalize_domain (MonoDomain *domain, volatile gboolean *suspend);
void mono_gc_run_finalize (void *obj, void *data);
void mono_gc_clear_domain (MonoDomain * domain);
typedef struct DomainFinalizationReq {
MonoDomain *domain;
+#ifdef TARGET_WIN32
HANDLE done_event;
+#else
+ gboolean done;
+ MonoCoopCond cond;
+ MonoCoopMutex mutex;
+#endif
} DomainFinalizationReq;
static gboolean gc_disabled = FALSE;
return result;
}
+typedef struct {
+ MonoCoopCond *cond;
+ MonoCoopMutex *mutex;
+} BreakCoopAlertableWaitUD;
+
+static inline void
+break_coop_alertable_wait (gpointer user_data)
+{
+ BreakCoopAlertableWaitUD *ud = (BreakCoopAlertableWaitUD*)user_data;
+
+ mono_coop_mutex_lock (ud->mutex);
+ mono_coop_cond_signal (ud->cond);
+ mono_coop_mutex_unlock (ud->mutex);
+}
+
+/*
+ * coop_cond_timedwait_alertable:
+ *
+ * Wait on COND/MUTEX. If ALERTABLE is non-null, the wait can be interrupted.
+ * In that case, *ALERTABLE will be set to TRUE, and 0 is returned.
+ */
+static inline gint
+coop_cond_timedwait_alertable (MonoCoopCond *cond, MonoCoopMutex *mutex, guint32 timeout_ms, gboolean *alertable)
+{
+ int res;
+
+ if (alertable) {
+ BreakCoopAlertableWaitUD ud;
+
+ *alertable = FALSE;
+ ud.cond = cond;
+ ud.mutex = mutex;
+ mono_thread_info_install_interrupt (break_coop_alertable_wait, &ud, alertable);
+ if (*alertable)
+ return 0;
+ }
+ res = mono_coop_cond_timedwait (cond, mutex, timeout_ms);
+ if (alertable) {
+ mono_thread_info_uninstall_interrupt (alertable);
+ if (*alertable)
+ return 0;
+ }
+ return res;
+}
+
static gboolean
add_thread_to_finalize (MonoInternalThread *thread, MonoError *error)
{
mono_domain_finalize (MonoDomain *domain, guint32 timeout)
{
DomainFinalizationReq *req;
- guint32 res;
- HANDLE done_event;
MonoInternalThread *thread = mono_thread_internal_current ();
#if defined(__native_client__)
mono_gc_collect (mono_gc_max_generation ());
- done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
- if (done_event == NULL) {
- return FALSE;
- }
-
req = g_new0 (DomainFinalizationReq, 1);
req->domain = domain;
- req->done_event = done_event;
+
+#ifdef TARGET_WIN32
+ req->done_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+ if (req->done_event == NULL) {
+ g_free (req);
+ return FALSE;
+ }
+#else
+ mono_coop_cond_init (&req->cond);
+ mono_coop_mutex_init (&req->mutex);
+#endif
if (domain == mono_get_root_domain ())
finalizing_root_domain = TRUE;
if (timeout == -1)
timeout = INFINITE;
+#if TARGET_WIN32
while (TRUE) {
- res = guarded_wait (done_event, timeout, TRUE);
+ guint32 res = guarded_wait (req->done_event, timeout, TRUE);
/* printf ("WAIT RES: %d.\n", res); */
if (res == WAIT_IO_COMPLETION) {
}
}
- CloseHandle (done_event);
+ CloseHandle (req->done_event);
+#else
+ mono_coop_mutex_lock (&req->mutex);
+ while (!req->done) {
+ gboolean alerted;
+ int res = coop_cond_timedwait_alertable (&req->cond, &req->mutex, timeout, &alerted);
+ if (alerted) {
+ if ((thread->state & (ThreadState_StopRequested | ThreadState_SuspendRequested)) != 0) {
+ mono_coop_mutex_unlock (&req->mutex);
+ return FALSE;
+ }
+ } else if (res == ETIMEDOUT) {
+ /* We leak the cond/mutex here */
+ mono_coop_mutex_unlock (&req->mutex);
+ return FALSE;
+ } else {
+ break;
+ }
+ }
+ mono_coop_mutex_unlock (&req->mutex);
+
+ /* When we reach here, the other thread has already exited the critical section, so this is safe to free */
+ mono_coop_cond_destroy (&req->cond);
+ mono_coop_mutex_destroy (&req->mutex);
+ g_free (req);
+#endif
if (domain == mono_get_root_domain ()) {
mono_threadpool_ms_cleanup ();
{
MonoDomain *domain = req->domain;
-#if HAVE_SGEN_GC
-#define NUM_FOBJECTS 64
- MonoObject *to_finalize [NUM_FOBJECTS];
- int count;
-#endif
-
/* Process finalizers which are already in the queue */
mono_gc_invoke_finalizers ();
g_ptr_array_free (objs, TRUE);
}
#elif defined(HAVE_SGEN_GC)
- while (!suspend_finalizers && (count = mono_gc_finalizers_for_domain (domain, to_finalize, NUM_FOBJECTS))) {
- int i;
- for (i = 0; i < count; ++i) {
- mono_gc_run_finalize (to_finalize [i], 0);
- }
- }
+ mono_gc_finalize_domain (domain, &suspend_finalizers);
+ mono_gc_invoke_finalizers ();
#endif
/* cleanup the reference queue */
reference_queue_clear_for_domain (domain);
/* printf ("DONE.\n"); */
+#if TARGET_WIN32
SetEvent (req->done_event);
/* The event is closed in mono_domain_finalize if we get here */
g_free (req);
+#else
+ mono_coop_mutex_lock (&req->mutex);
+ req->done = TRUE;
+ mono_coop_cond_signal (&req->cond);
+ mono_coop_mutex_unlock (&req->mutex);
+#endif
}
static guint32
hazard_free_queue_pump ();
/* Avoid posting the pending done event until there are pending finalizers */
- if (mono_coop_sem_timedwait (&finalizer_sem, 0, MONO_SEM_FLAGS_NONE) == 0) {
+ if (mono_coop_sem_timedwait (&finalizer_sem, 0, MONO_SEM_FLAGS_NONE) == MONO_SEM_TIMEDWAIT_RET_SUCCESS) {
/* Don't wait again at the start of the loop */
wait = FALSE;
} else {
We could then generate neat type safe wrappers.
*/
-const MonoObject *null_cell = { NULL };
-const MonoObjectHandle mono_null_value_handle = { (MonoObject**)&null_cell };
+const MonoObjectHandle mono_null_value_handle = NULL;
#define THIS_IS_AN_OK_NUMBER_OF_HANDLES 100
c = next;
}
g_free (c);
+ g_free (stack);
}
void
#ifdef ENABLE_CHECKED_BUILD
void mono_handle_verify (MonoRawHandle handle);
-#define HANDLE_INVARIANTS(H) mono_handle_verify((void*)(H).__obj)
+#define HANDLE_INVARIANTS(H) mono_handle_verify((void*)(H))
#else
#define HANDLE_INVARIANTS(H) (0)
#endif
+#define TYPED_HANDLE_PAYLOAD_NAME(TYPE) TYPE ## HandlePayload
#define TYPED_HANDLE_NAME(TYPE) TYPE ## Handle
-#define TYPED_HANDLE_DECL(TYPE) typedef struct { TYPE **__obj; } TYPED_HANDLE_NAME (TYPE) ;
+/*
+ * typedef struct {
+ * MonoObject *__obj;
+ * } MonoObjectHandlePayload;
+ *
+ * typedef MonoObjectHandlePayload* MonoObjectHandle;
+ */
+#define TYPED_HANDLE_DECL(TYPE) typedef struct { TYPE *__obj; } TYPED_HANDLE_PAYLOAD_NAME (TYPE) ; typedef TYPED_HANDLE_PAYLOAD_NAME (TYPE) * TYPED_HANDLE_NAME (TYPE);
-#define MONO_HANDLE_INIT { (void*)mono_null_value_handle.__obj }
+#define MONO_HANDLE_INIT ((void*) mono_null_value_handle)
#define NULL_HANDLE mono_null_value_handle
//XXX add functions to get/set raw, set field, set field to null, set array, set array to null
-#define MONO_HANDLE_RAW(HANDLE) (HANDLE_INVARIANTS (HANDLE), (*(HANDLE).__obj))
-#define MONO_HANDLE_DCL(TYPE, NAME) TYPED_HANDLE_NAME(TYPE) NAME = { mono_handle_new ((MonoObject*)(NAME ## _raw)) }
-#define MONO_HANDLE_NEW(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE)){ mono_handle_new ((MonoObject*)(VALUE)) }
-#define MONO_HANDLE_CAST(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE)){ (TYPE**)((VALUE).__obj) }
+#define MONO_HANDLE_RAW(HANDLE) (HANDLE_INVARIANTS (HANDLE), ((HANDLE)->__obj))
+#define MONO_HANDLE_DCL(TYPE, NAME) TYPED_HANDLE_NAME(TYPE) NAME = (TYPED_HANDLE_NAME(TYPE))(mono_handle_new ((MonoObject*)(NAME ## _raw)))
+#define MONO_HANDLE_NEW(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE))( mono_handle_new ((MonoObject*)(VALUE)) )
+#define MONO_HANDLE_CAST(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE))( VALUE )
/*
WARNING WARNING WARNING
ICALL_TYPE(RTCLASS, "Mono.RuntimeClassHandle", RTCLASS_1)
ICALL(RTCLASS_1, "GetTypeFromClass", ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass)
+ICALL_TYPE(RTPTRARRAY, "Mono.RuntimeGPtrArrayHandle", RTPTRARRAY_1)
+ICALL(RTPTRARRAY_1, "GPtrArrayFree", ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree)
+
#ifndef PLATFORM_RO_FS
ICALL_TYPE(KPAIR, "Mono.Security.Cryptography.KeyPairPersistence", KPAIR_1)
ICALL(KPAIR_1, "_CanSecure", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure)
ICALL_TYPE(ASSEM, "System.Reflection.Assembly", ASSEM_1)
ICALL(ASSEM_1, "FillName", ves_icall_System_Reflection_Assembly_FillName)
+ICALL(ASSEM_1a, "GetAotId", ves_icall_System_Reflection_Assembly_GetAotId)
ICALL(ASSEM_2, "GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly)
ICALL(ASSEM_3, "GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly)
ICALL(ASSEM_4, "GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly)
ICALL(TYPEB_6, "setup_generic_class", mono_reflection_setup_generic_class)
ICALL(TYPEB_7, "setup_internal_class", mono_reflection_setup_internal_class)
+ICALL_TYPE(EVENTI, "System.Reflection.EventInfo", EVENTI_1)
+ICALL(EVENTI_1, "internal_from_handle_type", ves_icall_System_Reflection_EventInfo_internal_from_handle_type)
+
ICALL_TYPE(FIELDI, "System.Reflection.FieldInfo", FILEDI_1)
ICALL(FILEDI_1, "GetTypeModifiers", ves_icall_System_Reflection_FieldInfo_GetTypeModifiers)
ICALL(FILEDI_2, "get_marshal_info", ves_icall_System_Reflection_FieldInfo_get_marshal_info)
ICALL_TYPE(MBASE, "System.Reflection.MethodBase", MBASE_1)
ICALL(MBASE_1, "GetCurrentMethod", ves_icall_GetCurrentMethod)
ICALL(MBASE_2, "GetMethodBodyInternal", ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal)
-ICALL(MBASE_4, "GetMethodFromHandleInternalType", ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType)
+ICALL(MBASE_4, "GetMethodFromHandleInternalType_native", ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native)
ICALL_TYPE(MODULE, "System.Reflection.Module", MODULE_1)
ICALL(MODULE_1, "Close", ves_icall_System_Reflection_Module_Close)
ICALL(PARAMI_1, "GetMetadataToken", ves_icall_reflection_get_token)
ICALL(PARAMI_2, "GetTypeModifiers", ves_icall_ParameterInfo_GetTypeModifiers)
+ICALL_TYPE(PROPI, "System.Reflection.PropertyInfo", PROPI_1)
+ICALL(PROPI_1, "internal_from_handle_type", ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type)
+
ICALL_TYPE(RTFIELD, "System.Reflection.RtFieldInfo", RTFIELD_1)
ICALL(RTFIELD_1, "UnsafeGetValue", ves_icall_MonoField_GetValueInternal)
ICALL_TYPE(RT, "System.RuntimeType", RT_1)
ICALL(RT_1, "CreateInstanceInternal", ves_icall_System_Activator_CreateInstanceInternal)
-ICALL(RT_2, "GetConstructors_internal", ves_icall_RuntimeType_GetConstructors_internal)
+ICALL(RT_2, "GetConstructors_native", ves_icall_RuntimeType_GetConstructors_native)
ICALL(RT_30, "GetCorrespondingInflatedConstructor", ves_icall_RuntimeType_GetCorrespondingInflatedMethod)
ICALL(RT_31, "GetCorrespondingInflatedMethod", ves_icall_RuntimeType_GetCorrespondingInflatedMethod)
-ICALL(RT_3, "GetEvents_internal", ves_icall_RuntimeType_GetEvents_internal)
-ICALL(RT_5, "GetFields_internal", ves_icall_RuntimeType_GetFields_internal)
+ICALL(RT_3, "GetEvents_native", ves_icall_RuntimeType_GetEvents_native)
+ICALL(RT_5, "GetFields_native", ves_icall_RuntimeType_GetFields_native)
ICALL(RT_6, "GetGenericArgumentsInternal", ves_icall_RuntimeType_GetGenericArguments)
-ICALL(RT_7, "GetGenericParameterAttributes", ves_icall_RuntimeType_GetGenericParameterAttributes)
-ICALL(RT_8, "GetGenericParameterConstraints_impl", ves_icall_RuntimeType_GetGenericParameterConstraints)
ICALL(RT_9, "GetGenericParameterPosition", ves_icall_RuntimeType_GetGenericParameterPosition)
ICALL(RT_10, "GetInterfaceMapData", ves_icall_RuntimeType_GetInterfaceMapData)
ICALL(RT_11, "GetInterfaces", ves_icall_RuntimeType_GetInterfaces)
-ICALL(RT_12, "GetMethodsByName", ves_icall_RuntimeType_GetMethodsByName)
+ICALL(RT_12, "GetMethodsByName_native", ves_icall_RuntimeType_GetMethodsByName_native)
ICALL(RT_13, "GetNestedTypes_internal", ves_icall_RuntimeType_GetNestedTypes)
ICALL(RT_14, "GetPacking", ves_icall_RuntimeType_GetPacking)
-ICALL(RT_15, "GetPropertiesByName", ves_icall_RuntimeType_GetPropertiesByName)
+ICALL(RT_15, "GetPropertiesByName_native", ves_icall_RuntimeType_GetPropertiesByName_native)
ICALL(RT_16, "GetTypeCodeImplInternal", ves_icall_type_GetTypeCodeInternal)
ICALL(RT_28, "IsTypeExportedToWindowsRuntime", ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime)
ICALL(RT_29, "IsWindowsRuntimeObjectType", ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType)
ICALL(RTH_3, "GetAttributes", ves_icall_RuntimeTypeHandle_GetAttributes)
ICALL(RTH_4, "GetBaseType", ves_icall_RuntimeTypeHandle_GetBaseType)
ICALL(RTH_5, "GetElementType", ves_icall_RuntimeTypeHandle_GetElementType)
+ICALL(RTH_19, "GetGenericParameterInfo", ves_icall_RuntimeTypeHandle_GetGenericParameterInfo)
ICALL(RTH_6, "GetGenericTypeDefinition_impl", ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl)
ICALL(RTH_7, "GetMetadataToken", ves_icall_reflection_get_token)
ICALL(RTH_8, "GetModule", ves_icall_RuntimeTypeHandle_GetModule)
return mono_class_get_type (klass);
}
+ICALL_EXPORT void
+ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array, MonoBoolean freeSeg)
+{
+ g_ptr_array_free (ptr_array, freeSeg);
+}
+
/* System.TypeCode */
typedef enum {
TYPECODE_EMPTY,
MonoError error;
gboolean found = FALSE;
MonoClass *klass;
- MonoClass *k;
g_assert (handle);
} else {
klass = mono_class_from_mono_type (type);
- /* Check that the field belongs to the class */
- for (k = klass; k; k = k->parent) {
- if (k == handle->parent) {
- found = TRUE;
- break;
- }
- }
+ found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
if (!found)
/* The managed code will throw the exception */
return result;
}
+ICALL_EXPORT MonoReflectionEvent*
+ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
+{
+ MonoError error;
+ MonoClass *klass;
+
+ g_assert (handle);
+
+ if (!type) {
+ klass = handle->parent;
+ } else {
+ klass = mono_class_from_mono_type (type);
+
+ gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
+ if (!found)
+ /* Managed code will throw an exception */
+ return NULL;
+ }
+
+ MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
+}
+
+
+ICALL_EXPORT MonoReflectionProperty*
+ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
+{
+ MonoError error;
+ MonoClass *klass;
+
+ g_assert (handle);
+
+ if (!type) {
+ klass = handle->parent;
+ } else {
+ klass = mono_class_from_mono_type (type);
+
+ gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
+ if (!found)
+ /* Managed code will throw an exception */
+ return NULL;
+ }
+
+ MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
+}
+
ICALL_EXPORT MonoArray*
ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
{
return -1;
}
-ICALL_EXPORT GenericParameterAttributes
-ves_icall_RuntimeType_GetGenericParameterAttributes (MonoReflectionType *type)
-{
- g_assert (IS_MONOTYPE (type));
- g_assert (is_generic_parameter (type->type));
- return (GenericParameterAttributes)mono_generic_param_info (type->type->data.generic_param)->flags;
-}
-
-ICALL_EXPORT MonoArray *
-ves_icall_RuntimeType_GetGenericParameterConstraints (MonoReflectionType *type)
+ICALL_EXPORT MonoGenericParamInfo *
+ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
{
- MonoError error;
- MonoReflectionType *rt;
- MonoGenericParamInfo *param_info;
- MonoDomain *domain;
- MonoClass **ptr;
- MonoArray *res;
- int i, count;
-
- g_assert (IS_MONOTYPE (type));
-
- domain = mono_object_domain (type);
- param_info = mono_generic_param_info (type->type->data.generic_param);
- for (count = 0, ptr = param_info->constraints; ptr && *ptr; ptr++, count++)
- ;
-
- res = mono_array_new_checked (domain, mono_defaults.runtimetype_class, count, &error);
- if (mono_error_set_pending_exception (&error))
- return NULL;
- for (i = 0; i < count; i++) {
- rt = mono_type_get_object_checked (domain, ¶m_info->constraints [i]->byval_arg, &error);
- if (mono_error_set_pending_exception (&error))
- return NULL;
-
- mono_array_setref (res, i, rt);
- }
-
-
- return res;
+ return mono_generic_param_info (type->type->data.generic_param);
}
ICALL_EXPORT MonoBoolean
BFLAGS_OptionalParamBinding = 0x40000
};
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetFields_internal (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, MonoString *name, guint32 bflags)
{
MonoError error;
MonoDomain *domain;
- MonoClass *startklass, *klass, *refklass;
- MonoArray *res;
- MonoObject *member;
- int i, match;
+ MonoClass *startklass, *klass;
+ int match;
gpointer iter;
char *utf8_name = NULL;
int (*compare_func) (const char *s1, const char *s2) = NULL;
MonoClassField *field;
- MonoPtrArray tmp_array;
domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref) {
- MonoArray *result = mono_array_new_checked (domain, mono_defaults.field_info_class, 0, &error);
- mono_error_set_pending_exception (&error);
- return result;
+ return g_ptr_array_new ();
}
klass = startklass = mono_class_from_mono_type (type->type);
- refklass = mono_class_from_mono_type (reftype->type);
- mono_ptr_array_init (tmp_array, 2, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection fields list");
+ GPtrArray *ptr_array = g_ptr_array_sized_new (16);
handle_parent:
if (mono_class_has_failure (klass)) {
- mono_ptr_array_destroy (tmp_array);
- mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
- return NULL;
+ mono_error_init (&error);
+ mono_error_set_for_class_failure (&error, klass);
+ goto fail;
}
iter = NULL;
continue;
}
- member = (MonoObject*)mono_field_get_object_checked (domain, refklass, field, &error);
- if (!mono_error_ok (&error))
- goto fail;
- mono_ptr_array_append (tmp_array, member);
+ g_ptr_array_add (ptr_array, field);
}
if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
goto handle_parent;
- res = mono_array_new_cached (domain, mono_defaults.field_info_class, mono_ptr_array_size (tmp_array), &error);
- if (!is_ok (&error))
- goto fail;
-
- for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
- mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
- mono_ptr_array_destroy (tmp_array);
-
if (utf8_name != NULL)
g_free (utf8_name);
+ return ptr_array;
- return res;
fail:
- mono_ptr_array_destroy (tmp_array);
+ g_ptr_array_free (ptr_array, FALSE);
mono_error_set_pending_exception (&error);
return NULL;
}
}
GPtrArray*
-mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoException **ex)
+mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
{
GPtrArray *array;
MonoClass *startklass;
array = g_ptr_array_new ();
startklass = klass;
- *ex = NULL;
+ mono_error_init (error);
if (name != NULL)
compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
g_free (method_slots);
g_ptr_array_free (array, TRUE);
- if (mono_class_has_failure (klass)) {
- *ex = mono_class_get_exception_for_failure (klass);
- } else {
- *ex = mono_get_exception_execution_engine ("Unknown error");
- }
+ g_assert (mono_class_has_failure (klass));
+ mono_error_set_for_class_failure (error, klass);
return NULL;
}
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case)
{
- static MonoClass *MethodInfo_array;
MonoError error;
MonoDomain *domain;
- MonoArray *res;
- MonoVTable *array_vtable;
- MonoException *ex = NULL;
const char *mname = NULL;
GPtrArray *method_array;
- MonoClass *klass, *refklass;
- int i;
-
- mono_error_init (&error);
-
- if (!MethodInfo_array) {
- MonoClass *klass = mono_array_class_get (mono_defaults.method_info_class, 1);
- mono_memory_barrier ();
- MethodInfo_array = klass;
- }
+ MonoClass *klass;
klass = mono_class_from_mono_type (type->type);
- refklass = mono_class_from_mono_type (reftype->type);
domain = ((MonoObject *)type)->vtable->domain;
- array_vtable = mono_class_vtable_full (domain, MethodInfo_array, &error);
- if (!is_ok (&error)) {
- mono_error_set_pending_exception (&error);
- return NULL;
- }
if (type->type->byref) {
- res = mono_array_new_specific_checked (array_vtable, 0, &error);
- mono_error_set_pending_exception (&error);
-
- return res;
+ return g_ptr_array_new ();
}
if (name) {
return NULL;
}
- method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &ex);
+ method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
g_free ((char*)mname);
- if (ex) {
- mono_set_pending_exception (ex);
- return NULL;
- }
-
- res = mono_array_new_specific_checked (array_vtable, method_array->len, &error);
- if (!mono_error_ok (&error)) {
- mono_error_set_pending_exception (&error);
- return NULL;
- }
-
- for (i = 0; i < method_array->len; ++i) {
- MonoMethod *method = (MonoMethod *)g_ptr_array_index (method_array, i);
- MonoReflectionMethod *rm = mono_method_get_object_checked (domain, method, refklass, &error);
- if (!mono_error_ok (&error))
- goto failure;
- mono_array_setref (res, i, rm);
- }
-
-failure:
- g_ptr_array_free (method_array, TRUE);
- if (!mono_error_ok (&error))
- mono_set_pending_exception (mono_error_convert_to_exception (&error));
- return res;
+ mono_error_set_pending_exception (&error);
+ return method_array;
}
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
{
- MonoDomain *domain;
- MonoClass *startklass, *klass, *refklass;
- MonoArray *res = NULL;
+ MonoClass *startklass, *klass;
MonoMethod *method;
- MonoObject *member;
- int i, match;
+ int match;
gpointer iter = NULL;
- MonoPtrArray tmp_array;
+ GPtrArray *res_array;
MonoError error;
- domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref) {
- res = mono_array_new_cached (domain, mono_defaults.method_info_class, 0, &error);
- mono_error_set_pending_exception (&error);
- return res;
+ return g_ptr_array_new ();
}
- mono_ptr_array_init (tmp_array, 4, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection constructors list"); /*FIXME, guestimating*/
-
-
klass = startklass = mono_class_from_mono_type (type->type);
- refklass = mono_class_from_mono_type (reftype->type);
mono_class_setup_methods (klass);
if (mono_class_has_failure (klass)) {
- mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
- goto leave;
+ mono_error_init (&error);
+ mono_error_set_for_class_failure (&error, klass);
+ mono_error_set_pending_exception (&error);
+ return NULL;
}
+ res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
+
iter = NULL;
while ((method = mono_class_get_methods (klass, &iter))) {
match = 0;
if (!match)
continue;
- member = (MonoObject*)mono_method_get_object_checked (domain, method, refklass, &error);
- if (mono_error_set_pending_exception (&error))
- goto leave;
-
- mono_ptr_array_append (tmp_array, member);
+ g_ptr_array_add (res_array, method);
}
- res = mono_array_new_cached (domain, mono_class_get_constructor_info_class (), mono_ptr_array_size (tmp_array), &error);
- if (mono_error_set_pending_exception (&error))
- goto leave;
-
- for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
- mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
-leave:
- mono_ptr_array_destroy (tmp_array);
-
- return res;
+ return res_array;
}
static guint
return method_nonpublic (accessor, start_klass);
}
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case)
{
MonoError error;
- MonoDomain *domain;
MonoClass *startklass, *klass;
- MonoArray *res;
MonoMethod *method;
MonoProperty *prop;
- int i, match;
+ int match;
guint32 flags;
gchar *propname = NULL;
int (*compare_func) (const char *s1, const char *s2) = NULL;
gpointer iter;
GHashTable *properties = NULL;
- MonoPtrArray tmp_array;
+ GPtrArray *res_array;
- mono_error_init (&error);
-
- domain = ((MonoObject *)type)->vtable->domain;
if (type->type->byref) {
- res = mono_array_new_cached (domain, mono_class_get_property_info_class (), 0, &error);
- mono_error_set_pending_exception (&error);
- return res;
+ return g_ptr_array_new ();
}
- mono_ptr_array_init (tmp_array, 8, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection properties list"); /*This the average for ASP.NET types*/
-
+ mono_error_init (&error);
+
klass = startklass = mono_class_from_mono_type (type->type);
if (name != NULL) {
compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
}
+ res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
+
properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
handle_parent:
mono_class_setup_methods (klass);
if (g_hash_table_lookup (properties, prop))
continue;
- MonoReflectionProperty *pr = mono_property_get_object_checked (domain, startklass, prop, &error);
- if (!pr)
- goto failure;
- mono_ptr_array_append (tmp_array, pr);
+ g_ptr_array_add (res_array, prop);
g_hash_table_insert (properties, prop, prop);
}
- if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
+ if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
goto handle_parent;
g_hash_table_destroy (properties);
g_free (propname);
- res = mono_array_new_cached (domain, mono_class_get_property_info_class (), mono_ptr_array_size (tmp_array), &error);
- if (!is_ok (&error))
- goto failure;
- for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
- mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
- mono_ptr_array_destroy (tmp_array);
-
- return res;
-
+ return res_array;
loader_error:
if (mono_class_has_failure (klass))
mono_error_set_for_class_failure (&error, klass);
-failure:
if (properties)
g_hash_table_destroy (properties);
if (name)
g_free (propname);
- mono_ptr_array_destroy (tmp_array);
+ g_ptr_array_free (res_array, FALSE);
mono_error_set_pending_exception (&error);
return g_str_equal (event1->name, event2->name);
}
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetEvents_internal (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoReflectionType *reftype)
+ICALL_EXPORT GPtrArray*
+ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *name, guint32 bflags)
{
MonoError error;
- MonoDomain *domain;
MonoClass *startklass, *klass;
- MonoArray *res;
MonoMethod *method;
MonoEvent *event;
- int i, match;
+ int match;
gpointer iter;
char *utf8_name = NULL;
int (*compare_func) (const char *s1, const char *s2) = NULL;
GHashTable *events = NULL;
- MonoPtrArray tmp_array;
+ GPtrArray *res_array;
- mono_error_init (&error);
-
- domain = mono_object_domain (type);
if (type->type->byref) {
- res = mono_array_new_cached (domain, mono_class_get_event_info_class (), 0, &error);
- mono_error_set_pending_exception (&error);
- return res;
+ return g_ptr_array_new ();
}
- mono_ptr_array_init (tmp_array, 4, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection events list");
+ mono_error_init (&error);
+
+ res_array = g_ptr_array_sized_new (4);
klass = startklass = mono_class_from_mono_type (type->type);
if (g_hash_table_lookup (events, event))
continue;
- MonoReflectionEvent *ev_obj;
- ev_obj = mono_event_get_object_checked (domain, startklass, event, &error);
- if (!ev_obj)
- goto failure;
- mono_ptr_array_append (tmp_array, ev_obj);
+ g_ptr_array_add (res_array, event);
g_hash_table_insert (events, event, event);
}
g_hash_table_destroy (events);
- res = mono_array_new_cached (domain, mono_class_get_event_info_class (), mono_ptr_array_size (tmp_array), &error);
- if (!is_ok (&error))
- goto failure;
-
- for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
- mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
- mono_ptr_array_destroy (tmp_array);
-
if (utf8_name != NULL)
g_free (utf8_name);
- return res;
+ return res_array;
loader_error:
if (mono_class_has_failure (klass))
if (utf8_name != NULL)
g_free (utf8_name);
- mono_ptr_array_destroy (tmp_array);
+ g_ptr_array_free (res_array, FALSE);
mono_error_set_pending_exception (&error);
return NULL;
return result;
}
+ICALL_EXPORT MonoString*
+ves_icall_System_Reflection_Assembly_GetAotId ()
+{
+ int i;
+ guint8 aotid_sum = 0;
+ MonoDomain* domain = mono_domain_get ();
+
+ if (!domain->entry_assembly || !domain->entry_assembly->image)
+ return NULL;
+
+ guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
+
+ for (i = 0; i < 16; ++i)
+ aotid_sum |= (*aotid)[i];
+
+ if (aotid_sum == 0)
+ return NULL;
+
+ return mono_string_new (domain, mono_guid_to_string((guint8*) aotid));
+}
+
static MonoObject*
create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision, MonoError *error)
{
mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
- if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
+ if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
info->location = 0;
else
info->location = RESOURCE_LOCATION_EMBEDDED;
for (i = 0; i < file_count; ++i, ++j) {
mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
- if (cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA) {
+ if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
if (mono_error_set_pending_exception (&error))
return NULL;
}
ICALL_EXPORT MonoReflectionMethod*
-ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
+ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
{
MonoReflectionMethod *res = NULL;
MonoError error;
MonoClass *klass;
- if (type) {
+ if (type && generic_check) {
klass = mono_class_from_mono_type (type);
- if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
+ if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
return NULL;
+
if (method->klass != klass) {
method = mono_method_get_equivalent_method (method, klass);
if (!method)
return NULL;
}
- } else
+ } else if (type)
+ klass = mono_class_from_mono_type (type);
+ else
klass = method->klass;
res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
mono_error_set_pending_exception (&error);
}
#endif
} else if (level==2) {
- if (is_string == TRUE || (is_string == FALSE && lang_id != 0 && name_offset != lang_id))
+ if (is_string || (lang_id != 0 && name_offset != lang_id))
return NULL;
} else {
g_assert_not_reached ();
}
- if(is_dir==TRUE) {
+ if (is_dir) {
MonoPEResourceDir *res_dir=(MonoPEResourceDir *)(((char *)root)+dir_offset);
MonoPEResourceDirEntry *sub_entries=(MonoPEResourceDirEntry *)(res_dir+1);
guint32 entries, i;
*/
}
if (dll_map->func && strcmp (dll_map->func, func) == 0) {
+ *rdll = dll_map->target;
*rfunc = dll_map->target_func;
break;
}
* @dll: The name of the external library, as it would be found in the DllImport declaration. If prefixed with 'i:' the matching of the library name is done without case sensitivity
* @func: if not null, the mapping will only applied to the named function (the value of EntryPoint)
* @tdll: The name of the library to map the specified @dll if it matches.
- * @tfunc: if func is not NULL, the name of the function that replaces the invocation
+ * @tfunc: The name of the function that replaces the invocation. If NULL, it is replaced with a copy of @func.
*
* LOCKING: Acquires the loader lock.
*
entry->dll = dll? g_strdup (dll): NULL;
entry->target = tdll? g_strdup (tdll): NULL;
entry->func = func? g_strdup (func): NULL;
- entry->target_func = tfunc? g_strdup (tfunc): NULL;
+ entry->target_func = tfunc? g_strdup (tfunc): (func? g_strdup (func): NULL);
global_loader_data_lock ();
entry->next = global_dll_map;
entry->dll = dll? mono_image_strdup (assembly, dll): NULL;
entry->target = tdll? mono_image_strdup (assembly, tdll): NULL;
entry->func = func? mono_image_strdup (assembly, func): NULL;
- entry->target_func = tfunc? mono_image_strdup (assembly, tfunc): NULL;
+ entry->target_func = tfunc? mono_image_strdup (assembly, tfunc): (func? mono_image_strdup (assembly, func): NULL);
mono_image_lock (assembly);
entry->next = assembly->dll_map;
return delegate->delegate_trampoline;
fail:
- mono_gchandle_free (target_handle);
+ if (target_handle != 0)
+ mono_gchandle_free (target_handle);
mono_error_set_pending_exception (&error);
return NULL;
}
* ARGS should contain the this argument too.
* This wrapper serves the same purpose as the runtime-invoke wrappers, but there
* is only one copy of it, which is useful in full-aot.
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod*
mono_marshal_get_runtime_invoke_dynamic (void)
/*
* generates IL code for the icall wrapper (the generated method
* calls the unmanaged code in func)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gconstpointer func, gboolean check_exceptions)
/* Set LastError if needed */
if (piinfo->piflags & PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR) {
#ifdef TARGET_WIN32
- static MonoMethodSignature *get_last_error_sig = NULL;
- if (!get_last_error_sig) {
- get_last_error_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
- get_last_error_sig->ret = &mono_defaults.int_class->byval_arg;
- get_last_error_sig->pinvoke = 1;
- }
+ if (!aot) {
+ static MonoMethodSignature *get_last_error_sig = NULL;
+ if (!get_last_error_sig) {
+ get_last_error_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
+ get_last_error_sig->ret = &mono_defaults.int_class->byval_arg;
+ get_last_error_sig->pinvoke = 1;
+ }
- /*
- * Have to call GetLastError () early and without a wrapper, since various runtime components could
- * clobber its value.
- */
- mono_mb_emit_native_call (mb, get_last_error_sig, GetLastError);
- mono_mb_emit_icall (mb, mono_marshal_set_last_error_windows);
+ /*
+ * Have to call GetLastError () early and without a wrapper, since various runtime components could
+ * clobber its value.
+ */
+ mono_mb_emit_native_call (mb, get_last_error_sig, GetLastError);
+ mono_mb_emit_icall (mb, mono_marshal_set_last_error_windows);
+ } else {
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_GET_LAST_ERROR);
+ mono_mb_emit_icall (mb, mono_marshal_set_last_error_windows);
+ }
#else
mono_mb_emit_icall (mb, mono_marshal_set_last_error);
#endif
*
* generates IL code for the pinvoke wrapper (the generated method
* calls the unmanaged code in piinfo->addr)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, gboolean aot)
/*
* This does the equivalent of mono_object_castclass_with_cache.
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_castclass_with_cache (void)
/*
* This does the equivalent of mono_object_isinst_with_cache.
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_isinst_with_cache (void)
* an instance of the given type, icluding the case where the object is a proxy.
* The generated function has the following signature:
* MonoObject* __castclass_wrapper_ (MonoObject *obj)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_castclass (MonoClass *klass)
* @klass:
*
* generates IL code for StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_struct_to_ptr (MonoClass *klass)
* @klass:
*
* generates IL code for PtrToStructure (IntPtr src, object structure)
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_ptr_to_struct (MonoClass *klass)
* This is used to avoid infinite recursion since it is hard to determine where to
* replace a method with its synchronized wrapper, and where not.
* The runtime should execute METHOD instead of the wrapper.
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod *
mono_marshal_get_synchronized_inner_wrapper (MonoMethod *method)
#endif
/*
- * The wrapper info for the wrapper is a WrapperInfo structure.
- *
* TODO:
* - Separate simple interfaces from variant interfaces or mbr types. This way we can avoid the icall for them.
* - Emit a (new) mono bytecode that produces OP_COND_EXC_NE_UN to raise ArrayTypeMismatch
MonoMethod *res;
char *name;
const char *param_names [16];
- guint32 b1, b2, b3;
+ guint32 b1, b2, b3, b4;
int aklass, vklass, vtable, uiid;
int array_slot_addr;
WrapperInfo *info;
mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoClass, idepth));
mono_mb_emit_byte (mb, CEE_LDIND_U2);
- b2 = mono_mb_emit_branch (mb, CEE_BLT_UN);
+ b3 = mono_mb_emit_branch (mb, CEE_BLT_UN);
/* if (vklass->supertypes [aklass->idepth - 1] != aklass) goto failure */
mono_mb_emit_ldloc (mb, vklass);
mono_mb_emit_byte (mb, CEE_LDIND_I);
mono_mb_emit_ldloc (mb, aklass);
- b3 = mono_mb_emit_branch (mb, CEE_BNE_UN);
+ b4 = mono_mb_emit_branch (mb, CEE_BNE_UN);
/* do_store: */
mono_mb_patch_branch (mb, b1);
/* do_exception: */
mono_mb_patch_branch (mb, b2);
mono_mb_patch_branch (mb, b3);
+ mono_mb_patch_branch (mb, b4);
mono_mb_emit_exception (mb, "ArrayTypeMismatchException", NULL);
break;
return res;
}
-/*
- * The wrapper info for the wrapper is a WrapperInfo structure.
- */
MonoMethod*
mono_marshal_get_stelemref (void)
{
* mono_marshal_get_gsharedvt_in_wrapper:
*
* This wrapper handles calls from normal code to gsharedvt code.
- *
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod*
mono_marshal_get_gsharedvt_in_wrapper (void)
* mono_marshal_get_gsharedvt_out_wrapper:
*
* This wrapper handles calls from gsharedvt code to normal code.
- *
- * The wrapper info for the wrapper is a WrapperInfo structure.
*/
MonoMethod*
mono_marshal_get_gsharedvt_out_wrapper (void)
MonoException *exc;
gpointer stackdata;
- g_assert (gchandle >= 0);
-
mono_threads_enter_gc_unsafe_region_unbalanced (&stackdata);
exc = (MonoException*) mono_gchandle_get_target (gchandle);
{
MonoMemPool *p;
int count = 0;
- guint32 still_free = pool->end - pool->pos;
+ guint32 still_free;
p = pool;
while (p) {
count++;
}
if (pool) {
+ still_free = pool->end - pool->pos;
g_print ("Mempool %p stats:\n", pool);
g_print ("Total mem allocated: %d\n", pool->d.allocated);
g_print ("Num chunks: %d\n", count);
gpointer aot_module;
+ guint8 aotid[16];
+
/*
* The Assembly this image was loaded from.
*/
if (!read32 (ptr + 8) || !read32 (ptr + 12))
ADD_ERROR (ctx, g_strdup_printf ("Missing medatata section in the CLI header"));
- if ((read32 (ptr + 16) & ~0x0001000B) != 0)
+ if ((read32 (ptr + 16) & ~0x0003000B) != 0)
ADD_ERROR (ctx, g_strdup_printf ("Invalid CLI header flags"));
ptr += 24;
return FALSE;
if (original_sig->explicit_this != signature->explicit_this)
return FALSE;
- if (original_sig->call_convention != signature->call_convention)
- return FALSE;
if (original_sig->pinvoke != signature->pinvoke)
return FALSE;
if (original_sig->sentinelpos != signature->sentinelpos)
guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
}
+/**
+ * mono_guid_to_string_minimal:
+ *
+ * Converts a 16 byte Microsoft GUID to lower case no '-' representation..
+ */
+char *
+mono_guid_to_string_minimal (const guint8 *guid)
+{
+ return g_strdup_printf ("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ guid[3], guid[2], guid[1], guid[0],
+ guid[5], guid[4],
+ guid[7], guid[6],
+ guid[8], guid[9],
+ guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
+}
static gboolean
get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGenericContainer *container, MonoError *error)
{
struct _MonoArrayType {
MonoClass *eklass;
+ // Number of dimensions of the array
uint8_t rank;
+
+ // Arrays recording known upper and lower index bounds for each dimension
uint8_t numsizes;
uint8_t numlobounds;
int *sizes;
MONO_API char *mono_guid_to_string (const uint8_t *guid);
+MONO_API char *mono_guid_to_string_minimal (const uint8_t *guid);
+
MONO_API uint32_t mono_metadata_declsec_from_index (MonoImage *meta, uint32_t idx);
MONO_API uint32_t mono_metadata_translate_token_index (MonoImage *image, int table, uint32_t idx);
memset (&info->old_version_bottom, 0, sizeof (info->old_version_bottom));
memset (&info->old_version_top, 0, sizeof (info->old_version_top));
memset (&info->new_version, 0, sizeof (info->new_version));
- } if (!strcmp (element_name, "assemblyIdentity")) {
+ } else if (!strcmp (element_name, "assemblyIdentity")) {
for (n = 0; attribute_names [n]; n++) {
const gchar *attribute_name = attribute_names [n];
#include <mono/io-layer/io-layer.h>
/* FIXME: fix this code to not depend so much on the internals */
#include <mono/metadata/class-internals.h>
+#include <mono/utils/w32handle.h>
#define LOGDEBUG(...)
/* define LOGDEBUG(...) g_message(__VA_ARGS__) */
MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, name));
MONO_OBJECT_SETREF (res, name, mono_string_new (domain, name));
MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, name));
- res->is_resource = cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA;
+ res->is_resource = cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA;
res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1);
return res;
MonoReflectionEvent *res;
MonoReflectionMonoEvent *mono_event;
+ mono_error_init (error);
CHECK_OBJECT (MonoReflectionEvent *, event, klass);
mono_event = (MonoReflectionMonoEvent *)mono_object_new_checked (domain, mono_class_get_mono_event_class (), error);
if (!mono_event)
klass = mono_defaults.array_class;
} else if (type->type == MONO_TYPE_VALUETYPE) {
klass = type->data.klass;
- } else if (t == MONO_TYPE_OBJECT || t == MONO_TYPE_CLASS || t == MONO_TYPE_STRING ||
- t == MONO_TYPE_CLASS) {
+ } else if (t == MONO_TYPE_OBJECT || t == MONO_TYPE_CLASS || t == MONO_TYPE_STRING) {
klass = mono_defaults.object_class;
} else if (t == MONO_TYPE_PTR || t == MONO_TYPE_FNPTR) {
klass = mono_defaults.int_class;
void (*register_finalized_object) (GCObject *object);
void (*describe_pointer) (GCObject *object);
void (*enable_accounting) (void);
+
+ // Optional-- used for debugging
void (*set_dump_prefix) (const char *prefix);
/*
void sgen_tarjan_bridge_init (SgenBridgeProcessor *collector);
void sgen_set_bridge_implementation (const char *name);
void sgen_bridge_set_dump_prefix (const char *prefix);
+void sgen_init_bridge (void);
#endif
#include "sgen/sgen-qsort.h"
#include "utils/mono-logger-internals.h"
+typedef enum {
+ BRIDGE_PROCESSOR_INVALID,
+ BRIDGE_PROCESSOR_OLD,
+ BRIDGE_PROCESSOR_NEW,
+ BRIDGE_PROCESSOR_TARJAN,
+ BRIDGE_PROCESSOR_DEFAULT = BRIDGE_PROCESSOR_TARJAN
+} BridgeProcessorSelection;
+
+// Bridge processor type pending / in use
+static BridgeProcessorSelection bridge_processor_selection = BRIDGE_PROCESSOR_DEFAULT;
+// Most recently requested callbacks
+static MonoGCBridgeCallbacks pending_bridge_callbacks;
+// Currently-in-use callbacks
MonoGCBridgeCallbacks bridge_callbacks;
+
+// Bridge processor state
static SgenBridgeProcessor bridge_processor;
+// This is used for a special debug feature
static SgenBridgeProcessor compare_to_bridge_processor;
volatile gboolean bridge_processing_in_progress = FALSE;
+// FIXME: The current usage pattern for this function is unsafe. Bridge processing could start immediately after unlock
void
mono_gc_wait_for_bridge_processing (void)
{
sgen_gc_unlock ();
}
-
void
mono_gc_register_bridge_callbacks (MonoGCBridgeCallbacks *callbacks)
{
if (callbacks->bridge_version != SGEN_BRIDGE_VERSION)
g_error ("Invalid bridge callback version. Expected %d but got %d\n", SGEN_BRIDGE_VERSION, callbacks->bridge_version);
- bridge_callbacks = *callbacks;
+ // Defer assigning to bridge_callbacks until we have the gc lock.
+ // Note: This line is unsafe if we are on a separate thread from the one the runtime was initialized on.
+ pending_bridge_callbacks = *callbacks;
- // If callbacks are still uninitialized, initialize defaults
- if (!bridge_processor.reset_data)
- sgen_tarjan_bridge_init (&bridge_processor);
+ // If sgen has started, will assign bridge callbacks and init bridge
+ sgen_init_bridge ();
}
-static gboolean
-init_bridge_processor (SgenBridgeProcessor *processor, const char *name)
+static BridgeProcessorSelection
+bridge_processor_name (const char *name)
{
if (!strcmp ("old", name)) {
- memset (processor, 0, sizeof (SgenBridgeProcessor));
- sgen_old_bridge_init (processor);
+ return BRIDGE_PROCESSOR_OLD;
} else if (!strcmp ("new", name)) {
- memset (processor, 0, sizeof (SgenBridgeProcessor));
- sgen_new_bridge_init (processor);
+ return BRIDGE_PROCESSOR_NEW;
} else if (!strcmp ("tarjan", name)) {
- memset (processor, 0, sizeof (SgenBridgeProcessor));
- sgen_tarjan_bridge_init (processor);
+ return BRIDGE_PROCESSOR_TARJAN;
} else {
- return FALSE;
+ return BRIDGE_PROCESSOR_INVALID;
+ }
+}
+
+// Initialize a single bridge processor
+static void
+init_bridge_processor (SgenBridgeProcessor *processor, BridgeProcessorSelection selection)
+{
+ memset (processor, 0, sizeof (SgenBridgeProcessor));
+
+ switch (selection) {
+ case BRIDGE_PROCESSOR_OLD:
+ sgen_old_bridge_init (processor);
+ break;
+ case BRIDGE_PROCESSOR_NEW:
+ sgen_new_bridge_init (processor);
+ break;
+ case BRIDGE_PROCESSOR_TARJAN:
+ sgen_tarjan_bridge_init (processor);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+/*
+ * Initializing the sgen bridge consists of setting the bridge callbacks,
+ * and initializing the bridge processor. Init should follow these rules:
+ *
+ * - Init happens only after sgen is initialized (because we don't
+ * know which bridge processor to initialize until then, and also
+ * to allow bridge processor init to interact with sgen if it wants)
+ *
+ * - Init happens only after mono_gc_register_bridge_callbacks is called
+ *
+ * - Init should not happen concurrently with a GC (because a GC will
+ * call sgen_need_bridge_processing at various times)
+ *
+ * - Initializing the bridge processor should happen only once
+ *
+ * We call sgen_init_bridge when the callbacks are set, and also when sgen
+ * is done initing. Actual initialization then only occurs if it is ready.
+ */
+void
+sgen_init_bridge ()
+{
+ if (sgen_gc_initialized ()) {
+ // This lock is not initialized until the GC is
+ sgen_gc_lock ();
+
+ bridge_callbacks = pending_bridge_callbacks;
+
+ // If a bridge was registered but there is no bridge processor yet
+ if (bridge_callbacks.cross_references && !bridge_processor.reset_data)
+ init_bridge_processor (&bridge_processor, bridge_processor_selection);
+
+ sgen_gc_unlock ();
}
- return TRUE;
}
void
sgen_set_bridge_implementation (const char *name)
{
- if (!init_bridge_processor (&bridge_processor, name))
- g_warning ("Invalid value for bridge implementation, valid values are: 'new', 'old' and 'tarjan'.");
+ BridgeProcessorSelection selection = bridge_processor_name (name);
+
+ if (selection == BRIDGE_PROCESSOR_INVALID)
+ g_warning ("Invalid value for bridge processor implementation, valid values are: 'new', 'old' and 'tarjan'.");
+ else if (bridge_processor.reset_data)
+ g_warning ("Cannot set bridge processor implementation once bridge has already started");
+ else
+ bridge_processor_selection = selection;
}
gboolean
set_dump_prefix (prefix);
} else if (g_str_has_prefix (opt, "bridge-compare-to=")) {
const char *name = strchr (opt, '=') + 1;
- if (init_bridge_processor (&compare_to_bridge_processor, name)) {
- if (compare_to_bridge_processor.reset_data == bridge_processor.reset_data) {
- g_warning ("Cannot compare bridge implementation to itself - ignoring.");
- memset (&compare_to_bridge_processor, 0, sizeof (SgenBridgeProcessor));
- }
+ BridgeProcessorSelection selection = bridge_processor_name (name);
+
+ if (selection != BRIDGE_PROCESSOR_INVALID) {
+ init_bridge_processor (&compare_to_bridge_processor, selection);
} else {
g_warning ("Invalid bridge implementation to compare against - ignoring.");
}
* unreachable objects. We use it in monodroid to do garbage collection across
* the Mono and Java heaps.
*
- * The client can designate some objects as "bridged", which means that they
- * participate in the bridge processing step once SGen considers them
+ * The client (Monodroid) can designate some objects as "bridged", which means
+ * that they participate in the bridge processing step once SGen considers them
* unreachable, i.e., dead. Bridged objects must be registered for
* finalization.
*
* When SGen is done marking, it puts together a list of all dead bridged
- * objects and then does a strongly connected component analysis over their
- * object graph. That graph will usually contain non-bridged objects, too.
+ * objects. This is passed to the bridge processor, which does an analysis to
+ * simplify the graph: It replaces strongly-connected components with single
+ * nodes, and then removes any nodes corresponding to components which do not
+ * contain bridged objects.
*
- * The output of the SCC analysis is passed to the `cross_references()`
- * callback. It is expected to set the `is_alive` flag on those strongly
- * connected components that it wishes to be kept alive. Only bridged objects
- * will be reported to the callback, i.e., non-bridged objects are removed from
- * the callback graph.
+ * The output of the SCC analysis is passed to the client's `cross_references()`
+ * callback. This consists of 2 arrays, an array of SCCs (MonoGCBridgeSCC),
+ * and an array of "xrefs" (edges between SCCs, MonoGCBridgeXRef). Edges are
+ * encoded as pairs of "API indices", ie indexes in the SCC array. The client
+ * is expected to set the `is_alive` flag on those strongly connected components
+ * that it wishes to be kept alive.
*
* In monodroid each bridged object has a corresponding Java mirror object. In
* the bridge callback it reifies the Mono object graph in the Java heap so that
* point all links to bridged objects that don't have `is_alive` set are nulled.
* Note that weak links to non-bridged objects reachable from bridged objects
* are not nulled. This might be considered a bug.
+ *
+ * There are three different implementations of the bridge processor, each of
+ * which implements 8 callbacks (see SgenBridgeProcessor). The implementations
+ * differ in the algorithm they use to compute the "simplified" SCC graph.
*/
#ifndef _MONO_SGEN_BRIDGE_H_
void (*cross_references) (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs);
} MonoGCBridgeCallbacks;
+/*
+ * Note: This may be called at any time, but cannot be called concurrently
+ * with (during and on a separate thread from) sgen init. Callers are
+ * responsible for enforcing this.
+ */
MONO_API void mono_gc_register_bridge_callbacks (MonoGCBridgeCallbacks *callbacks);
MONO_API void mono_gc_wait_for_bridge_processing (void);
--- /dev/null
+/*
+ * Copyright 2016 Xamarin, Inc.
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+ // Growable array implementation used by sgen-new-bridge and sgen-tarjan-bridge.
+
+typedef struct {
+ int size;
+ int capacity; /* if negative, data points to another DynArray's data */
+ char *data;
+} DynArray;
+
+/*Specializations*/
+
+// IntArray supports an optimization (in sgen-new-bridge.c): If capacity is less than 0 it is a "copy" and does not own its buffer.
+typedef struct {
+ DynArray array;
+} DynIntArray;
+
+// PtrArray supports an optimization: If size is equal to 1 it is a "singleton" and data points to the single held item, not to a buffer.
+typedef struct {
+ DynArray array;
+} DynPtrArray;
+
+typedef struct {
+ DynArray array;
+} DynSCCArray;
+
+static void
+dyn_array_init (DynArray *da)
+{
+ da->size = 0;
+ da->capacity = 0;
+ da->data = NULL;
+}
+
+static void
+dyn_array_uninit (DynArray *da, int elem_size)
+{
+ if (da->capacity < 0) {
+ dyn_array_init (da);
+ return;
+ }
+
+ if (da->capacity == 0)
+ return;
+
+ sgen_free_internal_dynamic (da->data, elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA);
+ da->data = NULL;
+}
+
+static void
+dyn_array_empty (DynArray *da)
+{
+ if (da->capacity < 0)
+ dyn_array_init (da);
+ else
+ da->size = 0;
+}
+
+static char *
+dyn_array_ensure_capacity_internal (DynArray *da, int capacity, int elem_size)
+{
+ if (da->capacity <= 0)
+ da->capacity = 2;
+ while (capacity > da->capacity)
+ da->capacity *= 2;
+
+ return (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+}
+
+static void
+dyn_array_ensure_capacity (DynArray *da, int capacity, int elem_size)
+{
+ int old_capacity = da->capacity;
+ char *new_data;
+
+ g_assert (capacity > 0);
+
+ if (capacity <= old_capacity)
+ return;
+
+ new_data = dyn_array_ensure_capacity_internal (da, capacity, elem_size);
+ memcpy (new_data, da->data, elem_size * da->size);
+ if (old_capacity > 0)
+ sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA);
+ da->data = new_data;
+}
+
+static gboolean
+dyn_array_is_copy (DynArray *da)
+{
+ return da->capacity < 0;
+}
+
+static void
+dyn_array_ensure_independent (DynArray *da, int elem_size)
+{
+ if (!dyn_array_is_copy (da))
+ return;
+ dyn_array_ensure_capacity (da, da->size, elem_size);
+ g_assert (da->capacity > 0);
+}
+
+static void*
+dyn_array_add (DynArray *da, int elem_size)
+{
+ void *p;
+
+ dyn_array_ensure_capacity (da, da->size + 1, elem_size);
+
+ p = da->data + da->size * elem_size;
+ ++da->size;
+ return p;
+}
+
+static void
+dyn_array_copy (DynArray *dst, DynArray *src, int elem_size)
+{
+ dyn_array_uninit (dst, elem_size);
+
+ if (src->size == 0)
+ return;
+
+ dst->size = src->size;
+ dst->capacity = -1;
+ dst->data = src->data;
+}
+
+/* int */
+static void
+dyn_array_int_init (DynIntArray *da)
+{
+ dyn_array_init (&da->array);
+}
+
+static void
+dyn_array_int_uninit (DynIntArray *da)
+{
+ dyn_array_uninit (&da->array, sizeof (int));
+}
+
+static int
+dyn_array_int_size (DynIntArray *da)
+{
+ return da->array.size;
+}
+
+#ifdef NEW_XREFS
+static void
+dyn_array_int_empty (DynIntArray *da)
+{
+ dyn_array_empty (&da->array);
+}
+#endif
+
+static void
+dyn_array_int_add (DynIntArray *da, int x)
+{
+ int *p = (int *)dyn_array_add (&da->array, sizeof (int));
+ *p = x;
+}
+
+static int
+dyn_array_int_get (DynIntArray *da, int x)
+{
+ return ((int*)da->array.data)[x];
+}
+
+#ifdef NEW_XREFS
+static void
+dyn_array_int_set (DynIntArray *da, int idx, int val)
+{
+ ((int*)da->array.data)[idx] = val;
+}
+#endif
+
+static void
+dyn_array_int_ensure_independent (DynIntArray *da)
+{
+ dyn_array_ensure_independent (&da->array, sizeof (int));
+}
+
+static void
+dyn_array_int_copy (DynIntArray *dst, DynIntArray *src)
+{
+ dyn_array_copy (&dst->array, &src->array, sizeof (int));
+}
+
+static gboolean
+dyn_array_int_is_copy (DynIntArray *da)
+{
+ return dyn_array_is_copy (&da->array);
+}
+
+/* ptr */
+
+static void
+dyn_array_ptr_init (DynPtrArray *da)
+{
+ dyn_array_init (&da->array);
+}
+
+static void
+dyn_array_ptr_uninit (DynPtrArray *da)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1)
+ dyn_array_ptr_init (da);
+ else
+#endif
+ dyn_array_uninit (&da->array, sizeof (void*));
+}
+
+static int
+dyn_array_ptr_size (DynPtrArray *da)
+{
+ return da->array.size;
+}
+
+static void
+dyn_array_ptr_empty (DynPtrArray *da)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1)
+ dyn_array_ptr_init (da);
+ else
+#endif
+ dyn_array_empty (&da->array);
+}
+
+static void*
+dyn_array_ptr_get (DynPtrArray *da, int x)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1) {
+ g_assert (x == 0);
+ return da->array.data;
+ }
+#endif
+ return ((void**)da->array.data)[x];
+}
+
+static void
+dyn_array_ptr_set (DynPtrArray *da, int x, void *ptr)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1) {
+ g_assert (x == 0);
+ da->array.data = ptr;
+ } else
+#endif
+ {
+ ((void**)da->array.data)[x] = ptr;
+ }
+}
+
+static void
+dyn_array_ptr_add (DynPtrArray *da, void *ptr)
+{
+ void **p;
+
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 0) {
+ da->array.capacity = 1;
+ da->array.size = 1;
+ p = (void**)&da->array.data;
+ } else if (da->array.capacity == 1) {
+ void *ptr0 = da->array.data;
+ void **p0;
+ dyn_array_init (&da->array);
+ p0 = (void **)dyn_array_add (&da->array, sizeof (void*));
+ *p0 = ptr0;
+ p = (void **)dyn_array_add (&da->array, sizeof (void*));
+ } else
+#endif
+ {
+ p = (void **)dyn_array_add (&da->array, sizeof (void*));
+ }
+ *p = ptr;
+}
+
+#define dyn_array_ptr_push dyn_array_ptr_add
+
+static void*
+dyn_array_ptr_pop (DynPtrArray *da)
+{
+ int size = da->array.size;
+ void *p;
+ g_assert (size > 0);
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (da->array.capacity == 1) {
+ p = dyn_array_ptr_get (da, 0);
+ dyn_array_init (&da->array);
+ } else
+#endif
+ {
+ g_assert (da->array.capacity > 1);
+ dyn_array_ensure_independent (&da->array, sizeof (void*));
+ p = dyn_array_ptr_get (da, size - 1);
+ --da->array.size;
+ }
+ return p;
+}
+
+static void
+dyn_array_ptr_ensure_capacity (DynPtrArray *da, int capacity)
+{
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (capacity == 1 && da->array.capacity < 1) {
+ da->array.capacity = 1;
+ } else if (da->array.capacity == 1) // TODO size==1
+ {
+ if (capacity > 1)
+ {
+ void *ptr = dyn_array_ptr_get (da, 0);
+ da->array.data = dyn_array_ensure_capacity_internal(&da->array, capacity, sizeof (void*));
+ dyn_array_ptr_set (da, 0, ptr);
+ }
+ }
+#endif
+ {
+ dyn_array_ensure_capacity (&da->array, capacity, sizeof (void*));
+ }
+}
+
+static void
+dyn_array_ptr_set_all (DynPtrArray *dst, DynPtrArray *src)
+{
+ const int copysize = src->array.size;
+ if (copysize > 0) {
+ dyn_array_ptr_ensure_capacity (dst, copysize);
+
+#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
+ if (copysize == 1) {
+ dyn_array_ptr_set (dst, 0, dyn_array_ptr_get (src, 0));
+ } else
+#endif
+ {
+ memcpy (dst->array.data, src->array.data, copysize * sizeof (void*));
+ }
+ }
+ dst->array.size = src->array.size;
+}
* @out_array: output array
* @out_size: size of output array
*
- * Store inside @out_array up to @out_size objects that belong to the unloading
- * appdomain @domain. Returns the number of stored items. Can be called repeteadly
- * until it returns 0.
- * The items are removed from the finalizer data structure, so the caller is supposed
- * to finalize them.
- * @out_array should be on the stack to allow the GC to know the objects are still alive.
+ * Enqueue for finalization all objects that belong to the unloading appdomain @domain
+ * @suspend is used for early termination of the enqueuing process.
*/
-int
-mono_gc_finalizers_for_domain (MonoDomain *domain, MonoObject **out_array, int out_size)
+void
+mono_gc_finalize_domain (MonoDomain *domain, volatile gboolean *suspend)
{
- return sgen_gather_finalizers_if (object_in_domain_predicate, domain, out_array, out_size);
+ sgen_finalize_if (object_in_domain_predicate, domain, suspend);
}
/*
#include "tabledefs.h"
#include "utils/mono-logger-internals.h"
+#define OPTIMIZATION_COPY
+#define OPTIMIZATION_FORWARD
+#define OPTIMIZATION_SINGLETON_DYN_ARRAY
+#include "sgen-dynarray.h"
+
//#define NEW_XREFS
#ifdef NEW_XREFS
//#define TEST_NEW_XREFS
#define XREFS old_xrefs
#endif
-#define OPTIMIZATION_COPY
-#define OPTIMIZATION_FORWARD
-#define OPTIMIZATION_SINGLETON_DYN_ARRAY
-
-typedef struct {
- int size;
- int capacity; /* if negative, data points to another DynArray's data */
- char *data;
-} DynArray;
-
-/*Specializations*/
-
-typedef struct {
- DynArray array;
-} DynIntArray;
-
-typedef struct {
- DynArray array;
-} DynPtrArray;
-
-typedef struct {
- DynArray array;
-} DynSCCArray;
-
-
/*
* Bridge data for a single managed object
*
static SgenBridgeProcessor *bridge_processor;
/* Core functions */
-/* public */
-
-/* private */
-
-static void
-dyn_array_init (DynArray *da)
-{
- da->size = 0;
- da->capacity = 0;
- da->data = NULL;
-}
-
-static void
-dyn_array_uninit (DynArray *da, int elem_size)
-{
- if (da->capacity < 0) {
- dyn_array_init (da);
- return;
- }
-
- if (da->capacity == 0)
- return;
-
- sgen_free_internal_dynamic (da->data, elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA);
- da->data = NULL;
-}
-
-static void
-dyn_array_empty (DynArray *da)
-{
- if (da->capacity < 0)
- dyn_array_init (da);
- else
- da->size = 0;
-}
-
-static void
-dyn_array_ensure_capacity (DynArray *da, int capacity, int elem_size)
-{
- int old_capacity = da->capacity;
- char *new_data;
-
- g_assert (capacity > 0);
-
- if (capacity <= old_capacity)
- return;
-
- if (old_capacity <= 0)
- da->capacity = 2;
- while (capacity > da->capacity)
- da->capacity *= 2;
-
- new_data = (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
- memcpy (new_data, da->data, elem_size * da->size);
- if (old_capacity > 0)
- sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA);
- da->data = new_data;
-}
-
-static gboolean
-dyn_array_is_copy (DynArray *da)
-{
- return da->capacity < 0;
-}
-
-static void
-dyn_array_ensure_independent (DynArray *da, int elem_size)
-{
- if (!dyn_array_is_copy (da))
- return;
- dyn_array_ensure_capacity (da, da->size, elem_size);
- g_assert (da->capacity > 0);
-}
-
-static void*
-dyn_array_add (DynArray *da, int elem_size)
-{
- void *p;
-
- dyn_array_ensure_capacity (da, da->size + 1, elem_size);
-
- p = da->data + da->size * elem_size;
- ++da->size;
- return p;
-}
-
-static void
-dyn_array_copy (DynArray *dst, DynArray *src, int elem_size)
-{
- dyn_array_uninit (dst, elem_size);
-
- if (src->size == 0)
- return;
-
- dst->size = src->size;
- dst->capacity = -1;
- dst->data = src->data;
-}
-
-/* int */
-static void
-dyn_array_int_init (DynIntArray *da)
-{
- dyn_array_init (&da->array);
-}
-
-static void
-dyn_array_int_uninit (DynIntArray *da)
-{
- dyn_array_uninit (&da->array, sizeof (int));
-}
-
-static int
-dyn_array_int_size (DynIntArray *da)
-{
- return da->array.size;
-}
-
-#ifdef NEW_XREFS
-static void
-dyn_array_int_empty (DynIntArray *da)
-{
- dyn_array_empty (&da->array);
-}
-#endif
-
-static void
-dyn_array_int_add (DynIntArray *da, int x)
-{
- int *p = (int *)dyn_array_add (&da->array, sizeof (int));
- *p = x;
-}
-
-static int
-dyn_array_int_get (DynIntArray *da, int x)
-{
- return ((int*)da->array.data)[x];
-}
-
-#ifdef NEW_XREFS
-static void
-dyn_array_int_set (DynIntArray *da, int idx, int val)
-{
- ((int*)da->array.data)[idx] = val;
-}
-#endif
-
-static void
-dyn_array_int_ensure_independent (DynIntArray *da)
-{
- dyn_array_ensure_independent (&da->array, sizeof (int));
-}
-
-static void
-dyn_array_int_copy (DynIntArray *dst, DynIntArray *src)
-{
- dyn_array_copy (&dst->array, &src->array, sizeof (int));
-}
-
-static gboolean
-dyn_array_int_is_copy (DynIntArray *da)
-{
- return dyn_array_is_copy (&da->array);
-}
-
-/* ptr */
-
-static void
-dyn_array_ptr_init (DynPtrArray *da)
-{
- dyn_array_init (&da->array);
-}
-
-static void
-dyn_array_ptr_uninit (DynPtrArray *da)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 1)
- dyn_array_ptr_init (da);
- else
-#endif
- dyn_array_uninit (&da->array, sizeof (void*));
-}
-
-static int
-dyn_array_ptr_size (DynPtrArray *da)
-{
- return da->array.size;
-}
-
-static void
-dyn_array_ptr_empty (DynPtrArray *da)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 1)
- dyn_array_ptr_init (da);
- else
-#endif
- dyn_array_empty (&da->array);
-}
-
-static void*
-dyn_array_ptr_get (DynPtrArray *da, int x)
-{
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 1) {
- g_assert (x == 0);
- return da->array.data;
- }
-#endif
- return ((void**)da->array.data)[x];
-}
-
-static void
-dyn_array_ptr_add (DynPtrArray *da, void *ptr)
-{
- void **p;
-
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 0) {
- da->array.capacity = 1;
- da->array.size = 1;
- p = (void**)&da->array.data;
- } else if (da->array.capacity == 1) {
- void *ptr0 = da->array.data;
- void **p0;
- dyn_array_init (&da->array);
- p0 = (void **)dyn_array_add (&da->array, sizeof (void*));
- *p0 = ptr0;
- p = (void **)dyn_array_add (&da->array, sizeof (void*));
- } else
-#endif
- {
- p = (void **)dyn_array_add (&da->array, sizeof (void*));
- }
- *p = ptr;
-}
-
-#define dyn_array_ptr_push dyn_array_ptr_add
-
-static void*
-dyn_array_ptr_pop (DynPtrArray *da)
-{
- int size = da->array.size;
- void *p;
- g_assert (size > 0);
-#ifdef OPTIMIZATION_SINGLETON_DYN_ARRAY
- if (da->array.capacity == 1) {
- p = dyn_array_ptr_get (da, 0);
- dyn_array_init (&da->array);
- } else
-#endif
- {
- g_assert (da->array.capacity > 1);
- dyn_array_ensure_independent (&da->array, sizeof (void*));
- p = dyn_array_ptr_get (da, size - 1);
- --da->array.size;
- }
- return p;
-}
/*SCC */
gpointer stack_start;
info->client_info.stopped_domain = mono_domain_get ();
+ info->client_info.stack_start = NULL;
info->client_info.signal = 0;
stop_count = sgen_global_stop_count;
/* duplicate signal */
#include "tabledefs.h"
#include "utils/mono-logger-internals.h"
-typedef struct {
- int size;
- int capacity;
- char *data;
-} DynArray;
-
-/*Specializations*/
-
-typedef struct {
- DynArray array;
-} DynPtrArray;
-
-/* private */
-
-static void
-dyn_array_uninit (DynArray *da, int elem_size)
-{
- if (da->capacity <= 0)
- return;
+#include "sgen-dynarray.h"
- sgen_free_internal_dynamic (da->data, elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA);
- da->data = NULL;
-}
-
-static void
-dyn_array_ensure_capacity (DynArray *da, int capacity, int elem_size)
-{
- int old_capacity = da->capacity;
- char *new_data;
-
- if (capacity <= old_capacity)
- return;
-
- if (da->capacity == 0)
- da->capacity = 2;
- while (capacity > da->capacity)
- da->capacity *= 2;
-
- new_data = (char *)sgen_alloc_internal_dynamic (elem_size * da->capacity, INTERNAL_MEM_BRIDGE_DATA, TRUE);
- if (da->data) {
- memcpy (new_data, da->data, elem_size * da->size);
- sgen_free_internal_dynamic (da->data, elem_size * old_capacity, INTERNAL_MEM_BRIDGE_DATA);
- }
- da->data = new_data;
-}
-
-static void*
-dyn_array_add (DynArray *da, int elem_size)
-{
- void *p;
-
- dyn_array_ensure_capacity (da, da->size + 1, elem_size);
-
- p = da->data + da->size * elem_size;
- ++da->size;
- return p;
-}
-
-/* ptr */
-
-static void
-dyn_array_ptr_uninit (DynPtrArray *da)
-{
- dyn_array_uninit (&da->array, sizeof (void*));
-}
-
-static int
-dyn_array_ptr_size (DynPtrArray *da)
-{
- return da->array.size;
-}
-
-static void
-dyn_array_ptr_set_size (DynPtrArray *da, int size)
-{
- da->array.size = size;
-}
-
-static void*
-dyn_array_ptr_get (DynPtrArray *da, int x)
-{
- return ((void**)da->array.data)[x];
-}
-
-static void
-dyn_array_ptr_add (DynPtrArray *da, void *ptr)
-{
- void **p = (void **)dyn_array_add (&da->array, sizeof (void*));
- *p = ptr;
-}
-
-#define dyn_array_ptr_push dyn_array_ptr_add
-
-static void*
-dyn_array_ptr_pop (DynPtrArray *da)
-{
- void *p;
- int size = da->array.size;
- g_assert (size > 0);
- p = dyn_array_ptr_get (da, size - 1);
- --da->array.size;
- return p;
-}
-
-static void
-dyn_array_ptr_ensure_capacity (DynPtrArray *da, int capacity)
-{
- dyn_array_ensure_capacity (&da->array, capacity, sizeof (void*));
-}
-
-
-static void
-dyn_array_ptr_set_all (DynPtrArray *dst, DynPtrArray *src)
-{
- if (src->array.size > 0) {
- dyn_array_ptr_ensure_capacity (dst, src->array.size);
- memcpy (dst->array.data, src->array.data, src->array.size * sizeof (void*));
- }
- dst->array.size = src->array.size;
-}
+/*
+ * See comments in sgen-bridge.h
+ *
+ * This bridge implementation is based on the tarjan algorithm for strongly
+ * connected components. It has two elements:
+ *
+ * - Standard tarjan SCC algorithm to convert graph to SCC forest
+ *
+ * - "Colors": We reduce the SCC forest to bridged-SCCs-only by using a
+ * "color" algorithm devised by Kumpera. Consider the set of bridged SCCs
+ * which is reachable from a given object. We call each such unique set a
+ * "color". We compute the set of colors and which colors contain links to
+ * which colors. The color graph then becomes the reduced SCC graph.
+ */
static void
enable_accounting (void)
// hash_table = (SgenHashTable)SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
}
+// Is this class bridged or not, and should its dependencies be scanned or not?
+// The result of this callback will be cached for use by is_opaque_object later.
static MonoGCBridgeObjectKind
class_kind (MonoClass *klass)
{
return GC_BRIDGE_TRANSPARENT_CLASS;
}
-//enable unsage logging
+//enable usage logging
// #define DUMP_GRAPH 1
+// ScanData state
enum {
INITIAL,
SCANNED,
We can split this data structure in two, those with bridges and those without
*/
typedef struct {
+ // Colors (ColorDatas) linked to by objects with this color
DynPtrArray other_colors;
+ // Bridge objects (GCObjects) held by objects with this color
DynPtrArray bridges;
int api_index : 31;
unsigned visited : 1;
} ColorData;
-
-typedef struct {
- GCObject *obj; //XXX this can be eliminated.
+// Represents one managed object. Equivalent of new/old bridge "HashEntry"
+typedef struct _ScanData {
+ // FIXME this can be eliminated; if we have a ScanData we generally looked it up from its GCObject
+ GCObject *obj;
+ // We use the sgen lock_word in GCObject to store a pointer to the ScanData. Cache the original here to restore later:
mword lock_word;
ColorData *color;
+ // Tarjan algorithm index (order visited)
int index;
+ // Tarjan index of lowest-index object known reachable from here
int low_index : 27;
+ // See "ScanData state" enum above
unsigned state : 2;
unsigned is_bridge : 1;
+ // Similar to lock_word, we use these bits in the GCObject as scratch space then restore them when done
unsigned obj_state : 2;
} ScanData;
+// Stacks of ScanData objects used for tarjan algorithm.
+// The Tarjan algorithm is normally defined recursively; here scan_stack simulates the call stack of a recursive algorithm,
+// and loop_stack is the stack structure used by the algorithm itself.
+static DynPtrArray scan_stack, loop_stack;
-static DynPtrArray scan_stack, loop_stack, registered_bridges;
+// GCObjects on which register_finalized_object has been called
+static DynPtrArray registered_bridges;
+
+// ColorData objects
static DynPtrArray color_merge_array;
static int ignored_objects;
//ColorData buckets
#define NUM_COLOR_ENTRIES ((BUCKET_SIZE - SIZEOF_VOID_P * 2) / sizeof (ColorData))
+// Same as ObjectBucket except NUM_COLOR_ENTRIES and NUM_SCAN_ENTRIES differ
typedef struct _ColorBucket ColorBucket;
struct _ColorBucket {
ColorBucket *next;
res->obj = obj;
res->color = NULL;
res->index = res->low_index = -1;
+ res->state = INITIAL;
+ res->is_bridge = FALSE;
res->obj_state = o [0] & SGEN_VTABLE_BITS_MASK;
res->lock_word = o [1];
return FALSE;
}
+// Called during DFS; visits one child. If it is a candidate to be scanned, pushes it to the stacks.
static void
push_object (GCObject *obj)
{
if (dst) push_object (dst); \
} while (0)
+// dfs () function's queue-children-of-object operation.
static void
push_all (ScanData *data)
{
mword desc = sgen_obj_get_descriptor_safe (obj);
#if DUMP_GRAPH
- printf ("**scanning %p %s\n", obj, safe_name_bridge (obj));
+ printf ("+scanning %s (%p) index %d color %p\n", safe_name_bridge (data->obj), data->obj, data->index, data->color);
#endif
#include "sgen/sgen-scan-object.h"
{
ScanData *other;
ColorData *cd;
- obj = bridge_object_forward (obj);
+ obj = bridge_object_forward (obj);
other = find_data (obj);
#if DUMP_GRAPH
#if DUMP_GRAPH
printf ("|SCC rooted in %s (%p) has bridge %d\n", safe_name_bridge (data->obj), data->obj, found_bridge);
printf ("\tpoints-to-colors: ");
- for (i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i)
+ for (int i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i)
printf ("%p ", dyn_array_ptr_get (&color_merge_array, i));
printf ("\n");
printf ("loop stack: ");
- for (i = 0; i < dyn_array_ptr_size (&loop_stack); ++i) {
+ for (int i = 0; i < dyn_array_ptr_size (&loop_stack); ++i) {
ScanData *other = dyn_array_ptr_get (&loop_stack, i);
printf ("(%d/%d)", other->index, other->low_index);
}
g_assert (cd->visited);
cd->visited = FALSE;
}
- dyn_array_ptr_set_size (&color_merge_array, 0);
+ dyn_array_ptr_empty (&color_merge_array);
found_bridge = FALSE;
}
g_assert (dyn_array_ptr_size (&scan_stack) == 1);
g_assert (dyn_array_ptr_size (&loop_stack) == 0);
- dyn_array_ptr_set_size (&color_merge_array, 0);
+ dyn_array_ptr_empty (&color_merge_array);
while (dyn_array_ptr_size (&scan_stack) > 0) {
ScanData *data = (ScanData *)dyn_array_ptr_pop (&scan_stack);
static void
reset_data (void)
{
- dyn_array_ptr_set_size (®istered_bridges, 0);
+ dyn_array_ptr_empty (®istered_bridges);
}
static void
cleanup (void)
{
- dyn_array_ptr_set_size (&scan_stack, 0);
- dyn_array_ptr_set_size (&loop_stack, 0);
- dyn_array_ptr_set_size (®istered_bridges, 0);
+ dyn_array_ptr_empty (&scan_stack);
+ dyn_array_ptr_empty (&loop_stack);
+ dyn_array_ptr_empty (®istered_bridges);
free_object_buckets ();
free_color_buckets ();
reset_cache ();
#if defined (DUMP_GRAPH)
printf ("----summary----\n");
printf ("bridges:\n");
- for (i = 0; i < bridge_count; ++i) {
+ for (int i = 0; i < bridge_count; ++i) {
ScanData *sd = find_data (dyn_array_ptr_get (®istered_bridges, i));
printf ("\t%s (%p) index %d color %p\n", safe_name_bridge (sd->obj), sd->obj, sd->index, sd->color);
}
if (!bridges)
continue;
- dyn_array_ptr_set_size (&color_merge_array, 0);
+ dyn_array_ptr_empty (&color_merge_array);
gather_xrefs (cd);
reset_xrefs (cd);
dyn_array_ptr_set_all (&cd->other_colors, &color_merge_array);
#if defined (DUMP_GRAPH)
printf ("---xrefs:\n");
- for (i = 0; i < xref_count; ++i)
+ for (int i = 0; i < xref_count; ++i)
printf ("\t%d -> %d\n", api_xrefs [i].src_scc_index, api_xrefs [i].dst_scc_index);
#endif
#include <mono/utils/mono-threads.h>
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/networking.h>
+#include <mono/utils/w32handle.h>
#include <time.h>
#ifdef HAVE_SYS_TIME_H
mono_gc_set_skip_thread (TRUE);
+ MONO_ENTER_GC_SAFE;
ready = epoll_wait (epoll_fd, epoll_events, EPOLL_NEVENTS, -1);
+ MONO_EXIT_GC_SAFE;
mono_gc_set_skip_thread (FALSE);
mono_gc_set_skip_thread (TRUE);
+ MONO_ENTER_GC_SAFE;
ready = kevent (kqueue_fd, NULL, 0, kqueue_events, KQUEUE_NEVENTS, NULL);
+ MONO_EXIT_GC_SAFE;
mono_gc_set_skip_thread (FALSE);
mono_gc_set_skip_thread (TRUE);
+ MONO_ENTER_GC_SAFE;
ready = mono_poll (poll_fds, poll_fds_size, -1);
+ MONO_EXIT_GC_SAFE;
mono_gc_set_skip_thread (FALSE);
{
ThreadPoolIOUpdate *update;
- g_assert (handle >= 0);
+ g_assert (handle);
g_assert ((job->operation == EVENT_IN) ^ (job->operation == EVENT_OUT));
g_assert (job->callback);
break;
}
}
- g_assert (current_idx >= 0);
+ g_assert (current_idx != (guint)-1);
}
for (i = current_idx + 1; i < len + current_idx + 1; ++i) {
ThreadPoolDomain *tmp = (ThreadPoolDomain *)g_ptr_array_index (threadpool->domains, i % len);
if (retire)
retire = FALSE;
+ /* The tpdomain->domain might have unloaded, while this thread was parked */
+ previous_tpdomain = NULL;
+
continue;
}
args [0] = start_arg;
/* we may want to handle the exception here. See comment below on unhandled exceptions */
mono_runtime_delegate_invoke_checked (start_delegate, args, &error);
- mono_error_raise_exception (&error); /* OK, triggers unhandled exn handler */
+
+ if (!mono_error_ok (&error)) {
+ MonoException *ex = mono_error_convert_to_exception (&error);
+ if (ex)
+ mono_unhandled_exception (&ex->object);
+ } else {
+ mono_error_cleanup (&error);
+ }
}
/* If the thread calls ExitThread at all, this remaining code
wait->num++;
THREAD_DEBUG (g_print ("%s: Aborting id: %"G_GSIZE_FORMAT"\n", __func__, (gsize)thread->tid));
- mono_thread_internal_stop (thread);
+ mono_thread_internal_abort (thread);
return TRUE;
}
return NULL;
LOCK_THREAD (thread);
- still_aborting = (thread->state & ThreadState_AbortRequested) != 0;
+ still_aborting = (thread->state & (ThreadState_AbortRequested|ThreadState_StopRequested)) != 0;
UNLOCK_THREAD (thread);
/*This can happen if the protected block called Thread::ResetAbort*/
CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("This object not compatible with function pointer for delegate creation at 0x%04x", ctx->ip_offset));
} else {
if (method->flags & METHOD_ATTRIBUTE_STATIC) {
- if (!stack_slot_is_null_literal (value) && !is_first_arg_bound)
+ if (!stack_slot_is_null_literal (value))
CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Non-null this args used with static function for delegate creation at 0x%04x", ctx->ip_offset));
} else {
if (!verify_stack_type_compatibility_full (ctx, &method->klass->byval_arg, value, FALSE, TRUE) && !stack_slot_is_null_literal (value))
gc-test.cs \
gshared.cs
-regtests=basic.exe basic-float.exe basic-long.exe basic-calls.exe objects.exe arrays.exe basic-math.exe exceptions.exe iltests.exe devirtualization.exe generics.exe basic-simd.exe
+
+regtests_UNIVERSAL=basic.exe basic-float.exe basic-long.exe basic-calls.exe objects.exe arrays.exe basic-math.exe exceptions.exe iltests.exe devirtualization.exe generics.exe basic-simd.exe
+
+if INSTALL_MOBILE_STATIC
+regtests= \
+ $(regtests_UNIVERSAL)
+
if NACL_CODEGEN
test_sources += nacl.cs
regtests += nacl.exe
endif
+else
+regtests= \
+ $(regtests_UNIVERSAL) \
+ $(regtests_MOBILE_STATIC_BLACKLIST)
+endif
+
if X86
arch_sources = $(x86_sources)
arch_built=cpu-x86.h
libmonoboehm_2_0_la_SOURCES =
libmonoboehm_2_0_la_CFLAGS = $(mono_boehm_CFLAGS)
libmonoboehm_2_0_la_LIBADD = libmini.la $(boehm_libs) $(LIBMONO_DTRACE_OBJECT) $(LLVMMONOF)
-libmonoboehm_2_0_la_LDFLAGS = $(libmonoldflags)
+libmonoboehm_2_0_la_LDFLAGS = $(libmonoldflags) $(monobin_platform_ldflags)
libmonosgen_2_0_la_SOURCES =
libmonosgen_2_0_la_CFLAGS = $(mono_sgen_CFLAGS)
libmonosgen_2_0_la_LIBADD = libmini.la $(sgen_libs) $(LIBMONO_DTRACE_OBJECT) $(LLVMMONOF)
-libmonosgen_2_0_la_LDFLAGS = $(libmonoldflags)
+libmonosgen_2_0_la_LDFLAGS = $(libmonoldflags) $(monobin_platform_ldflags)
#
# This library is shared between mono and mono-sgen, since the code in mini/ doesn't contain
%.exe: %.il
$(ILASM) -output=$@ $<
-TestDriver.dll: $(srcdir)/TestDriver.cs
- $(MCS) -out:$@ -target:library $<
+TestDriver.dll: $(srcdir)/TestDriver.cs $(srcdir)/TestHelpers.cs
+ $(MCS) -out:$@ -target:library $^
generics-variant-types.dll: generics-variant-types.il
$(ILASM) -dll -output=$@ $<
checktests: $(regtests)
for i in $(regtests); do $(MINI_RUNTIME) $$i; done
-rcheck: mono $(regtests)
-if NACL_CODEGEN
- for i in $(regtests); do echo "running test $$i"; $(MINI_RUNTIME) $$i --exclude 'NaClDisable' || exit 1; done
-else
+rcheck-nunit: mono $(regtests)
-($(MINI_RUNTIME) --regression $(regtests); echo $$? > regressionexitcode.out) | $(srcdir)/emitnunit.pl
exit $$(cat regressionexitcode.out)
-endif
-rcheck2: mono $(regtests)
+rcheck: mono $(regtests)
$(MINI_RUNTIME) --regression $(regtests)
if ARM
fullaot_regtests = $(regtests) aot-tests.exe $(if $(GSHAREDVT),gshared.exe)
-FULLAOT_LIBS = \
+# Skip aoting the tests that aren't compiled
+# on the mobile_static profile because they're skipped
+# on mobile profiles
+FULLAOT_LIBS_MOBILE_STATIC_BLACKLIST = \
+ Mono.Posix.dll \
+ System.Configuration.dll \
+ Mono.Simd.dll
+
+FULLAOT_LIBS_UNIVERSAL = \
mscorlib.dll \
System.Core.dll \
System.dll \
- Mono.Posix.dll \
- System.Configuration.dll \
- System.Security.dll \
System.Xml.dll \
- Mono.Security.dll \
- Mono.Simd.dll
+ System.Security.dll \
+ Mono.Security.dll
+
+if INSTALL_MOBILE_STATIC
+FULLAOT_LIBS= \
+ Mono.Dynamic.Interpreter.dll \
+ $(FULLAOT_LIBS_UNIVERSAL)
+else
+FULLAOT_LIBS= \
+ $(FULLAOT_LIBS_UNIVERSAL) \
+ $(FULLAOT_LIBS_MOBILE_STATIC_BLACKLIST)
+endif
+
+FULLAOT_TMP_DIR=$(top_builddir)/mono/mini/fullaot-tmp
# This currently only works on amd64/arm
fullaotcheck: $(mono) $(fullaot_regtests)
- rm -rf fullaot-tmp
- mkdir fullaot-tmp
+ rm -rf $(FULLAOT_TMP_DIR)
+ mkdir $(FULLAOT_TMP_DIR)
$(MAKE) fullaot-libs AOT_FLAGS="full,$(MONO_FULLAOT_ADDITIONAL_ARGS)" GSHAREDVT=$(GSHAREDVT)
- cp $(regtests) $(fullaot_regtests) generics-variant-types.dll TestDriver.dll fullaot-tmp/
- MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot="full,$(MONO_FULLAOT_ADDITIONAL_ARGS)" fullaot-tmp/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
- ln -s $(if $(MONO_EXECUTABLE),$(MONO_EXECUTABLE),$$PWD/mono) fullaot-tmp/
- for i in $(fullaot_regtests); do echo $$i; MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper --full-aot fullaot-tmp/$$i --exclude '!FULLAOT' $(ARCH_FULLAOT_EXCLUDE) || exit 1; done
+ cp $(regtests) $(fullaot_regtests) generics-variant-types.dll TestDriver.dll $(FULLAOT_TMP_DIR)/
+ MONO_PATH=$(FULLAOT_TMP_DIR) $(top_builddir)/runtime/mono-wrapper $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot="full,$(MONO_FULLAOT_ADDITIONAL_ARGS)" $(FULLAOT_TMP_DIR)/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
+ ln -s $(if $(MONO_EXECUTABLE),$(MONO_EXECUTABLE),$$PWD/mono) $(FULLAOT_TMP_DIR)/
+ for i in $(fullaot_regtests); do echo $$i; MONO_PATH=$(FULLAOT_TMP_DIR) $(top_builddir)/runtime/mono-wrapper --full-aot $(FULLAOT_TMP_DIR)/$$i --exclude '!FULLAOT' $(ARCH_FULLAOT_EXCLUDE) || exit 1; done
# This can run in parallel
fullaot-libs: $(patsubst %,fullaot-tmp/%.dylib,$(FULLAOT_LIBS))
docu: mini.sgm
docbook2txt mini.sgm
-check-local: rcheck check-seq-points
+# We need these because automake can't process normal make conditionals
+check_local_targets = $(if $(EMIT_NUNIT), rcheck-nunit, rcheck)
+
+check-local: $(check_local_targets)
clean-local:
rm -f mono a.out gmon.out *.o buildver-boehm.h buildver-sgen.h test.exe regressionexitcode.out TestResult-op_il_seq_point.xml*
CLEANFILES= $(BUILT_SOURCES) *.exe *.dll
EXTRA_DIST = TestDriver.cs \
+ TestHelpers.cs \
genmdesc.pl \
emitnunit.pl \
$(test_sources) \
--- /dev/null
+using System;
+using System.Threading;
+
+namespace MonoTests.Helpers {
+
+ public static class FinalizerHelpers {
+ private static IntPtr aptr;
+
+ private static unsafe void NoPinActionHelper (int depth, Action act)
+ {
+ // Avoid tail calls
+ int* values = stackalloc int [20];
+ aptr = new IntPtr (values);
+
+ if (depth <= 0)
+ act ();
+ else
+ NoPinActionHelper (depth - 1, act);
+ }
+
+ public static void PerformNoPinAction (Action act)
+ {
+ Thread thr = new Thread (() => NoPinActionHelper (1024, act));
+ thr.Start ();
+ thr.Join ();
+ }
+ }
+}
+
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-rand.h>
#include <mono/utils/json.h>
#include <mono/utils/mono-threads-coop.h>
gboolean soft_debug;
gboolean log_generics;
gboolean log_instances;
- gboolean gen_seq_points_file;
- char *gen_seq_points_file_path;
+ gboolean gen_msym_dir;
+ char *gen_msym_dir_path;
gboolean direct_pinvoke;
gboolean direct_icalls;
gboolean no_direct_calls;
if (acfg->aot_opts.mtriple && strstr (acfg->aot_opts.mtriple, "darwin")) {
g_string_append (acfg->llc_args, "-mattr=+v6");
} else {
-#ifdef ARM_FPU_VFP
+#if defined(ARM_FPU_VFP_HARD)
+ g_string_append (acfg->llc_args, " -mattr=+vfp2,-neon,+d16 -float-abi=hard");
+ g_string_append (acfg->as_args, " -mfpu=vfp3");
+#elif defined(ARM_FPU_VFP)
g_string_append (acfg->llc_args, " -mattr=+vfp2,-neon,+d16");
g_string_append (acfg->as_args, " -mfpu=vfp3");
#else
mb = mono_mb_new (mono_defaults.object_class, "FOO", MONO_WRAPPER_NONE);
m = mono_mb_create_method (mb, sig, 16);
- return mono_marshal_get_runtime_invoke (m, FALSE);
+ MonoMethod *invoke = mono_marshal_get_runtime_invoke (m, FALSE);
+ mono_mb_free (mb);
+ return invoke;
}
static MonoMethod*
if (export_name)
g_hash_table_insert (acfg->export_names, wrapper, export_name);
}
+ g_free (cattr);
}
if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
for (j = 0; j < header->num_locals; ++j)
if (header->locals [j]->type == MONO_TYPE_GENERICINST)
add_generic_class_with_depth (acfg, mono_class_from_mono_type (header->locals [j]), depth + 1, "local");
+ mono_metadata_free_mh (header);
} else {
mono_error_cleanup (&error); /* FIXME report the error */
}
+
}
/*
}
}
+ g_ptr_array_free (patches, TRUE);
g_free (locs);
}
encode_patch_list (acfg, patches, n_patches, cfg->compile_llvm, first_got_offset, p, &p);
+ g_ptr_array_free (patches, TRUE);
+
acfg->stats.info_size += p - buf;
g_assert (p - buf < buf_size);
unwind_desc = get_unwind_info_offset (acfg, encoded, encoded_len);
encode_value (unwind_desc, p, &p);
+
+ g_free (encoded);
} else {
encode_value (jinfo->unwind_info, p, &p);
}
encode_patch_list (acfg, patches, patches->len, FALSE, got_offset, p, &p);
g_assert (p - buf < buf_size);
+ g_ptr_array_free (patches, TRUE);
sprintf (symbol, "%s%s_p", acfg->user_symbol_prefix, name);
if (acfg->dwarf)
mono_dwarf_writer_emit_trampoline (acfg->dwarf, symbol, symbol2, NULL, NULL, code_size, unwind_ops);
}
+
+ g_free (buf);
}
static G_GNUC_UNUSED void
offset = MONO_RGCTX_SLOT_MAKE_RGCTX (i);
mono_arch_create_rgctx_lazy_fetch_trampoline (offset, &info, TRUE);
emit_trampoline (acfg, acfg->got_offset, info);
+ g_free (info);
offset = MONO_RGCTX_SLOT_MAKE_MRGCTX (i);
mono_arch_create_rgctx_lazy_fetch_trampoline (offset, &info, TRUE);
emit_trampoline (acfg, acfg->got_offset, info);
+ g_free (info);
}
#ifdef MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE
}
}
+#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD_AOT
+ mono_arch_create_handler_block_trampoline (&info, TRUE);
+ emit_trampoline (acfg, acfg->got_offset, info);
+#endif
+
#endif /* #ifdef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES */
/* Emit trampolines which are numerous */
} else if (str_begins_with (arg, "soft-debug")) {
opts->soft_debug = TRUE;
} else if (str_begins_with (arg, "gen-seq-points-file=")) {
- debug_options.gen_seq_points_compact_data = TRUE;
- opts->gen_seq_points_file = TRUE;
- opts->gen_seq_points_file_path = g_strdup (arg + strlen ("gen-seq-points-file="));;
+ fprintf (stderr, "Mono Warning: aot option gen-seq-points-file= is deprecated.\n");
} else if (str_begins_with (arg, "gen-seq-points-file")) {
- debug_options.gen_seq_points_compact_data = TRUE;
- opts->gen_seq_points_file = TRUE;
+ fprintf (stderr, "Mono Warning: aot option gen-seq-points-file is deprecated.\n");
+ } else if (str_begins_with (arg, "msym-dir=")) {
+ debug_options.no_seq_points_compact_data = FALSE;
+ opts->gen_msym_dir = TRUE;
+ opts->gen_msym_dir_path = g_strdup (arg + strlen ("msym_dir="));;
} else if (str_begins_with (arg, "direct-pinvoke")) {
opts->direct_pinvoke = TRUE;
} else if (str_begins_with (arg, "direct-icalls")) {
printf (" tool-prefix=\n");
printf (" readonly-value=\n");
printf (" soft-debug\n");
- printf (" gen-seq-points-file\n");
+ printf (" msym-dir=\n");
printf (" gc-maps\n");
printf (" print-skipped\n");
printf (" no-instances\n");
if (acfg->aot_opts.print_skipped_methods)
printf ("Skip (disabled): %s\n", mono_method_get_full_name (method));
InterlockedIncrement (&acfg->stats.ocount);
- mono_destroy_compile (cfg);
return;
}
cfg->method_index = index;
if (acfg->aot_opts.print_skipped_methods)
printf ("Skip (abs call): %s\n", mono_method_get_full_name (method));
InterlockedIncrement (&acfg->stats.abscount);
- mono_destroy_compile (cfg);
return;
}
if (acfg->aot_opts.print_skipped_methods)
printf ("Skip (patches): %s\n", mono_method_get_full_name (method));
acfg->stats.ocount++;
- mono_destroy_compile (cfg);
mono_acfg_unlock (acfg);
return;
}
locals [i] = (MonoInst *)mono_mempool_alloc (acfg->mempool, sizeof (MonoInst));
memcpy (locals [i], cfg->locals [i], sizeof (MonoInst));
}
+ mono_metadata_free_mh (header);
cfg->locals = locals;
}
/* Free some fields used by cfg to conserve memory */
- mono_mempool_destroy (cfg->mempool);
- cfg->mempool = NULL;
- g_free (cfg->varinfo);
- cfg->varinfo = NULL;
- g_free (cfg->vars);
- cfg->vars = NULL;
- if (cfg->rs) {
- mono_regstate_free (cfg->rs);
- cfg->rs = NULL;
- }
+ mono_empty_compile (cfg);
//printf ("Compile: %s\n", mono_method_full_name (method, TRUE));
opts = g_strdup ("");
else
#if LLVM_API_VERSION > 100
- opts = g_strdup ("-O2");
+ opts = g_strdup ("-O2 -disable-tail-calls");
#else
opts = g_strdup ("-targetlibinfo -no-aa -basicaa -notti -instcombine -simplifycfg -inline-cost -inline -sroa -domtree -early-cse -lazy-value-info -correlated-propagation -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -indvars -loop-idiom -loop-deletion -loop-unroll -memdep -gvn -memdep -memcpyopt -sccp -instcombine -lazy-value-info -correlated-propagation -domtree -memdep -adce -simplifycfg -instcombine -strip-dead-prototypes -domtree -verify");
#endif
if (acfg->aot_opts.llvm_only) {
/* Use the stock clang from xcode */
// FIXME: arch
- command = g_strdup_printf ("clang -march=x86-64 -fpic -msse -msse2 -msse3 -msse4 -O2 -fno-optimize-sibling-calls -Wno-override-module -c -o \"%s\" \"%s.opt.bc\"", acfg->llvm_ofile, acfg->tmpbasename);
+ command = g_strdup_printf ("clang++ -fexceptions -march=x86-64 -fpic -msse -msse2 -msse3 -msse4 -O2 -fno-optimize-sibling-calls -Wno-override-module -c -o \"%s\" \"%s.opt.bc\"", acfg->llvm_ofile, acfg->tmpbasename);
aot_printf (acfg, "Executing clang: %s\n", command);
if (execute_system (command) != 0)
g_ptr_array_add (table, new_entry);
}
}
+ g_free (chain_lengths);
//printf ("MAX: %d\n", max_chain_length);
/* Emit the table */
emit_aot_data (acfg, MONO_AOT_TABLE_EXTRA_METHOD_TABLE, "extra_method_table", buf, p - buf);
+ g_free (buf);
+
/*
* Emit a table reverse mapping method indexes to their index in extra_method_info.
* This is used by mono_aot_find_jit_info ().
encode_int (info_offsets [i], p, &p);
}
emit_aot_data (acfg, MONO_AOT_TABLE_EXTRA_METHOD_INFO_OFFSETS, "extra_method_info_offsets", buf, p - buf);
+
+ g_free (buf);
+ g_free (info_offsets);
+ g_ptr_array_free (table, TRUE);
}
+static void
+generate_aotid (guint8* aotid)
+{
+ gpointer *rand_handle;
+ MonoError error;
+
+ mono_rand_open ();
+ rand_handle = mono_rand_init (NULL, 0);
+
+ mono_rand_try_get_bytes (rand_handle, aotid, 16, &error);
+ mono_error_assert_ok (&error);
+
+ mono_rand_close (rand_handle);
+}
+
static void
emit_exception_info (MonoAotCompile *acfg)
{
// By design aot-runtime decode_exception_debug_info is not able to load sequence point debug data from a file.
// As it is not possible to load debug data from a file its is also not possible to store it in a file.
- gboolean method_seq_points_to_file = acfg->aot_opts.gen_seq_points_file &&
+ gboolean method_seq_points_to_file = acfg->aot_opts.gen_msym_dir &&
cfg->gen_seq_points && !cfg->gen_sdb_seq_points;
gboolean method_seq_points_to_binary = cfg->gen_seq_points && !method_seq_points_to_file;
}
if (seq_points_to_file) {
- char *seq_points_aot_file = acfg->aot_opts.gen_seq_points_file_path ? acfg->aot_opts.gen_seq_points_file_path
- : g_strdup_printf("%s%s", acfg->image->name, SEQ_POINT_AOT_EXT);
- mono_seq_point_data_write (&sp_data, seq_points_aot_file);
+ char *aotid = mono_guid_to_string_minimal (acfg->image->aotid);
+ char *dir = g_build_filename (acfg->aot_opts.gen_msym_dir_path, aotid, NULL);
+ char *image_basename = g_path_get_basename (acfg->image->name);
+ char *aot_file = g_strdup_printf("%s%s", image_basename, SEQ_POINT_AOT_EXT);
+ char *aot_file_path = g_build_filename (dir, aot_file, NULL);
+
+ if (g_ensure_directory_exists (aot_file_path) == FALSE) {
+ fprintf (stderr, "AOT : failed to create msym directory: %s\n", aot_file_path);
+ exit (1);
+ }
+
+ mono_seq_point_data_write (&sp_data, aot_file_path);
mono_seq_point_data_free (&sp_data);
- g_free (seq_points_aot_file);
+
+ g_free (aotid);
+ g_free (dir);
+ g_free (image_basename);
+ g_free (aot_file);
+ g_free (aot_file_path);
}
acfg->stats.offsets_size += emit_offset_table (acfg, "ex_info_offsets", MONO_AOT_TABLE_EX_INFO_OFFSETS, acfg->nmethods, 10, offsets);
else
encode_int16 (0, p, &p);
}
+ g_free (entry);
}
g_assert (p - buf <= buf_size);
+ g_ptr_array_free (table, TRUE);
emit_aot_data (acfg, MONO_AOT_TABLE_CLASS_NAME, "class_name_table", buf, p - buf);
+
+ g_free (buf);
}
static void
info->nshared_got_entries = acfg->nshared_got_entries;
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
info->tramp_page_code_offsets [i] = acfg->tramp_page_code_offsets [i];
+
+ memcpy(&info->aotid, acfg->image->aotid, 16);
}
static void
for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
emit_int32 (acfg, info->tramp_page_code_offsets [i]);
+ emit_bytes (acfg, info->aotid, 16);
+
if (acfg->aot_opts.static_link) {
emit_global_inner (acfg, acfg->static_linking_symbol, FALSE);
emit_alignment (acfg, sizeof (gpointer));
wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
#else
// Default (linux)
- command = g_strdup_printf ("\"%sld\" %s -shared -o %s %s %s %s", tool_prefix, LD_OPTIONS,
+ char *args = g_strdup_printf ("%s %s -shared -o %s %s %s %s", tool_prefix, LD_OPTIONS,
wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
+
+ if (acfg->llvm) {
+ command = g_strdup_printf ("clang++ %s", args);
+ } else {
+ command = g_strdup_printf ("\"%sld\" %s", tool_prefix, args);
+ }
+ g_free (args);
+
#endif
aot_printf (acfg, "Executing the native linker: %s\n", command);
if (execute_system (command) != 0) {
* gas generates 'mapping symbols' each time code and data is mixed, which
* happens a lot in emit_and_reloc_code (), so we need to get rid of them.
*/
- command = g_strdup_printf ("\"%sstrip\" --strip-symbol=\\$a --strip-symbol=\\$d %s", tool_prefix, tmp_outfile_name);
+ command = g_strdup_printf ("\"%sstrip\" --strip-symbol=\\$a --strip-symbol=\\$d %s", wrap_path(tool_prefix), wrap_path(tmp_outfile_name));
aot_printf (acfg, "Stripping the binary: %s\n", command);
if (execute_system (command) != 0) {
g_free (tmp_outfile_name);
mono_img_writer_destroy (acfg->w);
for (i = 0; i < acfg->nmethods; ++i)
if (acfg->cfgs [i])
- g_free (acfg->cfgs [i]);
+ mono_destroy_compile (acfg->cfgs [i]);
+
g_free (acfg->cfgs);
+
g_free (acfg->static_linking_symbol);
g_free (acfg->got_symbol);
g_free (acfg->plt_symbol);
aot_printf (acfg, "Mono Ahead of Time compiler - compiling assembly %s\n", image->name);
+ generate_aotid ((guint8*) &acfg->image->aotid);
+
+ char *aotid = mono_guid_to_string (acfg->image->aotid);
+ aot_printf (acfg, "AOTID %s\n", aotid);
+ g_free (aotid);
+
#ifndef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES
if (mono_aot_mode_is_full (&acfg->aot_opts)) {
aot_printerrf (acfg, "--aot=full is not supported on this platform.\n");
msg = g_strdup_printf ("not compiled with --aot=llvmonly");
usable = FALSE;
}
-#ifdef TARGET_ARM
- /* mono_arch_find_imt_method () requires this */
- if ((info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) {
- msg = g_strdup_printf ("compiled against LLVM");
- usable = FALSE;
- }
- if (!(info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && mono_use_llvm) {
- msg = g_strdup_printf ("not compiled against LLVM");
- usable = FALSE;
- }
-#endif
if (mini_get_debug_options ()->mdb_optimizations && !(info->flags & MONO_AOT_FILE_FLAG_DEBUG) && !full_aot) {
msg = g_strdup_printf ("not compiled for debugging");
usable = FALSE;
find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&info);
}
+ // Copy aotid to MonoImage
+ memcpy(&assembly->image->aotid, info->aotid, 16);
+
if (version_symbol) {
/* Old file format */
version = atoi (version_symbol);
gpointer
mono_aot_get_method_checked (MonoDomain *domain,
- MonoMethod *method, MonoError *error);
+ MonoMethod *method, MonoError *error)
{
mono_error_init (error);
return NULL;
gc_param_slot_liveness_def: len:0
generic_class_init: src1:A len:32 clob:c
+get_last_error: dest:i len:32
static void
resume_vm (void)
{
- int err;
-
g_assert (is_debugger_thread ());
mono_loader_lock ();
}
/* Signal this even when suspend_count > 0, since some threads might have resume_count > 0 */
- err = mono_coop_cond_broadcast (&suspend_cond);
- g_assert (err == 0);
+ mono_coop_cond_broadcast (&suspend_cond);
mono_coop_mutex_unlock (&suspend_mutex);
//g_assert (err == 0);
static void
resume_thread (MonoInternalThread *thread)
{
- int err;
DebuggerTlsData *tls;
g_assert (is_debugger_thread ());
* Signal suspend_count without decreasing suspend_count, the threads will wake up
* but only the one whose resume_count field is > 0 will be resumed.
*/
- err = mono_coop_cond_broadcast (&suspend_cond);
- g_assert (err == 0);
+ mono_coop_cond_broadcast (&suspend_cond);
mono_coop_mutex_unlock (&suspend_mutex);
//g_assert (err == 0);
suspend_current (void)
{
DebuggerTlsData *tls;
- int err;
g_assert (!is_debugger_thread ());
DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer) (gsize) mono_native_thread_id_get ());
while (suspend_count - tls->resume_count > 0) {
- err = mono_coop_cond_wait (&suspend_cond, &suspend_mutex);
- g_assert (err == 0);
+ mono_coop_cond_wait (&suspend_cond, &suspend_mutex);
}
tls->suspended = FALSE;
case CMD_TYPE_GET_METHODS_BY_NAME_FLAGS: {
char *name = decode_string (p, &p, end);
int i, flags = decode_int (p, &p, end);
- MonoException *ex = NULL;
- GPtrArray *array = mono_class_get_methods_by_name (klass, name, flags & ~BINDING_FLAGS_IGNORE_CASE, (flags & BINDING_FLAGS_IGNORE_CASE) != 0, TRUE, &ex);
+ MonoError error;
+ GPtrArray *array;
- if (!array)
+ mono_error_init (&error);
+ array = mono_class_get_methods_by_name (klass, name, flags & ~BINDING_FLAGS_IGNORE_CASE, (flags & BINDING_FLAGS_IGNORE_CASE) != 0, TRUE, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error);
return ERR_LOADER_ERROR;
+ }
buffer_add_int (buf, array->len);
for (i = 0; i < array->len; ++i) {
MonoMethod *method = (MonoMethod *)g_ptr_array_index (array, i);
}
[Category ("!FULLAOT")]
+ [Category ("!BITCODE")]
public static int test_0_regress_668095_synchronized_gshared () {
return DoSomething (new DefaultRetriever ());
}
need_unbox_tramp = TRUE;
}
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
// FIXME: This can throw exceptions
addr = compiled_method = mono_compile_method_checked (m, error);
mono_error_assert_ok (error);
if (vt->klass->valuetype)
need_unbox_tramp = TRUE;
- // FIXME: This can throw exceptions
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
addr = compiled_method = mono_compile_method_checked (m, &error);
- mono_error_assert_ok (&error);
+ mono_error_raise_exception (&error);
g_assert (addr);
addr = mini_add_method_wrappers_llvmonly (m, addr, FALSE, need_unbox_tramp, &arg);
* but we don't have a a structure which could own its memory.
*/
if (G_UNLIKELY (!ftndesc)) {
- gpointer addr = mono_compile_method_checked (del->method, &error);
+ MonoMethod *m = del->method;
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
+ gpointer addr = mono_compile_method_checked (m, &error);
if (mono_error_set_pending_exception (&error))
return;
- if (del->method->klass->valuetype && mono_method_signature (del->method)->hasthis)
- addr = mono_aot_get_unbox_trampoline (del->method);
+ if (m->klass->valuetype && mono_method_signature (m)->hasthis)
+ addr = mono_aot_get_unbox_trampoline (m);
gpointer arg = mini_get_delegate_arg (del->method, addr);
method = mono_object_get_virtual_method (target, method);
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ method = mono_marshal_get_synchronized_wrapper (method);
+
del->method = method;
del->method_ptr = mono_compile_method_checked (method, &error);
if (mono_error_set_pending_exception (&error))
gboolean cost_driven;
if (!cfg->disable_reuse_registers && vars && (((MonoMethodVar*)vars->data)->interval != NULL)) {
- mono_linear_scan2 (cfg, vars, regs, used_mask);
- return;
- }
+ mono_linear_scan2 (cfg, vars, regs, used_mask);
+ g_list_free (regs);
+ g_list_free (vars);
+ return;
+ }
cost_driven = TRUE;
g_assert_not_reached ();
}
+gpointer
+mono_llvm_compile_method (MonoEERef mono_ee, LLVMValueRef method, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
void
mono_llvm_dispose_ee (MonoEERef *eeref)
{
GHashTable *prev_cbb_hash;
MonoBasicBlock **prev_cil_offset_to_bb;
MonoBasicBlock *prev_cbb;
- unsigned char* prev_cil_start;
+ const unsigned char *prev_ip;
+ unsigned char *prev_cil_start;
guint32 prev_cil_offset_to_bb_len;
MonoMethod *prev_current_method;
MonoGenericContext *prev_generic_context;
prev_cil_offset_to_bb = cfg->cil_offset_to_bb;
prev_cil_offset_to_bb_len = cfg->cil_offset_to_bb_len;
prev_cil_start = cfg->cil_start;
+ prev_ip = cfg->ip;
prev_cbb = cfg->cbb;
prev_current_method = cfg->current_method;
prev_generic_context = cfg->generic_context;
cfg->cil_offset_to_bb = prev_cil_offset_to_bb;
cfg->cil_offset_to_bb_len = prev_cil_offset_to_bb_len;
cfg->cil_start = prev_cil_start;
+ cfg->ip = prev_ip;
cfg->locals = prev_locals;
cfg->args = prev_args;
cfg->arg_types = prev_arg_types;
if (!header) {
mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
goto exception_exit;
+ } else {
+ cfg->headers_to_free = g_slist_prepend_mempool (cfg->mempool, cfg->headers_to_free, header);
}
+
generic_container = mono_method_get_generic_container (method);
sig = mono_method_signature (method);
num_args = sig->hasthis + sig->param_count;
inline_costs += 10 * num_calls++;
+ /*
+ * Synchronized wrappers.
+ * Its hard to determine where to replace a method with its synchronized
+ * wrapper without causing an infinite recursion. The current solution is
+ * to add the synchronized wrapper in the trampolines, and to
+ * change the called method to a dummy wrapper, and resolve that wrapper
+ * to the real method in mono_jit_compile_method ().
+ */
+ if (cfg->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
+ MonoMethod *orig = mono_marshal_method_from_wrapper (cfg->method);
+ if (cmethod == orig || (cmethod->is_inflated && mono_method_get_declaring_generic_method (cmethod) == orig))
+ cmethod = mono_marshal_get_synchronized_inner_wrapper (cmethod);
+ }
+
/*
* Making generic calls out of gsharedvt methods.
* This needs to be used for all generic calls, not just ones with a gsharedvt signature, to avoid
}
}
- /*
- * Synchronized wrappers.
- * Its hard to determine where to replace a method with its synchronized
- * wrapper without causing an infinite recursion. The current solution is
- * to add the synchronized wrapper in the trampolines, and to
- * change the called method to a dummy wrapper, and resolve that wrapper
- * to the real method in mono_jit_compile_method ().
- */
- if (cfg->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
- MonoMethod *orig = mono_marshal_method_from_wrapper (cfg->method);
- if (cmethod == orig || (cmethod->is_inflated && mono_method_get_declaring_generic_method (cmethod) == orig))
- cmethod = mono_marshal_get_synchronized_inner_wrapper (cmethod);
- }
-
/*
* Virtual calls in llvm-only mode.
*/
MONO_EMIT_NULL_CHECK (cfg, sp [0]->dreg);
+ if (ins_flag & MONO_INST_VOLATILE) {
+ /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */
+ emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL);
+ }
+
if (mini_is_gsharedvt_klass (klass)) {
MonoInst *offset_ins;
}
case CEE_THROW:
CHECK_STACK (1);
+ if (sp [-1]->type != STACK_OBJ)
+ UNVERIFIED;
+
MONO_INST_NEW (cfg, ins, OP_THROW);
--sp;
ins->sreg1 = sp [0]->dreg;
case CEE_MONO_LDDOMAIN:
CHECK_STACK_OVF (1);
EMIT_NEW_PCONST (cfg, ins, cfg->compile_aot ? NULL : cfg->domain);
+ ip += 2;
+ *sp++ = ins;
+ break;
+ case CEE_MONO_GET_LAST_ERROR:
+ CHECK_OPSIZE (2);
+ CHECK_STACK_OVF (1);
+
+ MONO_INST_NEW (cfg, ins, OP_GET_LAST_ERROR);
+ ins->dreg = alloc_dreg (cfg, STACK_I4);
+ ins->type = STACK_I4;
+ MONO_ADD_INS (cfg->cbb, ins);
+
ip += 2;
*sp++ = ins;
break;
g_slist_free (class_inits);
mono_basic_block_free (original_bb);
cfg->dont_inline = g_list_remove (cfg->dont_inline, method);
- cfg->headers_to_free = g_slist_prepend_mempool (cfg->mempool, cfg->headers_to_free, header);
if (cfg->exception_type)
return -1;
else
case ArgOnStack: return "ArgOnStack";
case ArgValuetypeInReg: return "ArgValuetypeInReg";
case ArgValuetypeAddrInIReg: return "ArgValuetypeAddrInIReg";
+ case ArgValuetypeAddrOnStack: return "ArgValuetypeAddrOnStack";
case ArgGSharedVtInReg: return "ArgGSharedVtInReg";
case ArgGSharedVtOnStack: return "ArgGSharedVtOnStack";
case ArgNone: return "ArgNone";
src = g_malloc (nsrc * sizeof (int));
src [0] = map_freg (sreg);
break;
+ case ArgValuetypeAddrInIReg:
+ nsrc = 1;
+ src = g_malloc (nsrc * sizeof (int));
+ src [0] = map_reg (ainfo->pair_regs [0]);
+ break;
+ case ArgValuetypeAddrOnStack:
+ nsrc = 1;
+ src = g_malloc (nsrc * sizeof (int));
+ // is_source_argument adds 2 because we're skipping over the old BBP and the return address
+ // XXX this is a very fragile setup as changes in alignment for the caller reg array can cause the magic number be 3
+ src [0] = map_stack_slot (sslot + (is_source_argument ? 2 : 0));
+ break;
default:
NOT_IMPLEMENTED;
break;
*arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL;
*arg_slots = dst_info->nregs;
break;
+ case ArgValuetypeAddrInIReg:
+ case ArgValuetypeAddrOnStack:
+ *arg_marshal = GSHAREDVT_ARG_NONE;
+ *arg_slots = dst_info->nregs;
+ break;
default:
NOT_IMPLEMENTED; // Inappropriate value: if dst and src are gsharedvt at once, we shouldn't be here
break;
case ArgOnStack:
*arg_marshal = GSHAREDVT_ARG_BYVAL_TO_BYREF;
break;
+ case ArgValuetypeAddrInIReg:
+ case ArgValuetypeAddrOnStack:
+ *arg_marshal = GSHAREDVT_ARG_NONE;
+ break;
default:
NOT_IMPLEMENTED; // See above
break;
handle_marshal_when_src_gsharedvt (dst_info, &arg_marshal, &arg_slots);
handle_map_when_gsharedvt_on_stack (src_info, &nsrc, &src, TRUE);
break;
+ case ArgValuetypeAddrInIReg:
+ case ArgValuetypeAddrOnStack:
+ nsrc = get_arg_slots (src_info, &src, TRUE);
+ break;
default:
g_error ("Gsharedvt can't handle source arg type %d", (int)src_info->storage); // Inappropriate value: ArgValuetypeAddrInIReg is for returns only
}
handle_marshal_when_dst_gsharedvt (src_info, &arg_marshal);
handle_map_when_gsharedvt_on_stack (dst_info, &ndst, &dst, FALSE);
break;
+ case ArgValuetypeAddrInIReg:
+ case ArgValuetypeAddrOnStack:
+ ndst = get_arg_slots (dst_info, &dst, FALSE);
+ break;
default:
g_error ("Gsharedvt can't handle dest arg type %d", (int)dst_info->storage); // See above
}
info->stack_usage = ALIGN_TO (info->stack_usage, MONO_ARCH_FRAME_ALIGNMENT);
+ g_free (callee_cinfo);
+ g_free (caller_cinfo);
+
DEBUG_AMD64_GSHAREDVT_PRINT ("allocated an info at %p stack usage %d\n", info, info->stack_usage);
return info;
}
* Dietmar Maurer (dietmar@ximian.com)
* Patrik Torstensson
* Zoltan Varga (vargaz@gmail.com)
+ * Johan Lorensson (lateralusx.github@gmail.com)
*
* (C) 2003 Ximian, Inc.
* Copyright 2003-2011 Novell, Inc (http://www.novell.com)
}
static int
-count_fields_nested (MonoClass *klass)
+count_fields_nested (MonoClass *klass, gboolean pinvoke)
{
MonoMarshalType *info;
int i, count;
- info = mono_marshal_load_type_info (klass);
- g_assert(info);
count = 0;
- for (i = 0; i < info->num_fields; ++i) {
- if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type))
- count += count_fields_nested (mono_class_from_mono_type (info->fields [i].field->type));
- else
- count ++;
+ if (pinvoke) {
+ info = mono_marshal_load_type_info (klass);
+ g_assert(info);
+ for (i = 0; i < info->num_fields; ++i) {
+ if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type))
+ count += count_fields_nested (mono_class_from_mono_type (info->fields [i].field->type), pinvoke);
+ else
+ count ++;
+ }
+ } else {
+ gpointer iter;
+ MonoClassField *field;
+
+ iter = NULL;
+ while ((field = mono_class_get_fields (klass, &iter))) {
+ if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
+ continue;
+ if (MONO_TYPE_ISSTRUCT (field->type))
+ count += count_fields_nested (mono_class_from_mono_type (field->type), pinvoke);
+ else
+ count ++;
+ }
}
return count;
}
+typedef struct {
+ MonoType *type;
+ int size, offset;
+} StructFieldInfo;
+
+/*
+ * collect_field_info_nested:
+ *
+ * Collect field info from KLASS recursively into FIELDS.
+ */
static int
-collect_field_info_nested (MonoClass *klass, MonoMarshalField *fields, int index, int offset)
+collect_field_info_nested (MonoClass *klass, StructFieldInfo *fields, int index, int offset, gboolean pinvoke, gboolean unicode)
{
MonoMarshalType *info;
int i;
- info = mono_marshal_load_type_info (klass);
- g_assert(info);
- for (i = 0; i < info->num_fields; ++i) {
- if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type)) {
- index = collect_field_info_nested (mono_class_from_mono_type (info->fields [i].field->type), fields, index, info->fields [i].offset);
- } else {
- memcpy (&fields [index], &info->fields [i], sizeof (MonoMarshalField));
- fields [index].offset += offset;
- index ++;
+ if (pinvoke) {
+ info = mono_marshal_load_type_info (klass);
+ g_assert(info);
+ for (i = 0; i < info->num_fields; ++i) {
+ if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type)) {
+ index = collect_field_info_nested (mono_class_from_mono_type (info->fields [i].field->type), fields, index, info->fields [i].offset, pinvoke, unicode);
+ } else {
+ guint32 align;
+
+ fields [index].type = info->fields [i].field->type;
+ fields [index].size = mono_marshal_type_size (info->fields [i].field->type,
+ info->fields [i].mspec,
+ &align, TRUE, unicode);
+ fields [index].offset = offset + info->fields [i].offset;
+ index ++;
+ }
+ }
+ } else {
+ gpointer iter;
+ MonoClassField *field;
+
+ iter = NULL;
+ while ((field = mono_class_get_fields (klass, &iter))) {
+ if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
+ continue;
+ if (MONO_TYPE_ISSTRUCT (field->type)) {
+ index = collect_field_info_nested (mono_class_from_mono_type (field->type), fields, index, field->offset - sizeof (MonoObject), pinvoke, unicode);
+ } else {
+ int align;
+
+ fields [index].type = field->type;
+ fields [index].size = mono_type_size (field->type, &align);
+ fields [index].offset = field->offset - sizeof (MonoObject) + offset;
+ index ++;
+ }
}
}
return index;
}
#ifdef TARGET_WIN32
-static void
-add_valuetype_win64 (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
- gboolean is_return,
- guint32 *gr, guint32 *fr, guint32 *stack_size)
-{
- guint32 size, i, nfields;
- guint32 argsize = 8;
- ArgumentClass arg_class;
- MonoMarshalType *info = NULL;
- MonoMarshalField *fields = NULL;
- MonoClass *klass;
- gboolean pass_on_stack = FALSE;
- klass = mono_class_from_mono_type (type);
- size = mini_type_stack_size_full (&klass->byval_arg, NULL, sig->pinvoke);
+/* Windows x64 ABI can pass/return value types in register of size 1,2,4,8 bytes. */
+#define MONO_WIN64_VALUE_TYPE_FITS_REG(arg_size) (arg_size <= SIZEOF_REGISTER && (arg_size == 1 || arg_size == 2 || arg_size == 4 || arg_size == 8))
- /*
- * Standard C and C++ doesn't allow empty structs, empty structs will always have a size of 1 byte.
- * GCC have an extension to allow empty structs, https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html.
- * This cause a little dilemma since runtime build using none GCC compiler will not be compatible with
- * GCC build C libraries and the other way around. On platforms where empty structs has size of 1 byte
- * it must be represented in call and cannot be dropped.
- */
- if (0 == size && MONO_TYPE_ISSTRUCT (type) && sig->pinvoke)
- ainfo->pass_empty_struct = TRUE;
-
- if (!sig->pinvoke)
- pass_on_stack = TRUE;
+static gboolean
+allocate_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, AMD64_Reg_No int_regs [], int int_reg_count, AMD64_Reg_No float_regs [], int float_reg_count, guint32 *current_int_reg, guint32 *current_float_reg)
+{
+ gboolean result = FALSE;
- /* If this struct can't be split up naturally into 8-byte */
- /* chunks (registers), pass it on the stack. */
- if (sig->pinvoke && !pass_on_stack) {
- guint32 align;
- guint32 field_size;
+ assert (arg_info != NULL && int_regs != NULL && float_regs != NULL && current_int_reg != NULL && current_float_reg != NULL);
+ assert (arg_info->storage == ArgValuetypeInReg || arg_info->storage == ArgValuetypeAddrInIReg);
- info = mono_marshal_load_type_info (klass);
- g_assert (info);
+ arg_info->pair_storage [0] = arg_info->pair_storage [1] = ArgNone;
+ arg_info->pair_regs [0] = arg_info->pair_regs [1] = ArgNone;
+ arg_info->pair_size [0] = 0;
+ arg_info->pair_size [1] = 0;
+ arg_info->nregs = 0;
- /*
- * Collect field information recursively to be able to
- * handle nested structures.
- */
- nfields = count_fields_nested (klass);
- fields = g_new0 (MonoMarshalField, nfields);
- collect_field_info_nested (klass, fields, 0, 0);
-
- for (i = 0; i < nfields; ++i) {
- field_size = mono_marshal_type_size (fields [i].field->type,
- fields [i].mspec,
- &align, TRUE, klass->unicode);
- if ((fields [i].offset < 8) && (fields [i].offset + field_size) > 8) {
- pass_on_stack = TRUE;
- break;
- }
- }
+ if (arg_class == ARG_CLASS_INTEGER && *current_int_reg < int_reg_count) {
+ /* Pass parameter in integer register. */
+ arg_info->pair_storage [0] = ArgInIReg;
+ arg_info->pair_regs [0] = int_regs [*current_int_reg];
+ (*current_int_reg) ++;
+ result = TRUE;
+ } else if (arg_class == ARG_CLASS_SSE && *current_float_reg < float_reg_count) {
+ /* Pass parameter in float register. */
+ arg_info->pair_storage [0] = (arg_size <= sizeof (gfloat)) ? ArgInFloatSSEReg : ArgInDoubleSSEReg;
+ arg_info->pair_regs [0] = float_regs [*current_float_reg];
+ (*current_float_reg) ++;
+ result = TRUE;
}
- if (pass_on_stack) {
- /* Allways pass in memory */
- ainfo->offset = *stack_size;
- *stack_size += ALIGN_TO (size, 8);
- ainfo->storage = is_return ? ArgValuetypeAddrInIReg : ArgOnStack;
- if (!is_return)
- ainfo->arg_size = ALIGN_TO (size, 8);
-
- g_free (fields);
- return;
+ if (result == TRUE) {
+ arg_info->pair_size [0] = arg_size;
+ arg_info->nregs = 1;
}
- if (!sig->pinvoke) {
- int n = mono_class_value_size (klass, NULL);
+ return result;
+}
- argsize = n;
+inline gboolean
+allocate_parameter_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, guint32 *current_int_reg, guint32 *current_float_reg)
+{
+ return allocate_register_for_valuetype_win64 (arg_info, arg_class, arg_size, param_regs, PARAM_REGS, float_param_regs, FLOAT_PARAM_REGS, current_int_reg, current_float_reg);
+}
- if (n > 8)
- arg_class = ARG_CLASS_MEMORY;
- else
- /* Always pass in 1 integer register */
- arg_class = ARG_CLASS_INTEGER;
- } else {
- g_assert (info);
+inline gboolean
+allocate_return_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, guint32 *current_int_reg, guint32 *current_float_reg)
+{
+ return allocate_register_for_valuetype_win64 (arg_info, arg_class, arg_size, return_regs, RETURN_REGS, float_return_regs, FLOAT_RETURN_REGS, current_int_reg, current_float_reg);
+}
- /*Only drop value type if its not an empty struct as input that must be represented in call*/
- if ((!fields && !ainfo->pass_empty_struct) || (!fields && ainfo->pass_empty_struct && is_return)) {
- ainfo->storage = ArgValuetypeInReg;
- ainfo->pair_storage [0] = ainfo->pair_storage [1] = ArgNone;
- return;
- }
+static void
+allocate_storage_for_valuetype_win64 (ArgInfo *arg_info, MonoType *type, gboolean is_return, ArgumentClass arg_class,
+ guint32 arg_size, guint32 *current_int_reg, guint32 *current_float_reg, guint32 *stack_size)
+{
+ /* Windows x64 value type ABI.
+ *
+ * Parameters: https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
+ *
+ * Integer/Float types smaller than or equals to 8 bytes or porperly sized struct/union (1,2,4,8)
+ * Try pass in register using ArgValuetypeInReg/(ArgInIReg|ArgInFloatSSEReg|ArgInDoubleSSEReg) as storage and size of parameter(1,2,4,8), if no more registers, pass on stack using ArgOnStack as storage and size of parameter(1,2,4,8).
+ * Integer/Float types bigger than 8 bytes or struct/unions larger than 8 bytes or (3,5,6,7).
+ * Try to pass pointer in register using ArgValuetypeAddrInIReg, if no more registers, pass pointer on stack using ArgValuetypeAddrOnStack as storage and parameter size of register (8 bytes).
+ *
+ * Return values: https://msdn.microsoft.com/en-us/library/7572ztz4.aspx.
+ *
+ * Integers/Float types smaller than or equal to 8 bytes
+ * Return in corresponding register RAX/XMM0 using ArgValuetypeInReg/(ArgInIReg|ArgInFloatSSEReg|ArgInDoubleSSEReg) as storage and size of parameter(1,2,4,8).
+ * Properly sized struct/unions (1,2,4,8)
+ * Return in register RAX using ArgValuetypeInReg as storage and size of parameter(1,2,4,8).
+ * Types bigger than 8 bytes or struct/unions larger than 8 bytes or (3,5,6,7).
+ * Return pointer to allocated stack space (allocated by caller) using ArgValuetypeAddrInIReg as storage and parameter size.
+ */
- switch (info->native_size) {
- case 0:
- g_assert (!fields && MONO_TYPE_ISSTRUCT (type) && !is_return);
- break;
- case 1: case 2: case 4: case 8:
- break;
- default:
- if (is_return) {
- ainfo->storage = ArgValuetypeAddrInIReg;
- ainfo->offset = *stack_size;
- *stack_size += ALIGN_TO (info->native_size, 8);
- }
- else {
- ainfo->storage = ArgValuetypeAddrInIReg;
+ assert (arg_info != NULL && type != NULL && current_int_reg != NULL && current_float_reg != NULL && stack_size != NULL);
- if (*gr < PARAM_REGS) {
- ainfo->pair_storage [0] = ArgInIReg;
- ainfo->pair_regs [0] = param_regs [*gr];
- (*gr) ++;
- }
- else {
- ainfo->pair_storage [0] = ArgOnStack;
- ainfo->offset = *stack_size;
- ainfo->arg_size = sizeof (mgreg_t);
- *stack_size += 8;
- }
- }
+ if (!is_return) {
- g_free (fields);
- return;
+ /* Parameter cases. */
+ if (arg_class != ARG_CLASS_MEMORY && MONO_WIN64_VALUE_TYPE_FITS_REG (arg_size)) {
+ assert (arg_size == 1 || arg_size == 2 || arg_size == 4 || arg_size == 8);
+
+ /* First, try to use registers for parameter. If type is struct it can only be passed by value in integer register. */
+ arg_info->storage = ArgValuetypeInReg;
+ if (!allocate_parameter_register_for_valuetype_win64 (arg_info, !MONO_TYPE_ISSTRUCT (type) ? arg_class : ARG_CLASS_INTEGER, arg_size, current_int_reg, current_float_reg)) {
+ /* No more registers, fallback passing parameter on stack as value. */
+ assert (arg_info->pair_storage [0] == ArgNone && arg_info->pair_storage [1] == ArgNone && arg_info->pair_size [0] == 0 && arg_info->pair_size [1] == 0 && arg_info->nregs == 0);
+
+ /* Passing value directly on stack, so use size of value. */
+ arg_info->storage = ArgOnStack;
+ arg_size = ALIGN_TO (arg_size, sizeof (mgreg_t));
+ arg_info->offset = *stack_size;
+ arg_info->arg_size = arg_size;
+ *stack_size += arg_size;
+ }
+ } else {
+ /* Fallback to stack, try to pass address to parameter in register. Always use integer register to represent stack address. */
+ arg_info->storage = ArgValuetypeAddrInIReg;
+ if (!allocate_parameter_register_for_valuetype_win64 (arg_info, ARG_CLASS_INTEGER, arg_size, current_int_reg, current_float_reg)) {
+ /* No more registers, fallback passing address to parameter on stack. */
+ assert (arg_info->pair_storage [0] == ArgNone && arg_info->pair_storage [1] == ArgNone && arg_info->pair_size [0] == 0 && arg_info->pair_size [1] == 0 && arg_info->nregs == 0);
+
+ /* Passing an address to value on stack, so use size of register as argument size. */
+ arg_info->storage = ArgValuetypeAddrOnStack;
+ arg_size = sizeof (mgreg_t);
+ arg_info->offset = *stack_size;
+ arg_info->arg_size = arg_size;
+ *stack_size += arg_size;
+ }
}
+ } else {
+ /* Return value cases. */
+ if (arg_class != ARG_CLASS_MEMORY && MONO_WIN64_VALUE_TYPE_FITS_REG (arg_size)) {
+ assert (arg_size == 1 || arg_size == 2 || arg_size == 4 || arg_size == 8);
- int size;
- guint32 align;
- ArgumentClass class1;
+ /* Return value fits into return registers. If type is struct it can only be returned by value in integer register. */
+ arg_info->storage = ArgValuetypeInReg;
+ allocate_return_register_for_valuetype_win64 (arg_info, !MONO_TYPE_ISSTRUCT (type) ? arg_class : ARG_CLASS_INTEGER, arg_size, current_int_reg, current_float_reg);
- if (nfields == 0 && ainfo->pass_empty_struct) {
- g_assert (!fields && !is_return);
- class1 = ARG_CLASS_INTEGER;
- }
- else if (nfields == 0)
- class1 = ARG_CLASS_MEMORY;
- else
- class1 = ARG_CLASS_NO_CLASS;
- for (i = 0; i < nfields; ++i) {
- size = mono_marshal_type_size (fields [i].field->type,
- fields [i].mspec,
- &align, TRUE, klass->unicode);
- /* How far into this quad this data extends.*/
- /* (8 is size of quad) */
- argsize = fields [i].offset + size;
+ /* Only RAX/XMM0 should be used to return valuetype. */
+ assert ((arg_info->pair_regs[0] == AMD64_RAX && arg_info->pair_regs[1] == ArgNone) || (arg_info->pair_regs[0] == AMD64_XMM0 && arg_info->pair_regs[1] == ArgNone));
+ } else {
+ /* Return value doesn't fit into return register, return address to allocated stack space (allocated by caller and passed as input). */
+ arg_info->storage = ArgValuetypeAddrInIReg;
+ allocate_return_register_for_valuetype_win64 (arg_info, ARG_CLASS_INTEGER, arg_size, current_int_reg, current_float_reg);
+
+ /* Only RAX should be used to return valuetype address. */
+ assert (arg_info->pair_regs[0] == AMD64_RAX && arg_info->pair_regs[1] == ArgNone);
- class1 = merge_argument_class_from_type (fields [i].field->type, class1);
+ arg_size = ALIGN_TO (arg_size, sizeof (mgreg_t));
+ arg_info->offset = *stack_size;
+ *stack_size += arg_size;
}
- g_assert (class1 != ARG_CLASS_NO_CLASS);
- arg_class = class1;
}
+}
- g_free (fields);
+static void
+get_valuetype_size_win64 (MonoClass *klass, gboolean pinvoke, ArgInfo *arg_info, MonoType *type, ArgumentClass *arg_class, guint32 *arg_size)
+{
+ *arg_size = 0;
+ *arg_class = ARG_CLASS_NO_CLASS;
- /* Allocate registers */
- {
- int orig_gr = *gr;
- int orig_fr = *fr;
+ assert (klass != NULL && arg_info != NULL && type != NULL && arg_class != NULL && arg_size != NULL);
+
+ if (pinvoke) {
+ /* Calculate argument class type and size of marshalled type. */
+ MonoMarshalType *info = mono_marshal_load_type_info (klass);
+ *arg_size = info->native_size;
+ } else {
+ /* Calculate argument class type and size of managed type. */
+ *arg_size = mono_class_value_size (klass, NULL);
+ }
- while (argsize != 1 && argsize != 2 && argsize != 4 && argsize != 8)
- argsize ++;
+ /* Windows ABI only handle value types on stack or passed in integer register (if it fits register size). */
+ *arg_class = MONO_WIN64_VALUE_TYPE_FITS_REG (*arg_size) ? ARG_CLASS_INTEGER : ARG_CLASS_MEMORY;
- ainfo->storage = ArgValuetypeInReg;
- ainfo->pair_storage [0] = ainfo->pair_storage [1] = ArgNone;
- ainfo->pair_size [0] = argsize;
- ainfo->pair_size [1] = 0;
- ainfo->nregs = 1;
- switch (arg_class) {
- case ARG_CLASS_INTEGER:
- if (*gr >= PARAM_REGS)
- arg_class = ARG_CLASS_MEMORY;
- else {
- ainfo->pair_storage [0] = ArgInIReg;
- if (is_return)
- ainfo->pair_regs [0] = return_regs [*gr];
- else
- ainfo->pair_regs [0] = param_regs [*gr];
- (*gr) ++;
- }
- break;
- case ARG_CLASS_SSE:
- if (*fr >= FLOAT_PARAM_REGS)
- arg_class = ARG_CLASS_MEMORY;
- else {
- if (argsize <= 4)
- ainfo->pair_storage [0] = ArgInFloatSSEReg;
- else
- ainfo->pair_storage [0] = ArgInDoubleSSEReg;
- ainfo->pair_regs [0] = *fr;
- (*fr) ++;
- }
- break;
- case ARG_CLASS_MEMORY:
- break;
- default:
- g_assert_not_reached ();
- }
+ if (*arg_class == ARG_CLASS_MEMORY) {
+ /* Value type has a size that doesn't seem to fit register according to ABI. Try to used full stack size of type. */
+ *arg_size = mini_type_stack_size_full (&klass->byval_arg, NULL, pinvoke);
+ }
- if (arg_class == ARG_CLASS_MEMORY) {
- /* Revert possible register assignments */
- *gr = orig_gr;
- *fr = orig_fr;
+ /*
+ * Standard C and C++ doesn't allow empty structs, empty structs will always have a size of 1 byte.
+ * GCC have an extension to allow empty structs, https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html.
+ * This cause a little dilemma since runtime build using none GCC compiler will not be compatible with
+ * GCC build C libraries and the other way around. On platforms where empty structs has size of 1 byte
+ * it must be represented in call and cannot be dropped.
+ */
+ if (*arg_size == 0 && MONO_TYPE_ISSTRUCT (type)) {
+ arg_info->pass_empty_struct = TRUE;
+ *arg_size = SIZEOF_REGISTER;
+ *arg_class = ARG_CLASS_INTEGER;
+ }
- ainfo->offset = *stack_size;
- *stack_size += sizeof (mgreg_t);
- ainfo->storage = is_return ? ArgValuetypeAddrInIReg : ArgOnStack;
- if (!is_return)
- ainfo->arg_size = sizeof (mgreg_t);
- }
+ assert (*arg_class != ARG_CLASS_NO_CLASS);
+}
+
+static void
+add_valuetype_win64 (MonoMethodSignature *signature, ArgInfo *arg_info, MonoType *type,
+ gboolean is_return, guint32 *current_int_reg, guint32 *current_float_reg, guint32 *stack_size)
+{
+ guint32 arg_size = SIZEOF_REGISTER;
+ MonoClass *klass = NULL;
+ ArgumentClass arg_class;
+
+ assert (signature != NULL && arg_info != NULL && type != NULL && current_int_reg != NULL && current_float_reg != NULL && stack_size != NULL);
+
+ klass = mono_class_from_mono_type (type);
+ get_valuetype_size_win64 (klass, signature->pinvoke, arg_info, type, &arg_class, &arg_size);
+
+ /* Only drop value type if its not an empty struct as input that must be represented in call */
+ if ((arg_size == 0 && !arg_info->pass_empty_struct) || (arg_size == 0 && arg_info->pass_empty_struct && is_return)) {
+ arg_info->storage = ArgValuetypeInReg;
+ arg_info->pair_storage [0] = arg_info->pair_storage [1] = ArgNone;
+ } else {
+ /* Alocate storage for value type. */
+ allocate_storage_for_valuetype_win64 (arg_info, type, is_return, arg_class, arg_size, current_int_reg, current_float_reg, stack_size);
}
}
+
#endif /* TARGET_WIN32 */
static void
/* use the right size when copying args/return vars. */
guint32 quadsize [2] = {8, 8};
ArgumentClass args [2];
- MonoMarshalType *info = NULL;
- MonoMarshalField *fields = NULL;
+ StructFieldInfo *fields = NULL;
MonoClass *klass;
gboolean pass_on_stack = FALSE;
+ int struct_size;
klass = mono_class_from_mono_type (type);
size = mini_type_stack_size_full (&klass->byval_arg, NULL, sig->pinvoke);
/* If this struct can't be split up naturally into 8-byte */
/* chunks (registers), pass it on the stack. */
- if (sig->pinvoke && !pass_on_stack) {
- guint32 align;
- guint32 field_size;
-
- info = mono_marshal_load_type_info (klass);
+ if (sig->pinvoke) {
+ MonoMarshalType *info = mono_marshal_load_type_info (klass);
g_assert (info);
+ struct_size = info->native_size;
+ } else {
+ struct_size = mono_class_value_size (klass, NULL);
+ }
+ /*
+ * Collect field information recursively to be able to
+ * handle nested structures.
+ */
+ nfields = count_fields_nested (klass, sig->pinvoke);
+ fields = g_new0 (StructFieldInfo, nfields);
+ collect_field_info_nested (klass, fields, 0, 0, sig->pinvoke, klass->unicode);
- /*
- * Collect field information recursively to be able to
- * handle nested structures.
- */
- nfields = count_fields_nested (klass);
- fields = g_new0 (MonoMarshalField, nfields);
- collect_field_info_nested (klass, fields, 0, 0);
-
- for (i = 0; i < nfields; ++i) {
- field_size = mono_marshal_type_size (fields [i].field->type,
- fields [i].mspec,
- &align, TRUE, klass->unicode);
- if ((fields [i].offset < 8) && (fields [i].offset + field_size) > 8) {
- pass_on_stack = TRUE;
- break;
- }
+ for (i = 0; i < nfields; ++i) {
+ if ((fields [i].offset < 8) && (fields [i].offset + fields [i].size) > 8) {
+ pass_on_stack = TRUE;
+ break;
}
}
* The X87 and SSEUP stuff is left out since there are no such types in
* the CLR.
*/
- g_assert (info);
-
- if (!fields) {
+ if (!nfields) {
ainfo->storage = ArgValuetypeInReg;
ainfo->pair_storage [0] = ainfo->pair_storage [1] = ArgNone;
return;
}
- if (info->native_size > 16) {
+ if (struct_size > 16) {
ainfo->offset = *stack_size;
- *stack_size += ALIGN_TO (info->native_size, 8);
+ *stack_size += ALIGN_TO (struct_size, 8);
ainfo->storage = is_return ? ArgValuetypeAddrInIReg : ArgOnStack;
if (!is_return)
- ainfo->arg_size = ALIGN_TO (info->native_size, 8);
+ ainfo->arg_size = ALIGN_TO (struct_size, 8);
g_free (fields);
return;
args [0] = ARG_CLASS_NO_CLASS;
args [1] = ARG_CLASS_NO_CLASS;
for (quad = 0; quad < nquads; ++quad) {
- int size;
- guint32 align;
ArgumentClass class1;
if (nfields == 0)
else
class1 = ARG_CLASS_NO_CLASS;
for (i = 0; i < nfields; ++i) {
- size = mono_marshal_type_size (fields [i].field->type,
- fields [i].mspec,
- &align, TRUE, klass->unicode);
- if ((fields [i].offset < 8) && (fields [i].offset + size) > 8) {
+ if ((fields [i].offset < 8) && (fields [i].offset + fields [i].size) > 8) {
/* Unaligned field */
NOT_IMPLEMENTED;
}
/* How far into this quad this data extends.*/
/* (8 is size of quad) */
- quadsize [quad] = fields [i].offset + size - (quad * 8);
+ quadsize [quad] = fields [i].offset + fields [i].size - (quad * 8);
- class1 = merge_argument_class_from_type (fields [i].field->type, class1);
+ class1 = merge_argument_class_from_type (fields [i].type, class1);
}
- g_assert (class1 != ARG_CLASS_NO_CLASS);
+ /* Empty structs have a nonzero size, causing this assert to be hit */
+ if (sig->pinvoke)
+ g_assert (class1 != ARG_CLASS_NO_CLASS);
args [quad] = class1;
}
}
break;
case ARG_CLASS_MEMORY:
break;
+ case ARG_CLASS_NO_CLASS:
+ break;
default:
g_assert_not_reached ();
}
ainfo->offset = *stack_size;
if (sig->pinvoke)
- arg_size = ALIGN_TO (info->native_size, 8);
+ arg_size = ALIGN_TO (struct_size, 8);
else
arg_size = nquads * sizeof(mgreg_t);
*stack_size += arg_size;
/* fall through */
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_TYPEDBYREF:
- add_valuetype (sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
+ add_valuetype (sig, ainfo, ptype, FALSE, &gr, &fr, &stack_size);
break;
case MONO_TYPE_U8:
mono_aot_register_jit_icall ("mono_amd64_throw_corlib_exception", mono_amd64_throw_corlib_exception);
mono_aot_register_jit_icall ("mono_amd64_resume_unwind", mono_amd64_resume_unwind);
mono_aot_register_jit_icall ("mono_amd64_get_original_ip", mono_amd64_get_original_ip);
+ mono_aot_register_jit_icall ("mono_amd64_handler_block_trampoline_helper", mono_amd64_handler_block_trampoline_helper);
+
#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
mono_aot_register_jit_icall ("mono_amd64_start_gsharedvt_call", mono_amd64_start_gsharedvt_call);
#endif
*exclude_mask |= MONO_OPT_CMOV;
}
+#ifdef TARGET_WIN32
+ /* The current SIMD doesn't support the argument used by a LD_ADDR to be of type OP_VTARG_ADDR. */
+ /* This will now be used for value types > 8 or of size 3,5,6,7 as dictated by windows x64 value type ABI. */
+ /* Since OP_VTARG_ADDR needs to be resolved in mono_spill_global_vars and the SIMD implementation optimize */
+ /* away the LD_ADDR in load_simd_vreg, that will cause an error in mono_spill_global_vars since incorrect opcode */
+ /* will now have a reference to an argument that won't be fully decomposed. */
+ *exclude_mask |= MONO_OPT_SIMD;
+#endif
+
return opts;
}
for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
ArgInfo *ainfo = &cinfo->args [i];
- if (ainfo->storage == ArgOnStack) {
+ if (ainfo->storage == ArgOnStack || ainfo->storage == ArgValuetypeAddrInIReg || ainfo->storage == ArgValuetypeAddrOnStack) {
/*
* The stack offset can only be determined when the frame
* size is known.
}
cfg->arch.saved_iregs = cfg->used_int_regs;
- if (cfg->method->save_lmf)
- /* Save all callee-saved registers normally, and restore them when unwinding through an LMF */
- cfg->arch.saved_iregs |= (1 << AMD64_RBX) | (1 << AMD64_R12) | (1 << AMD64_R13) | (1 << AMD64_R14) | (1 << AMD64_R15);
+ if (cfg->method->save_lmf) {
+ /* Save all callee-saved registers normally (except RBP, if not already used), and restore them when unwinding through an LMF */
+ guint32 iregs_to_save = AMD64_CALLEE_SAVED_REGS & ~(1<<AMD64_RBP);
+ cfg->arch.saved_iregs |= iregs_to_save;
+ }
if (cfg->arch.omit_fp)
cfg->arch.reg_save_area_offset = offset;
break;
case ArgValuetypeInReg:
break;
- case ArgValuetypeAddrInIReg: {
+ case ArgValuetypeAddrInIReg:
+ case ArgValuetypeAddrOnStack: {
MonoInst *indir;
g_assert (!cfg->arch.omit_fp);
-
+ g_assert (ainfo->storage == ArgValuetypeAddrInIReg || (ainfo->storage == ArgValuetypeAddrOnStack && ainfo->pair_storage [0] == ArgNone));
MONO_INST_NEW (cfg, indir, 0);
+
indir->opcode = OP_REGOFFSET;
if (ainfo->pair_storage [0] == ArgInIReg) {
indir->inst_basereg = cfg->frame_reg;
NOT_IMPLEMENTED;
}
- if (!inreg && (ainfo->storage != ArgOnStack) && (ainfo->storage != ArgValuetypeAddrInIReg) && (ainfo->storage != ArgGSharedVtOnStack)) {
+ if (!inreg && (ainfo->storage != ArgOnStack) && (ainfo->storage != ArgValuetypeAddrInIReg) && (ainfo->storage != ArgValuetypeAddrOnStack) && (ainfo->storage != ArgGSharedVtOnStack)) {
ins->opcode = OP_REGOFFSET;
ins->inst_basereg = cfg->frame_reg;
/* These arguments are saved to the stack in the prolog */
case ArgOnStack:
case ArgValuetypeInReg:
case ArgValuetypeAddrInIReg:
+ case ArgValuetypeAddrOnStack:
case ArgGSharedVtInReg:
case ArgGSharedVtOnStack: {
if (ainfo->storage == ArgOnStack && !MONO_TYPE_ISSTRUCT (t) && !call->tail_call)
}
break;
}
- case ArgValuetypeAddrInIReg: {
+ case ArgValuetypeAddrInIReg:
+ case ArgValuetypeAddrOnStack: {
MonoInst *vtaddr, *load;
+
+ g_assert (ainfo->storage == ArgValuetypeAddrInIReg || (ainfo->storage == ArgValuetypeAddrOnStack && ainfo->pair_storage [0] == ArgNone));
+
vtaddr = mono_compile_create_var (cfg, &ins->klass->byval_arg, OP_LOCAL);
MONO_INST_NEW (cfg, load, OP_LDADDR);
case ArgInFloatSSEReg:
case ArgInDoubleSSEReg:
case ArgValuetypeAddrInIReg:
+ case ArgValuetypeInReg:
break;
- case ArgValuetypeInReg: {
- ArgInfo *ainfo = &cinfo->ret;
-
- if (ainfo->pair_storage [0] != ArgNone && ainfo->pair_storage [0] != ArgInIReg)
- return FALSE;
- if (ainfo->pair_storage [1] != ArgNone && ainfo->pair_storage [1] != ArgInIReg)
- return FALSE;
- break;
- }
default:
return FALSE;
}
case ArgInIReg:
case ArgInFloatSSEReg:
case ArgInDoubleSSEReg:
- break;
case ArgValuetypeInReg:
- if (ainfo->pair_storage [0] != ArgNone && ainfo->pair_storage [0] != ArgInIReg)
- return FALSE;
- if (ainfo->pair_storage [1] != ArgNone && ainfo->pair_storage [1] != ArgInIReg)
- return FALSE;
break;
case ArgOnStack:
if (!(ainfo->offset + (ainfo->arg_size / 8) <= DYN_CALL_STACK_ARGS))
case MONO_TYPE_VALUETYPE: {
switch (ainfo->storage) {
case ArgValuetypeInReg:
- if (ainfo->pair_storage [0] != ArgNone) {
- slot = param_reg_to_index [ainfo->pair_regs [0]];
- g_assert (ainfo->pair_storage [0] == ArgInIReg);
- p->regs [slot] = ((mgreg_t*)(arg))[0];
- }
- if (ainfo->pair_storage [1] != ArgNone) {
- slot = param_reg_to_index [ainfo->pair_regs [1]];
- g_assert (ainfo->pair_storage [1] == ArgInIReg);
- p->regs [slot] = ((mgreg_t*)(arg))[1];
+ for (i = 0; i < 2; ++i) {
+ switch (ainfo->pair_storage [i]) {
+ case ArgNone:
+ break;
+ case ArgInIReg:
+ slot = param_reg_to_index [ainfo->pair_regs [i]];
+ p->regs [slot] = ((mgreg_t*)(arg))[i];
+ break;
+ case ArgInDoubleSSEReg:
+ p->has_fp = 1;
+ p->fregs [ainfo->pair_regs [i]] = ((double*)(arg))[i];
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
}
break;
case ArgOnStack:
guint8 *ret = dargs->ret;
mgreg_t res = dargs->res;
MonoType *sig_ret = mini_get_underlying_type (sig->ret);
+ int i;
switch (sig_ret->type) {
case MONO_TYPE_VOID:
g_assert (ainfo->storage == ArgValuetypeInReg);
- if (ainfo->pair_storage [0] != ArgNone) {
- g_assert (ainfo->pair_storage [0] == ArgInIReg);
- ((mgreg_t*)ret)[0] = res;
+ for (i = 0; i < 2; ++i) {
+ switch (ainfo->pair_storage [0]) {
+ case ArgInIReg:
+ ((mgreg_t*)ret)[i] = res;
+ break;
+ case ArgInDoubleSSEReg:
+ ((double*)ret)[i] = dargs->fregs [i];
+ break;
+ case ArgNone:
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
}
-
- g_assert (ainfo->pair_storage [1] == ArgNone);
}
break;
default:
return code;
}
+#ifdef TARGET_WIN32
+
+#define TEB_LAST_ERROR_OFFSET 0x068
+
+static guint8*
+emit_get_last_error (guint8* code, int dreg)
+{
+ /* Threads last error value is located in TEB_LAST_ERROR_OFFSET. */
+ x86_prefix (code, X86_GS_PREFIX);
+ amd64_mov_reg_membase (code, dreg, TEB_LAST_ERROR_OFFSET, 0, sizeof (guint32));
+
+ return code;
+}
+
+#else
+
+static guint8*
+emit_get_last_error (guint8* code, int dreg)
+{
+ g_assert_not_reached ();
+}
+
+#endif
+
/* benchmark and set based on cpu */
#define LOOP_ALIGNMENT 8
#define bb_is_loop_start(bb) ((bb)->loop_body_start && (bb)->nesting)
amd64_mov_reg_membase (code, AMD64_R11, var->inst_basereg, var->inst_offset, 8);
amd64_mov_membase_reg (code, AMD64_R11, MONO_STRUCT_OFFSET (DynCallArgs, res), AMD64_RAX, 8);
amd64_sse_movsd_membase_reg (code, AMD64_R11, MONO_STRUCT_OFFSET (DynCallArgs, fregs), AMD64_XMM0);
+ amd64_sse_movsd_membase_reg (code, AMD64_R11, MONO_STRUCT_OFFSET (DynCallArgs, fregs) + sizeof (double), AMD64_XMM1);
break;
}
case OP_AMD64_SAVE_SP_TO_LMF: {
ins->backend.pc_offset = code - cfg->native_code;
bb->spill_slot_defs = g_slist_prepend_mempool (cfg->mempool, bb->spill_slot_defs, ins);
break;
+ case OP_GET_LAST_ERROR:
+ emit_get_last_error(code, ins->dreg);
+ break;
default:
g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
g_assert_not_reached ();
if (ainfo->pair_storage [0] == ArgInIReg)
amd64_mov_membase_reg (code, ins->inst_left->inst_basereg, ins->inst_left->inst_offset, ainfo->pair_regs [0], sizeof (gpointer));
break;
+ case ArgValuetypeAddrOnStack:
+ break;
case ArgGSharedVtInReg:
amd64_mov_membase_reg (code, ins->inst_basereg, ins->inst_offset, ainfo->reg, 8);
break;
amd64_jump_membase (code, AMD64_RAX, offset);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
- if (load_imt_reg)
- tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", - offset / sizeof (gpointer));
- else
- tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", offset / sizeof (gpointer));
+ tramp_name = mono_get_delegate_virtual_invoke_impl_name (load_imt_reg, offset);
*info = mono_tramp_info_create (tramp_name, start, code - start, NULL, unwind_ops);
g_free (tramp_name);
res = g_slist_prepend (res, info);
}
- for (i = 0; i <= MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
+ for (i = 1; i <= MONO_IMT_SIZE; ++i) {
get_delegate_virtual_invoke_impl (&info, TRUE, - i * SIZEOF_VOID_P);
res = g_slist_prepend (res, info);
+ }
+ for (i = 0; i <= MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
get_delegate_virtual_invoke_impl (&info, FALSE, i * SIZEOF_VOID_P);
res = g_slist_prepend (res, info);
+ get_delegate_virtual_invoke_impl (&info, TRUE, i * SIZEOF_VOID_P);
+ res = g_slist_prepend (res, info);
}
return res;
} MonoCompileArch;
#ifdef TARGET_WIN32
-#define PARAM_REGS 4
-#define FLOAT_PARAM_REGS 4
static AMD64_Reg_No param_regs [] = { AMD64_RCX, AMD64_RDX, AMD64_R8, AMD64_R9 };
-static AMD64_Reg_No return_regs [] = { AMD64_RAX, AMD64_RDX };
+static AMD64_Reg_No float_param_regs [] = { AMD64_XMM0, AMD64_XMM1, AMD64_XMM2, AMD64_XMM3 };
+
+static AMD64_Reg_No return_regs [] = { AMD64_RAX };
+
+static AMD64_Reg_No float_return_regs [] = { AMD64_XMM0 };
+
+#define PARAM_REGS G_N_ELEMENTS(param_regs)
+#define FLOAT_PARAM_REGS G_N_ELEMENTS(float_param_regs)
+#define RETURN_REGS G_N_ELEMENTS(return_regs)
+#define FLOAT_RETURN_REGS G_N_ELEMENTS(float_return_regs)
+
#else
#define PARAM_REGS 6
#define FLOAT_PARAM_REGS 8
ArgOnStack,
ArgValuetypeInReg,
ArgValuetypeAddrInIReg,
+ ArgValuetypeAddrOnStack,
/* gsharedvt argument passed by addr */
ArgGSharedVtInReg,
ArgGSharedVtOnStack,
#define MONO_ARCH_LLVM_SUPPORTED 1
#define MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD 1
+#define MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD_AOT 1
#define MONO_ARCH_HAVE_CARD_TABLE_WBARRIER 1
#define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1
#define MONO_ARCH_GC_MAPS_SUPPORTED 1
int
mono_amd64_get_tls_gs_offset (void) MONO_LLVM_INTERNAL;
+gpointer
+mono_amd64_handler_block_trampoline_helper (void);
+
#ifdef TARGET_WIN32
void mono_arch_unwindinfo_add_push_nonvol (gpointer* monoui, gpointer codebegin, gpointer nextip, guchar reg );
/*
* Finds the bottom handler block running and install a block guard if needed.
- * FIXME add full-aot support.
*/
gboolean
mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
MonoJitTlsData *jit_tls = (MonoJitTlsData *)ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS];
gpointer resume_ip;
- /* FIXME */
+#ifndef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD_AOT
if (mono_aot_only)
return FALSE;
+#endif
/* Guard against a null MonoJitTlsData. This can happens if the thread receives the
* interrupt signal before the JIT has time to initialize its TLS data for the given thread.
MonoMethod *inflated_method;
MonoType *inflated_type = mono_class_inflate_generic_type_checked (&method->klass->byval_arg, context, &error);
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ WrapperInfo *winfo = NULL;
MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
MonoJumpInfoGSharedVtCall *res;
mono_class_init (inflated_class);
- g_assert (!method->wrapper_type);
+ if (method->wrapper_type) {
+ winfo = mono_marshal_get_wrapper_info (method);
+
+ g_assert (winfo);
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ method = winfo->d.synchronized_inner.method;
+ }
if (inflated_class->byval_arg.type == MONO_TYPE_ARRAY ||
inflated_class->byval_arg.type == MONO_TYPE_SZARRAY) {
}
mono_class_init (inflated_method->klass);
g_assert (inflated_method->klass == inflated_class);
+
+ if (winfo) {
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ inflated_method = mono_marshal_get_synchronized_inner_wrapper (inflated_method);
+ }
+
res->method = inflated_method;
return res;
g_assert (method->is_inflated);
+ if (mono_llvm_only && (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
+ method = mono_marshal_get_synchronized_wrapper (method);
+
if (!virtual_) {
addr = mono_compile_method_checked (method, error);
return_val_if_nok (error, NULL);
unwrap<CallInst>(func)->setCallingConv (CallingConv::PreserveAll);
}
+void
+mono_llvm_set_call_notail (LLVMValueRef func)
+{
+#if LLVM_API_VERSION > 100
+ //unwrap<CallInst>(func)->setTailCallKind (CallInst::TailCallKind::TCK_NoTail);
+#endif
+}
+
#if LLVM_API_VERSION > 100
void*
}
void*
-mono_llvm_di_create_function (void *di_builder, void *cu, const char *name, const char *mangled_name, const char *dir, const char *file, int line)
+mono_llvm_di_create_function (void *di_builder, void *cu, LLVMValueRef func, const char *name, const char *mangled_name, const char *dir, const char *file, int line)
{
DIBuilder *builder = (DIBuilder*)di_builder;
DIFile *di_file;
DISubroutineType *type;
+ DISubprogram *di_func;
// FIXME: Share DIFile
di_file = builder->createFile (file, dir);
type = builder->createSubroutineType (builder->getOrCreateTypeArray (ArrayRef<Metadata*> ()));
- return builder->createFunction (di_file, name, mangled_name, di_file, line, type, true, true, 0);
+ di_func = builder->createFunction (di_file, name, mangled_name, di_file, line, type, true, true, 0);
+
+ unwrap<Function>(func)->setMetadata ("dbg", di_func);
+
+ return di_func;
}
void*
void
mono_llvm_set_call_preserveall_cc (LLVMValueRef call);
+void
+mono_llvm_set_call_notail (LLVMValueRef call);
+
_Unwind_Reason_Code
mono_debug_personality (int a, _Unwind_Action b,
uint64_t c, struct _Unwind_Exception *d, struct _Unwind_Context *e);
mono_llvm_create_di_builder (LLVMModuleRef module);
void*
-mono_llvm_di_create_function (void *di_builder, void *cu, const char *name, const char *mangled_name, const char *dir, const char *file, int line);
+mono_llvm_di_create_function (void *di_builder, void *cu, LLVMValueRef func, const char *name, const char *mangled_name, const char *dir, const char *file, int line);
void*
mono_llvm_di_create_compile_unit (void *di_builder, const char *cu_name, const char *dir, const char *producer);
return "llvm.x86.sse2.min.pd";
case OP_MINPS:
return "llvm.x86.sse.min.ps";
- case OP_PMIND_UN:
- return "llvm.x86.sse41.pminud";
- case OP_PMINW_UN:
- return "llvm.x86.sse41.pminuw";
- case OP_PMINB_UN:
- return "llvm.x86.sse2.pminu.b";
- case OP_PMINW:
- return "llvm.x86.sse2.pmins.w";
case OP_MAXPD:
return "llvm.x86.sse2.max.pd";
case OP_MAXPS:
return "llvm.x86.sse3.hsub.pd";
case OP_HSUBPS:
return "llvm.x86.sse3.hsub.ps";
- case OP_PMAXD_UN:
- return "llvm.x86.sse41.pmaxud";
- case OP_PMAXW_UN:
- return "llvm.x86.sse41.pmaxuw";
- case OP_PMAXB_UN:
- return "llvm.x86.sse2.pmaxu.b";
case OP_ADDSUBPS:
return "llvm.x86.sse3.addsub.ps";
case OP_ADDSUBPD:
return "llvm.x86.sse2.cvttpd2dq";
case OP_CVTTPS2DQ:
return "llvm.x86.sse2.cvttps2dq";
- case OP_COMPPS:
- return "llvm.x86.sse.cmp.ps";
- case OP_COMPPD:
- return "llvm.x86.sse2.cmp.pd";
case OP_PACKW:
return "llvm.x86.sse2.packsswb.128";
case OP_PACKD:
emit_volatile_load (EmitContext *ctx, int vreg)
{
MonoType *t;
+ LLVMValueRef v;
- LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
+#ifdef TARGET_ARM64
+ // FIXME: This hack is required because we pass the rgctx in a callee saved
+ // register on arm64 (x15), and llvm might keep the value in that register
+ // even through the register is marked as 'reserved' inside llvm.
+ if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
+ v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
+ else
+ v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
+#else
+ v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
+#endif
t = ctx->vreg_cli_types [vreg];
if (t && !t->byref) {
/*
MonoCompile *cfg;
guint32 got_offset;
LLVMValueRef indexes [2];
- MonoJumpInfo *ji;
LLVMValueRef got_entry_addr, load;
LLVMBuilderRef builder = ctx->builder;
char *name = NULL;
cfg = ctx->cfg;
- ji = g_new0 (MonoJumpInfo, 1);
- ji->type = type;
- ji->data.target = data;
+ MonoJumpInfo tmp_ji;
+ tmp_ji.type = type;
+ tmp_ji.data.target = data;
- ji = mono_aot_patch_info_dup (ji);
+ MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
ji->next = cfg->patch_info;
cfg->patch_info = ji;
LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
LLVMBasicBlockRef *bbs;
LLVMTypeRef rtype;
- LLVMBuilderRef builder;
+ LLVMBuilderRef builder = LLVMCreateBuilder ();
char *name;
int i;
name = g_strdup_printf ("BB_CODE_START");
code_start_bb = LLVMAppendBasicBlock (func, name);
g_free (name);
- builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, code_start_bb);
LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
name = g_strdup_printf ("BB_CODE_END");
code_end_bb = LLVMAppendBasicBlock (func, name);
g_free (name);
- builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, code_end_bb);
LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
g_free (name);
bbs [i] = bb;
- builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, bb);
m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
}
fail_bb = LLVMAppendBasicBlock (func, "FAIL");
- builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, fail_bb);
LLVMBuildRet (builder, LLVMConstNull (rtype));
- builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, entry_bb);
switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
}
mark_as_used (module, func);
+
+ LLVMDisposeBuilder (builder);
}
/*
LLVMBasicBlockRef entry_bb, fail_bb, bb;
LLVMBasicBlockRef *bbs;
LLVMTypeRef rtype;
- LLVMBuilderRef builder;
+ LLVMBuilderRef builder = LLVMCreateBuilder ();
char *name;
int i;
g_free (name);
bbs [i] = bb;
- builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, bb);
LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
}
fail_bb = LLVMAppendBasicBlock (func, "FAIL");
- builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, fail_bb);
LLVMBuildRet (builder, LLVMConstNull (rtype));
- builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, entry_bb);
switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
}
mark_as_used (module, func);
+ LLVMDisposeBuilder (builder);
}
/* Add a function to mark the beginning of LLVM code */
builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, entry_bb);
LLVMBuildRetVoid (builder);
+ LLVMDisposeBuilder (builder);
}
static LLVMValueRef
LLVMBuildRetVoid (builder);
LLVMVerifyFunction(func, LLVMAbortProcessAction);
+ LLVMDisposeBuilder (builder);
return func;
}
builder = LLVMCreateBuilder ();
LLVMPositionBuilderAtEnd (builder, entry_bb);
LLVMBuildRetVoid (builder);
+ LLVMDisposeBuilder (builder);
}
static void
LLVMBuildRet (builder, call);
g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
+ LLVMDisposeBuilder (builder);
}
/*
LLVMPositionBuilderAtEnd (builder2, entry_bb);
LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
ctx->module->personality = personality;
+ LLVMDisposeBuilder (builder2);
}
#else
static gint32 mapping_inited;
if (!var) {
LLVMValueRef indexes [16];
- LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME");
+ LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
LLVMSetLinkage (name_var, LLVMPrivateLinkage);
LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
+ mark_as_used (ctx->module, name_var);
- LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES");
+ LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
LLVMSetExternallyInitialized (ref_var, TRUE);
LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
LLVMSetAlignment (ref_var, sizeof (mgreg_t));
+ mark_as_used (ctx->module, ref_var);
g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
var = ref_var;
values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
break;
}
+ case OP_PMIND_UN:
+ case OP_PMINW_UN:
+ case OP_PMINB_UN: {
+ LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
+ values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
+ break;
+ }
+ case OP_PMAXD_UN:
+ case OP_PMAXW_UN:
+ case OP_PMAXB_UN: {
+ LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
+ values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
+ break;
+ }
+ case OP_PMINW: {
+ LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
+ values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
+ break;
+ }
case OP_MINPD:
case OP_MINPS:
case OP_MAXPD:
case OP_MAXPS:
case OP_ADDSUBPD:
case OP_ADDSUBPS:
- case OP_PMIND_UN:
- case OP_PMINW_UN:
- case OP_PMINB_UN:
- case OP_PMINW:
- case OP_PMAXD_UN:
- case OP_PMAXW_UN:
- case OP_PMAXB_UN:
case OP_HADDPD:
case OP_HADDPS:
case OP_HSUBPD:
values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
break;
+#if 0
+ // Requires a later llvm version
+ case OP_CVTDQ2PD: {
+ LLVMValueRef indexes [16];
+
+ indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
+ indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
+ LLVMValueRef mask = LLVMConstVector (indexes, 2);
+ LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
+ values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
+ break;
+ }
+ case OP_CVTPS2PD: {
+ LLVMValueRef indexes [16];
+
+ indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
+ indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
+ LLVMValueRef mask = LLVMConstVector (indexes, 2);
+ LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
+ values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
+ break;
+ }
+ case OP_CVTTPS2DQ:
+ values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
+ break;
+#endif
+
case OP_CVTDQ2PD:
case OP_CVTDQ2PS:
case OP_CVTPD2DQ:
values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
break;
}
-
case OP_COMPPS:
case OP_COMPPD: {
- LLVMValueRef args [3];
+ LLVMRealPredicate op;
- args [0] = lhs;
- args [1] = rhs;
- args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
+ switch (ins->inst_c0) {
+ case SIMD_COMP_EQ:
+ op = LLVMRealOEQ;
+ break;
+ case SIMD_COMP_LT:
+ op = LLVMRealOLT;
+ break;
+ case SIMD_COMP_LE:
+ op = LLVMRealOLE;
+ break;
+ case SIMD_COMP_UNORD:
+ op = LLVMRealUNO;
+ break;
+ case SIMD_COMP_NEQ:
+ op = LLVMRealUNE;
+ break;
+ case SIMD_COMP_NLT:
+ op = LLVMRealUGE;
+ break;
+ case SIMD_COMP_NLE:
+ op = LLVMRealUGT;
+ break;
+ case SIMD_COMP_ORD:
+ op = LLVMRealORD;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
- values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
+ LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
+ if (ins->opcode == OP_COMPPD)
+ values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
+ else
+ values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
break;
}
-
case OP_ICONV_TO_X:
/* This is only used for implementing shifts by non-immediate */
values [ins->dreg] = lhs;
g_hash_table_destroy (ctx->region_to_handler);
g_hash_table_destroy (ctx->clause_to_handler);
g_hash_table_destroy (ctx->jit_callees);
+
+ GHashTableIter iter;
+ g_hash_table_iter_init (&iter, ctx->method_to_callers);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
+ g_slist_free (l);
+
+ g_hash_table_destroy (ctx->method_to_callers);
+
g_free (ctx->method_name);
g_ptr_array_free (ctx->bblock_list, TRUE);
INTRINS_SSE_HADDPD,
INTRINS_SSE_HSUBPD,
INTRINS_SSE_ADDSUBPD,
- INTRINS_SSE_PMINUD,
- INTRINS_SSE_PMAXUD,
- INTRINS_SSE_PMINUW,
- INTRINS_SSE_PMINSW,
- INTRINS_SSE_PMAXUW,
INTRINS_SSE_PADDSW,
INTRINS_SSE_PSUBSW,
INTRINS_SSE_PADDUSW,
INTRINS_SSE_PAVGW,
INTRINS_SSE_PMULHW,
INTRINS_SSE_PMULHU,
- INTRINS_SSE_PMINUB,
- INTRINS_SSE_PMAXUB,
INTRINS_SE_PADDSB,
INTRINS_SSE_PSUBSB,
INTRINS_SSE_PADDUSB,
{INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
{INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
{INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
- {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
- {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
- {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
- {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
- {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
{INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
{INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
{INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
{INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
{INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
{INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
- {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
- {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
{INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
{INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
{INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
AddFunc (module, name, ret_type, arg_types, 2);
break;
/* SSE Binary ops */
- case INTRINS_SSE_PMINUD:
- case INTRINS_SSE_PMAXUD:
- add_sse_binary (module, name, MONO_TYPE_I4);
- break;
- case INTRINS_SSE_PMINUW:
- case INTRINS_SSE_PMINSW:
- case INTRINS_SSE_PMAXUW:
case INTRINS_SSE_PADDSW:
case INTRINS_SSE_PSUBSW:
case INTRINS_SSE_PADDUSW:
case INTRINS_SSE_ADDSUBPD:
add_sse_binary (module, name, MONO_TYPE_R8);
break;
- case INTRINS_SSE_PMINUB:
- case INTRINS_SSE_PMAXUB:
case INTRINS_SE_PADDSB:
case INTRINS_SSE_PSUBSB:
case INTRINS_SSE_PADDUSB:
AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
}
- /* SSE intrinsics */
-#if defined(TARGET_X86) || defined(TARGET_AMD64)
-
-#endif
-
/* Load/Store intrinsics */
{
LLVMTypeRef arg_types [5];
/* clang ignores our debug info because it has an invalid version */
module->emit_dwarf = FALSE;
-#if LLVM_API_VERSION > 100
- module->emit_dwarf = FALSE;
-#endif
-
add_intrinsics (module->lmodule);
add_types (module);
return res;
}
+static LLVMValueRef
+llvm_array_from_bytes (guint8 *values, int nvalues)
+{
+ int i;
+ LLVMValueRef res, *vals;
+
+ vals = g_new0 (LLVMValueRef, nvalues);
+ for (i = 0; i < nvalues; ++i)
+ vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
+ res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
+ g_free (vals);
+ return res;
+}
/*
* mono_llvm_emit_aot_file_info:
*
info = &module->aot_info;
/* Create an LLVM type to represent MonoAotFileInfo */
- nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
+ nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
eltypes = g_new (LLVMTypeRef, nfields);
tindex = 0;
eltypes [tindex ++] = LLVMInt32Type ();
eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
for (i = 0; i < 4; ++i)
eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
+ eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
g_assert (tindex == nfields);
file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
+
+ fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
g_assert (tindex == nfields);
LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
LLVMValueRef lmethod;
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ continue;
+
lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
if (lmethod) {
for (l = callers; l; l = l->next) {
filename = g_path_get_basename (source_file);
#if LLVM_API_VERSION > 100
- return mono_llvm_di_create_function (module->di_builder, module->cu, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
+ return mono_llvm_di_create_function (module->di_builder, module->cu, method, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
#endif
ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
MINI_OP(OP_GET_SP, "get_sp", IREG, NONE, NONE)
MINI_OP(OP_SET_SP, "set_sp", NONE, IREG, NONE)
+MINI_OP(OP_GET_LAST_ERROR, "get_last_error", IREG, NONE, NONE)
handle = mono_ldtoken_checked (patch_info->data.token->image,
patch_info->data.token->token, &handle_class, patch_info->data.token->has_context ? &patch_info->data.token->context : NULL, error);
if (!mono_error_ok (error))
- g_error ("Could not patch ldtoken due to %s", mono_error_get_message (error));
+ return NULL;
mono_class_init (handle_class);
mono_class_init (mono_class_from_mono_type ((MonoType *)handle));
mono_error_init (error);
+ if (mono_llvm_only)
+ /* Should be handled by the caller */
+ g_assert (!(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED));
+
/*
* ICALL wrappers are handled specially, since there is only one copy of them
* shared by all appdomains.
MonoException *exc;
MONO_SIG_HANDLER_GET_CONTEXT;
+ if (mono_runtime_get_no_exec ())
+ exit (1);
+
MONO_ENTER_GC_UNSAFE_UNBALANCED;
exc = mono_get_exception_execution_engine ("SIGILL");
del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr);
}
+char*
+mono_get_delegate_virtual_invoke_impl_name (gboolean load_imt_reg, int offset)
+{
+ int abs_offset;
+
+ abs_offset = offset;
+ if (abs_offset < 0)
+ abs_offset = - abs_offset;
+ return g_strdup_printf ("delegate_virtual_invoke%s_%s%d", load_imt_reg ? "_imt" : "", offset < 0 ? "m_" : "", abs_offset / SIZEOF_VOID_P);
+}
+
gpointer
mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method)
{
/* FIXME Support more cases */
if (mono_aot_only) {
- char tramp_name [256];
- const char *imt = load_imt_reg ? "_imt" : "";
- int ind = (load_imt_reg ? (-offset) : offset) / SIZEOF_VOID_P;
-
- sprintf (tramp_name, "delegate_virtual_invoke%s_%d", imt, ind);
- cache [idx] = (guint8 *)mono_aot_get_trampoline (tramp_name);
+ cache [idx] = (guint8 *)mono_aot_get_trampoline (mono_get_delegate_virtual_invoke_impl_name (load_imt_reg, offset));
g_assert (cache [idx]);
} else {
cache [idx] = (guint8 *)mono_arch_get_delegate_virtual_invoke_impl (sig, method, offset, load_imt_reg);
else if (!strcmp (option, "gen-seq-points"))
debug_options.gen_sdb_seq_points = TRUE;
else if (!strcmp (option, "gen-compact-seq-points"))
- debug_options.gen_seq_points_compact_data = TRUE;
+ fprintf (stderr, "Mono Warning: option gen-compact-seq-points is deprecated.\n");
+ else if (!strcmp (option, "no-compact-seq-points"))
+ debug_options.no_seq_points_compact_data = TRUE;
else if (!strcmp (option, "single-imm-size"))
debug_options.single_imm_size = TRUE;
else if (!strcmp (option, "init-stacks"))
if (!mini_parse_debug_option (arg)) {
fprintf (stderr, "Invalid option for the MONO_DEBUG env variable: %s\n", arg);
- fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'gen-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n");
+ fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'no-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n");
exit (1);
}
}
mono_simd_intrinsics_init ();
#endif
-#if MONO_SUPPORT_TASKLETS
mono_tasklets_init ();
-#endif
register_trampolines (domain);
mono_create_handler_block_trampoline (void)
{
static gpointer code;
- if (code) {
+
+ if (code)
+ return code;
+
+ if (mono_aot_only) {
+ gpointer tmp = mono_aot_get_trampoline ("handler_block_trampoline");
+ g_assert (tmp);
mono_memory_barrier ();
+ code = tmp;
return code;
}
- g_assert (!mono_aot_only);
-
mono_trampolines_lock ();
-
if (!code) {
MonoTrampInfo *info;
gpointer tmp;
mono_error_init (error);
if (mono_aot_only) {
+ if (mono_llvm_only && method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ method = mono_marshal_get_synchronized_wrapper (method);
+
/* Avoid creating trampolines if possible */
gpointer code = mono_jit_find_compiled_method (domain, method);
x86_jump_membase (code, X86_EAX, offset);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
- if (load_imt_reg)
- tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", - offset / sizeof (gpointer));
- else
- tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", offset / sizeof (gpointer));
+ tramp_name = mono_get_delegate_virtual_invoke_impl_name (load_imt_reg, offset);
*info = mono_tramp_info_create (tramp_name, start, code - start, NULL, unwind_ops);
g_free (tramp_name);
vars = g_list_prepend (vars, vmv);
}
- vars = g_list_sort (g_list_copy (vars), compare_by_interval_start_pos_func);
+ vars = g_list_sort (vars, compare_by_interval_start_pos_func);
/* Sanity check */
/*
mono_verify_bblock (bb);
}
+// This will free many fields in cfg to save
+// memory. Note that this must be safe to call
+// multiple times. It must be idempotent.
+void
+mono_empty_compile (MonoCompile *cfg)
+{
+ mono_free_loop_info (cfg);
+
+ // These live in the mempool, and so must be freed
+ // first
+ for (GSList *l = cfg->headers_to_free; l; l = l->next) {
+ mono_metadata_free_mh ((MonoMethodHeader *)l->data);
+ }
+ cfg->headers_to_free = NULL;
+
+ if (cfg->mempool) {
+ //mono_mempool_stats (cfg->mempool);
+ mono_mempool_destroy (cfg->mempool);
+ cfg->mempool = NULL;
+ }
+
+ g_free (cfg->varinfo);
+ cfg->varinfo = NULL;
+
+ g_free (cfg->vars);
+ cfg->vars = NULL;
+
+ if (cfg->rs) {
+ mono_regstate_free (cfg->rs);
+ cfg->rs = NULL;
+ }
+}
+
void
mono_destroy_compile (MonoCompile *cfg)
{
- GSList *l;
+ mono_empty_compile (cfg);
if (cfg->header)
mono_metadata_free_mh (cfg->header);
- //mono_mempool_stats (cfg->mempool);
- mono_free_loop_info (cfg);
- if (cfg->rs)
- mono_regstate_free (cfg->rs);
+
if (cfg->spvars)
g_hash_table_destroy (cfg->spvars);
if (cfg->exvars)
g_hash_table_destroy (cfg->exvars);
- for (l = cfg->headers_to_free; l; l = l->next)
- mono_metadata_free_mh ((MonoMethodHeader *)l->data);
+
g_list_free (cfg->ldstr_list);
- g_hash_table_destroy (cfg->token_info_hash);
+
+ if (cfg->token_info_hash)
+ g_hash_table_destroy (cfg->token_info_hash);
+
if (cfg->abs_patches)
g_hash_table_destroy (cfg->abs_patches);
- mono_mempool_destroy (cfg->mempool);
mono_debug_free_method (cfg);
cfg->disable_omit_fp = debug_options.disable_omit_fp;
cfg->skip_visibility = method->skip_visibility;
cfg->orig_method = method;
- cfg->gen_seq_points = debug_options.gen_seq_points_compact_data || debug_options.gen_sdb_seq_points;
+ cfg->gen_seq_points = !debug_options.no_seq_points_compact_data || debug_options.gen_sdb_seq_points;
cfg->gen_sdb_seq_points = debug_options.gen_sdb_seq_points;
cfg->llvm_only = (flags & JIT_FLAG_LLVM_ONLY) != 0;
cfg->backend = current_backend;
//g_free (nm);
}
if (cfg->llvm_only) {
+ g_free (cfg->exception_message);
cfg->disable_aot = TRUE;
return cfg;
}
guint32 trampoline_size [MONO_AOT_TRAMP_NUM];
/* The offset where the trampolines begin on a trampoline page */
guint32 tramp_page_code_offsets [MONO_AOT_TRAMP_NUM];
+ /* GUID of aot compilation */
+ guint8 aotid[16];
} MonoAotFileInfo;
/* Number of symbols in the MonoAotFileInfo structure */
* Next sequence points and flags are required by the debugger agent.
*/
gboolean gen_sdb_seq_points;
- gboolean gen_seq_points_compact_data;
+ gboolean no_seq_points_compact_data;
/*
* Setting single_imm_size should guarantee that each time managed code is compiled
* the same instructions and registers are used, regardless of the size of used values.
void mono_create_jump_table (MonoCompile *cfg, MonoInst *label, MonoBasicBlock **bbs, int num_blocks);
MonoCompile *mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFlags flags, int parts, int aot_method_index);
void mono_destroy_compile (MonoCompile *cfg);
+void mono_empty_compile (MonoCompile *cfg);
MonoJitICallInfo *mono_find_jit_opcode_emulation (int opcode);
void mono_print_ins_index (int i, MonoInst *ins);
void mono_print_ins (MonoInst *ins);
/* Delegates */
gpointer mini_get_delegate_arg (MonoMethod *method, gpointer method_ptr);
void mini_init_delegate (MonoDelegate *del);
+char* mono_get_delegate_virtual_invoke_impl_name (gboolean load_imt_reg, int offset);
gpointer mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method);
/* methods that must be provided by the arch-specific port */
mono_tasklets_cleanup (void)
{
}
+#else
+static
+void continuations_not_supported (void)
+{
+ mono_set_pending_exception (mono_get_exception_not_implemented ("Tasklets are not implemented on this platform."));
+}
+
+static void*
+continuation_alloc (void)
+{
+ continuations_not_supported ();
+ return NULL;
+}
+
+static void
+continuation_free (MonoContinuation *cont)
+{
+ continuations_not_supported ();
+}
+
+static MonoException*
+continuation_mark_frame (MonoContinuation *cont)
+{
+ continuations_not_supported ();
+ return NULL;
+}
+
+static int
+continuation_store (MonoContinuation *cont, int state, MonoException **e)
+{
+ continuations_not_supported ();
+ return 0;
+}
+
+static MonoException*
+continuation_restore (MonoContinuation *cont, int state)
+{
+ continuations_not_supported ();
+ return NULL;
+}
+
+void
+mono_tasklets_init(void)
+{
+ mono_add_internal_call ("Mono.Tasklets.Continuation::alloc", continuation_alloc);
+ mono_add_internal_call ("Mono.Tasklets.Continuation::free", continuation_free);
+ mono_add_internal_call ("Mono.Tasklets.Continuation::mark", continuation_mark_frame);
+ mono_add_internal_call ("Mono.Tasklets.Continuation::store", continuation_store);
+ mono_add_internal_call ("Mono.Tasklets.Continuation::restore", continuation_restore);
+
+}
#endif
#!/bin/bash
-TEST_FILE=$1
-USE_AOT=$2
+DEFAULT_PROFILE=$1
+TEST_FILE=$2
+USE_AOT=$3
TMP_FILE_PREFIX=$(basename $0).tmp
BASEDIR=$(dirname $0)
*) PLATFORM_PATH_SEPARATOR=':';;
esac
-MONO_PATH=$BASEDIR/../../mcs/class/lib/net_4_x$PLATFORM_PATH_SEPARATOR$BASEDIR
+MONO_PATH=$BASEDIR/../../mcs/class/lib/$DEFAULT_PROFILE$PLATFORM_PATH_SEPARATOR$BASEDIR
RUNTIME=$BASEDIR/../../runtime/mono-wrapper
trap "rm -rf ${TMP_FILE_PREFIX}*" EXIT
diff_methods () {
TMP_FILE1=$(tmp_file)
TMP_FILE2=$(tmp_file)
- echo "$(MONO_DEBUG=single-imm-size get_methods $1 $2 $3 $4)" >$TMP_FILE1
- echo "$(MONO_DEBUG=gen-compact-seq-points,single-imm-size get_methods $1 $2 $3 $4)" >$TMP_FILE2
+ echo "$(MONO_DEBUG=no-compact-seq-points,single-imm-size get_methods $1 $2 $3 $4)" >$TMP_FILE1
+ echo "$(MONO_DEBUG=single-imm-size get_methods $1 $2 $3 $4)" >$TMP_FILE2
diff $TMP_FILE1 $TMP_FILE2
}
diff_method () {
TMP_FILE1=$(tmp_file)
TMP_FILE2=$(tmp_file)
- echo "$(MONO_DEBUG=single-imm-size get_method $1 $2 $3 $4 $5)" >$TMP_FILE1
- echo "$(MONO_DEBUG=gen-compact-seq-points,single-imm-size get_method $1 $2 $3 $4 $5 | grep -Ev il_seq_point)" >$TMP_FILE2
+ echo "$(MONO_DEBUG=no-compact-seq-points,single-imm-size get_method $1 $2 $3 $4 $5)" >$TMP_FILE1
+ echo "$(MONO_DEBUG=single-imm-size get_method $1 $2 $3 $4 $5 | grep -Ev il_seq_point)" >$TMP_FILE2
sdiff -w 150 $TMP_FILE1 $TMP_FILE2
}
amd64_call_reg (code, AMD64_R11);
}
-
-static void
-handler_block_trampoline_helper (gpointer *ptr)
+gpointer
+mono_amd64_handler_block_trampoline_helper (void)
{
MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
- *ptr = jit_tls->handler_block_return_address;
+ return jit_tls->handler_block_return_address;
}
gpointer
MonoJumpInfo *ji = NULL;
GSList *unwind_ops;
- g_assert (!aot);
-
code = buf = (guint8 *)mono_global_codeman_reserve (tramp_size);
unwind_ops = mono_arch_get_cie_program ();
/*
This trampoline restore the call chain of the handler block then jumps into the code that deals with it.
*/
- if (mono_get_jit_tls_offset () != -1) {
+ if (!aot && mono_get_jit_tls_offset () != -1) {
code = mono_amd64_emit_tls_get (code, MONO_AMD64_ARG_REG1, mono_get_jit_tls_offset ());
amd64_mov_reg_membase (code, MONO_AMD64_ARG_REG1, MONO_AMD64_ARG_REG1, MONO_STRUCT_OFFSET (MonoJitTlsData, handler_block_return_address), 8);
/* Simulate a call */
mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 16);
amd64_jump_code (code, tramp);
} else {
- /*Slow path uses a c helper*/
- amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, AMD64_RSP, 8);
- amd64_mov_reg_imm (code, AMD64_RAX, tramp);
- amd64_push_reg (code, AMD64_RAX);
- mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 16);
+ /*
+ * We get here from the ret emitted by CEE_ENDFINALLY.
+ * The stack is misaligned.
+ */
+ /* Align the stack before the call */
+ amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 8);
+ if (aot) {
+ code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_amd64_handler_block_trampoline_helper");
+ amd64_call_reg (code, AMD64_R11);
+ } else {
+ amd64_call_code (code, mono_amd64_handler_block_trampoline_helper);
+ }
+ /* Undo stack alignment */
+ amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 8);
+ /* Save the result to the stack */
amd64_push_reg (code, AMD64_RAX);
- mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 24);
- amd64_jump_code (code, handler_block_trampoline_helper);
+ if (aot) {
+ char *name = g_strdup_printf ("trampoline_func_%d", MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD);
+ code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, name);
+ amd64_mov_reg_reg (code, AMD64_RAX, AMD64_R11, 8);
+ } else {
+ amd64_mov_reg_imm (code, AMD64_RAX, tramp);
+ }
+ /* The stack is aligned */
+ amd64_call_reg (code, AMD64_RAX);
+ /* Load return address */
+ amd64_pop_reg (code, AMD64_RAX);
+ /* The stack is misaligned, thats what the code we branch to expects */
+ amd64_jump_reg (code, AMD64_RAX);
}
mono_arch_flush_icache (buf, code - buf);
while (op->when > loc) {
if (op->when - loc > 65536) {
*p ++ = DW_CFA_advance_loc4;
- *(guint32*)p = (guint32)(op->when - loc);
+ guint32 v = (guint32)(op->when - loc);
+ memcpy (p, &v, 4);
g_assert (read32 (p) == (guint32)(op->when - loc));
p += 4;
loc = op->when;
} else if (op->when - loc > 256) {
*p ++ = DW_CFA_advance_loc2;
- *(guint16*)p = (guint16)(op->when - loc);
+ guint16 v = (guint16)(op->when - loc);
+ memcpy (p, &v, 2);
g_assert (read16 (p) == (guint32)(op->when - loc));
p += 2;
loc = op->when;
}
/* LOCKING: requires that the GC lock is held */
-static int
-finalizers_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, GCObject **out_array, int out_size, SgenHashTable *hash_table)
+static void
+finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, volatile gboolean *suspend, SgenHashTable *hash_table)
{
GCObject *object;
gpointer dummy G_GNUC_UNUSED;
- int count;
- if (no_finalize || !out_size || !out_array)
- return 0;
- count = 0;
+ if (no_finalize)
+ return;
SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
object = tagged_object_get_object (object);
if (predicate (object, user_data)) {
/* remove and put in out_array */
SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);
- out_array [count ++] = object;
- SGEN_LOG (5, "Collecting object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table));
- if (count == out_size)
- return count;
- continue;
+ sgen_queue_finalization_entry (object);
+ SGEN_LOG (5, "Enqueuing object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table));
}
+
+ if (*suspend)
+ break;
} SGEN_HASH_TABLE_FOREACH_END;
- return count;
}
/**
* @out_array me be on the stack, or registered as a root, to allow the GC to know the
* objects are still alive.
*/
-int
-sgen_gather_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, GCObject **out_array, int out_size)
+void
+sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data, volatile gboolean *suspend)
{
- int result;
-
LOCK_GC;
sgen_process_fin_stage_entries ();
- result = finalizers_with_predicate (predicate, user_data, (GCObject**)out_array, out_size, &minor_finalizable_hash);
- if (result < out_size) {
- result += finalizers_with_predicate (predicate, user_data, (GCObject**)out_array + result, out_size - result,
- &major_finalizable_hash);
- }
+ finalize_with_predicate (predicate, user_data, suspend, &minor_finalizable_hash);
+ finalize_with_predicate (predicate, user_data, suspend, &major_finalizable_hash);
UNLOCK_GC;
-
- return result;
}
void
sgen_register_root (NULL, 0, sgen_make_user_root_descriptor (sgen_mark_normal_gc_handles), ROOT_TYPE_NORMAL, MONO_ROOT_SOURCE_GC_HANDLE, "normal gc handles");
gc_initialized = 1;
+
+ sgen_init_bridge ();
+}
+
+gboolean
+sgen_gc_initialized ()
+{
+ return gc_initialized > 0;
}
NurseryClearPolicy
List of what each bit on of the vtable gc bits means.
*/
enum {
+ // When the Java bridge has determined an object is "bridged", it uses these two bits to cache that information.
SGEN_GC_BIT_BRIDGE_OBJECT = 1,
SGEN_GC_BIT_BRIDGE_OPAQUE_OBJECT = 2,
SGEN_GC_BIT_FINALIZER_AWARE = 4,
void sgen_conservatively_pin_objects_from (void **start, void **end, void *start_nursery, void *end_nursery, int pin_type);
+gboolean sgen_gc_initialized (void);
+
/* Keep in sync with description_for_type() in sgen-internal.c! */
enum {
INTERNAL_MEM_PIN_QUEUE,
gboolean sgen_have_pending_finalizers (void);
void sgen_object_register_for_finalization (GCObject *obj, void *user_data);
-int sgen_gather_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, GCObject **out_array, int out_size);
+void sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data, volatile gboolean *suspend);
void sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, int generation);
void sgen_register_disappearing_link (GCObject *obj, void **link, gboolean track, gboolean in_gc);
if (fixed_type_allocator_indexes [type] == -1)
fixed_type_allocator_indexes [type] = slot;
- else
- g_assert (fixed_type_allocator_indexes [type] == slot);
+ else {
+ if (fixed_type_allocator_indexes [type] != slot)
+ g_error ("Invalid double registration of type %d old slot %d new slot %d", type, fixed_type_allocator_indexes [type], slot);
+ }
}
static const char*
}
done:
+ /*
+ * Once the block is written back without the checking bit other threads are
+ * free to access it. Make sure the block state is visible before we write it
+ * back.
+ */
+ mono_memory_write_barrier ();
*block_slot = tagged_block;
return !!tagged_block;
}
SUBDIRS = assemblyresolve gc-descriptors
+if INSTALL_MOBILE_STATIC
+FEATUREFUL_RUNTIME_TEST =
+else
+FEATUREFUL_RUNTIME_TEST = test-appdomain-unload
+endif
+
check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform \
- test-console-output test-messages test-env-options test-unhandled-exception-2 test-appdomain-unload test-process-stress rm-empty-logs
+ test-console-output test-messages test-env-options test-unhandled-exception-2 $(FEATUREFUL_RUNTIME_TEST) test-process-stress rm-empty-logs
check-full: test-sgen check-local
check-parallel: compile-tests check-full
TEST_RUNNER_ARGS=--config tests-config --runtime $(if $(MONO_EXECUTABLE),$(MONO_EXECUTABLE),mono)
endif
+TEST_RUNNER_ARGS += $(if $(V), --verbose,)
+
CLASS=$(mcs_topdir)/class/lib/$(DEFAULT_PROFILE)
with_mono_path = MONO_PATH=$(CLASS)
PKG_CONFIG_PATH=$(top_builddir):$(PKG_CONFIG_PATH) \
$(RUNTIME) $(CLASS)/mkbundle.exe
+if INSTALL_MOBILE_STATIC
+PROFILE_MCS_FLAGS = -d:MOBILE,MOBILE_STATIC,MOBILE_LEGACY
+endif
+
MCS_NO_LIB = $(RUNTIME) $(mcs_topdir)/class/lib/build/mcs.exe -unsafe -debug \
-noconfig -nologo \
-nowarn:0162 -nowarn:0168 -nowarn:0219 -nowarn:0414 -nowarn:0618 \
-nowarn:0169 -nowarn:1690 -nowarn:0649 -nowarn:0612 -nowarn:3021 \
- -nowarn:0197
+ -nowarn:0197 $(PROFILE_MCS_FLAGS)
MCS = $(MCS_NO_LIB) -lib:$(CLASS)
ILASM = $(RUNTIME) $(CLASS)/ilasm.exe
+if INSTALL_MOBILE_STATIC
+TEST_RUNNER = ./test-runner.exe --runtime $(top_builddir)/runtime/mono-wrapper --mono-path "$(CLASS)" --aot-run-flags "$(AOT_RUN_FLAGS)" --aot-build-flags "$(AOT_BUILD_FLAGS)"
+else
+TEST_RUNNER = ./test-runner.exe --runtime $(top_builddir)/runtime/mono-wrapper --mono-path "$(CLASS)"
+endif
+
+
BENCHSRC=fib.cs random.cs nested-loops.cs ackermann.cs tight-loop.cs sieve.cs
STRESS_TESTS_SRC= \
process-stress.cs \
assembly-load-stress.cs
+BASE_TEST_MOBILE_STATIC_NOT_SUPPORTED= \
+ remoting4.cs # Needs remoting support \
+ remoting1.cs # Needs remoting support \
+ remoting2.cs # Needs remoting support \
+ remoting3.cs # Needs remoting support \
+ remoting5.cs # Needs remoting support \
+ appdomain.cs # Needs appdomain support \
+ appdomain-client.cs # Needs appdomain support \
+ appdomain-unload.cs # Needs appdomain support \
+ appdomain-async-invoke.cs # Needs appdomain support \
+ appdomain-thread-abort.cs # Needs appdomain support \
+ appdomain1.cs # Needs appdomain support \
+ appdomain2.cs # Needs appdomain support \
+ appdomain-exit.cs # Needs appdomain support \
+ assemblyresolve_event2.2.cs # Needs appdomain support \
+ appdomain-unload-callback.cs # Needs appdomain support \
+ appdomain-unload-doesnot-raise-pending-events.cs # Needs appdomain support \
+ unload-appdomain-on-shutdown.cs # Needs appdomain support \
+ bug-47295.cs # Needs SRE \
+ loader.cs # Needs SRE \
+ pinvoke2.cs # Needs SRE \
+ generic-type-builder.2.cs # Needs SRE \
+ dynamic-generic-size.cs # Needs SRE \
+ cominterop.cs # Needs COM \
+ dynamic-method-access.2.cs # Need SRE \
+ dynamic-method-finalize.2.cs # Need SRE \
+ dynamic-method-stack-traces.cs # Need SRE\
+ generic_type_definition.2.cs # Need SRE \
+ bug-333798-tb.2.cs # Need SRE \
+ bug-335131.2.cs # Need SRE \
+ bug-322722_patch_bx.2.cs # Need SRE\
+ bug-322722_dyn_method_throw.2.cs # Need SRE \
+ bug-389886-2.cs # Need SRE \
+ bug-349190.2.cs # Need SRE \
+ bug-389886-sre-generic-interface-instances.cs # Need SRE \
+ bug-462592.cs # Need SRE \
+ bug-575941.cs # Need SRE \
+ bug-389886-3.cs # Need SRE \
+ dynamic-method-resurrection.cs # Need SRE \
+ bug-80307.cs # Need System.Web \
+ assembly_append_ordering.cs # Need SRE \
+ bug-544446.cs # Needs AppDomains / TranparentProxy \
+ bug-36848.cs # Needs AppDomains / TranparentProxy \
+ generic-marshalbyref.2.cs # Needs AppDomains \
+ stackframes-async.2.cs # Needs AppDomains \
+ transparentproxy.cs # Needs AppDomains / TranparentProxy \
+ bug-48015.cs # Needs AppDomains / TranparentProxy \
+ delegate9.cs # Needs AppDomains \
+ marshal-valuetypes.cs # Needs AppDomains \
+ xdomain-threads.cs # Needs AppDomains \
+ monitor.cs # Needs AppDomains \
+ generic-xdomain.2.cs # Needs AppDomains \
+ threadpool-exceptions7.cs # Needs AppDomains \
+ cross-domain.cs # Needs AppDomains \
+ generic-unloading.2.cs # Needs AppDomains \
+ thread6.cs # On MOBILE, ThreadAbortException doesn't have necessary field for this test
+
# Disabled until ?mcs is fixed
# bug-331958.cs
-BASE_TEST_CS_SRC= \
+BASE_TEST_CS_SRC_UNIVERSAL= \
+ generic-unloading-sub.2.cs \
+ create-instance.cs \
bug-2907.cs \
array-init.cs \
arraylist.cs \
assemblyresolve_event4.cs \
checked.cs \
char-isnumber.cs \
- create-instance.cs \
field-layout.cs \
pack-layout.cs \
pack-bug.cs \
typeof-ptr.cs \
static-constructor.cs \
pinvoke.cs \
- pinvoke2.cs \
pinvoke3.cs \
pinvoke11.cs \
pinvoke13.cs \
jit-float.cs \
pop.cs \
time.cs \
- appdomain.cs \
- appdomain1.cs \
- appdomain2.cs \
- appdomain-client.cs \
- appdomain-unload.cs \
- appdomain-async-invoke.cs \
- loader.cs \
pointer.cs \
hashcode.cs \
delegate1.cs \
delegate6.cs \
delegate7.cs \
delegate8.cs \
- delegate9.cs \
delegate10.cs \
delegate11.cs \
delegate12.cs \
delegate13.cs \
- remoting1.cs \
- remoting2.cs \
- remoting3.cs \
- remoting4.cs \
- remoting5.cs \
largeexp.cs \
largeexp2.cs \
marshalbyref1.cs \
marshal8.cs \
marshal9.cs \
marshalbool.cs \
- marshal-valuetypes.cs \
test-byval-in-struct.cs \
thread.cs \
thread5.cs \
- thread6.cs \
thread-static.cs \
thread-static-init.cs \
context-static.cs \
threadpool-exceptions4.cs \
threadpool-exceptions5.cs \
threadpool-exceptions6.cs \
- threadpool-exceptions7.cs \
base-definition.cs \
bug-27420.cs \
- bug-47295.cs \
bug-46781.cs \
- bug-48015.cs \
bug-42136.cs \
bug-59286.cs \
bug-70561.cs \
bug-323114.cs \
bug-Xamarin-5278.cs \
interlocked.cs \
- cross-domain.cs \
- appdomain-exit.cs \
delegate-async-exit.cs \
delegate-delegate-exit.cs \
delegate-exit.cs \
main-returns.cs \
subthread-exit.cs \
desweak.cs \
- cominterop.cs \
exists.cs \
handleref.cs \
- transparentproxy.cs \
dbnull-missing.cs \
test-type-ctor.cs \
soft-float-tests.cs \
thread-exit.cs \
finalize-parent.cs \
- assemblyresolve_event2.2.cs \
interlocked-2.2.cs \
pinvoke-2.2.cs \
bug-78431.2.cs \
catch-generics.2.cs \
event-get.2.cs \
safehandle.2.cs \
- stackframes-async.2.cs \
module-cctor-loader.2.cs \
generics-invoke-byref.2.cs \
generic-signature-compare.2.cs \
generic-virtual2.2.cs \
generic-valuetype-interface.2.cs \
generic-getgenericarguments.2.cs \
- generic-type-builder.2.cs \
generic-synchronized.2.cs \
generic-delegate-ctor.2.cs \
generic-array-iface-set.2.cs \
generic-typedef.2.cs \
- generic-marshalbyref.2.cs \
- generic-xdomain.2.cs \
- dynamic-generic-size.cs \
bug-431413.2.cs \
bug-459285.2.cs \
generic-virtual-invoke.2.cs \
bug-479763.2.cs \
bug-616463.cs \
bug-80392.2.cs \
- dynamic-method-access.2.cs \
- dynamic-method-finalize.2.cs \
- dynamic-method-stack-traces.cs \
bug-82194.2.cs \
anonarray.2.cs \
ienumerator-interfaces.2.cs \
array-enumerator-ifaces.2.cs \
generic_type_definition_encoding.2.cs \
- generic_type_definition.2.cs \
bug-333798.2.cs \
- bug-333798-tb.2.cs \
- bug-335131.2.cs \
- bug-322722_patch_bx.2.cs \
bug-348522.2.cs \
bug-340662_bug.cs \
- bug-322722_dyn_method_throw.2.cs \
- bug-389886-2.cs \
bug-325283.2.cs \
thunks.cs \
winx64structs.cs \
- bug-349190.2.cs \
nullable_boxing.2.cs \
valuetype-equals.cs \
custom-modifiers.2.cs \
bug-324535.cs \
modules.cs \
bug-81673.cs \
- bug-36848.cs \
bug-81691.cs \
- bug-80307.cs \
bug-415577.cs \
filter-stack.cs \
vararg2.cs \
- bug-389886-sre-generic-interface-instances.cs \
bug-461867.cs \
bug-461941.cs \
bug-461261.cs \
bug-400716.cs \
- bug-462592.cs \
bug-459094.cs \
- generic-unloading.2.cs \
- generic-unloading-sub.2.cs \
bug-467456.cs \
- appdomain-unload-callback.cs \
bug-508538.cs \
bug-472692.2.cs \
gchandles.cs \
interlocked-3.cs \
interlocked-4.2.cs \
- appdomain-thread-abort.cs \
- xdomain-threads.cs \
w32message.cs \
- bug-544446.cs \
gc-altstack.cs \
large-gc-bitmap.cs \
bug-561239.cs \
bug-562150.cs \
- bug-575941.cs \
bug-599469.cs \
- bug-389886-3.cs \
- monitor.cs \
monitor-resurrection.cs \
monitor-wait-abort.cs \
monitor-abort.cs \
- dynamic-method-resurrection.cs \
bug-666008.cs \
bug-685908.cs \
sgen-long-vtype.cs \
bug-bxc-795.cs \
bug-3903.cs \
async-with-cb-throws.cs \
- appdomain-unload-doesnot-raise-pending-events.cs \
bug-6148.cs \
- assembly_append_ordering.cs \
bug-10127.cs \
bug-18026.cs \
allow-synchronous-major.cs \
- unload-appdomain-on-shutdown.cs \
block_guard_restore_aligment_on_exit.cs \
thread_static_gc_layout.cs \
sleep.cs \
bug-29585.cs \
priority.cs
+if INSTALL_MOBILE_STATIC
+BASE_TEST_CS_SRC= \
+ $(BASE_TEST_CS_SRC_UNIVERSAL)
+else
+BASE_TEST_CS_SRC= \
+ $(BASE_TEST_MOBILE_STATIC_NOT_SUPPORTED) \
+ $(BASE_TEST_CS_SRC_UNIVERSAL)
+endif
+
TEST_CS_SRC_DIST= \
$(BASE_TEST_CS_SRC) \
async-exc-compilation.cs \
COOP_DISABLED_TESTS=
endif
+if INSTALL_MOBILE_STATIC
+# Tests which rely on TypeLoadExceptions
+# In full-aot mode, these cause the relevant methods to be not AOTed.
+PROFILE_DISABLED_TESTS = \
+ typeload-unaligned.exe \
+ field-access.exe \
+ invalid_generic_instantiation.exe \
+ bug-481403.exe \
+ array_ldelema.exe \
+ array_load_exception.exe \
+ bug445361.exe \
+ generic-type-load-exception.2.exe \
+ invalid-token.exe \
+ call_missing_method.exe \
+ call_missing_class.exe \
+ ldfld_missing_field.exe \
+ ldfld_missing_class.exe \
+ vt-sync-method.exe
+
+# Tests which rely on remoting
+PROFILE_DISABLED_TESTS += \
+ context-static.exe \
+ bug-415577.exe \
+ generic-marshalbyref.2.exe \
+ unhandled-exception-7.exe
+
+# Tests which use unsupported pinvoke+full aot
+# functionality
+PROFILE_DISABLED_TESTS += \
+ marshal.exe \
+ marshal2.exe \
+ marshal6.exe \
+ marshal7.exe \
+ marshal8.exe \
+ pinvoke-2.2.exe \
+ pinvoke3.exe \
+ thunks.exe
+
+# Tests which load assemblies which are not
+# in the mobile_static profile
+PROFILE_DISABLED_TESTS += \
+ assembly-load-remap.exe
+else
+PROFILE_DISABLED_TESTS=
+endif
+
# The two finalizer tests only work under sgen
# gc-altstack.exe fails under boehm because it has no support for altstack
# bug-459094.exe creates an extremely deep directory tree
bug-Xamarin-5278.exe \
$(PLATFORM_DISABLED_TESTS) \
$(EXTRA_DISABLED_TESTS) \
- $(COOP_DISABLED_TESTS)
+ $(COOP_DISABLED_TESTS) \
+ $(PROFILE_DISABLED_TESTS)
DISABLED_TESTS_WRENCH= \
$(DISABLED_TESTS) \
TEST_CSC_SRC= \
vararg.cs
-TEST_IL_SRC= \
+# constraints-load.il:
+# Failed to load method 0x6000007 from '..../mono/tests/constraints-load.exe' due to
+# Could not resolve type with token 01000002 assembly:mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 type:System.BrokenIComparable`1 member:<none>.
+IL_SRC_MOBILE_STATIC_NOT_SUPPORTED= \
+ constraints-load.il \
+ bug-515884.il
+
+TEST_IL_SRC_UNIVERSAL= \
field-access.il \
method-access.il \
ldftn-access.il \
bug-463303.il \
bug469742.2.il \
bug-528055.il \
- constraints-load.il \
array_load_exception.il \
bug-481403.il \
interface-with-static-method.il \
- bug-515884.il \
bug-633291.il \
delegate-with-null-target.il \
bug-318677.il \
gsharing-valuetype-layout.il \
invalid_generic_instantiation.il
+if INSTALL_MOBILE_STATIC
+TEST_IL_SRC= \
+ $(TEST_IL_SRC_UNIVERSAL)
+else
+TEST_IL_SRC= \
+ $(TEST_IL_SRC_MOBILE_STATIC_NOT_SUPPORTED) \
+ $(TEST_IL_SRC_UNIVERSAL)
+endif
# pre-requisite test sources: files that are not test themselves
# but that need to be compiled
TESTBS=$(BENCHSRC:.cs=.exe)
STRESS_TESTS=$(STRESS_TESTS_SRC:.cs=.exe)
+PREREQSI_IL_AOT=$(PREREQ_IL_SRC:.il=.exe$(PLATFORM_AOT_SUFFIX))
+PREREQSI_CS_AOT=$(PREREQ_CS_SRC:.cs=.exe$(PLATFORM_AOT_SUFFIX))
+
EXTRA_DIST=test-driver test-runner.cs $(TEST_CS_SRC_DIST) $(TEST_IL_SRC) \
$(BENCHSRC) $(STRESS_TESTS_SRC) stress-runner.pl $(PREREQ_IL_SRC) $(PREREQ_CS_SRC)
%.exe: %.il
$(ILASM) -out:$@ $<
-%.exe: %.cs TestDriver.dll
- $(MCS) -r:System.dll -r:System.Xml.dll -r:System.Core.dll -r:TestDriver.dll -r:Mono.Posix.dll -out:$@ $<
+if !INSTALL_MOBILE_STATIC
+TEST_DRIVER_HARD_KILL_FEATURE=-r:Mono.Posix.dll
+endif
+
+if INSTALL_MOBILE_STATIC
+TEST_DRIVER_DEPEND=TestDriver.dll$(PLATFORM_AOT_SUFFIX)
+else
+TEST_DRIVER_DEPEND=TestDriver.dll
+endif
+
+%.exe: %.cs $(TEST_DRIVER_DEPEND)
+ $(MCS) -r:System.dll -r:System.Xml.dll -r:System.Core.dll -r:TestDriver.dll $(TEST_DRIVER_HARD_KILL_FEATURE) -out:$@ $<
+
+%.exe$(PLATFORM_AOT_SUFFIX): %.exe
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $<
+
+%.dll$(PLATFORM_AOT_SUFFIX): %.dll
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $<
# mkbundle works on ppc, but the pkg-config POC doesn't when run with make test
if POWERPC
endif
endif
+AOT_EXTRA_LIBS = \
+bug-382986-lib.dll$(PLATFORM_AOT_SUFFIX) \
+bug-324535-il.dll$(PLATFORM_AOT_SUFFIX) \
+bug-36848-a.dll$(PLATFORM_AOT_SUFFIX) \
+bug-81691-b.dll$(PLATFORM_AOT_SUFFIX) \
+bug-327438.2.exe$(PLATFORM_AOT_SUFFIX) \
+bug-81466-lib.dll$(PLATFORM_AOT_SUFFIX)
+
+if INSTALL_MOBILE_STATIC
+prereqs: $(PREREQSI_IL_AOT) $(PREREQSI_CS_AOT) $(AOT_EXTRA_LIBS)
+else
+prereqs: $(PREREQSI_IL) $(PREREQSI_CS)
+endif
+
# Target to precompile the test executables
-tests: $(TESTSI_CS) $(TESTSI_IL) $(TESTBS) libtest.la $(PREREQSI_IL) $(PREREQSI_CS) $(GSHARED_TESTS)
+tests: $(TESTSI_CS) $(TESTSI_IL) $(TESTBS) libtest.la prereqs $(GSHARED_TESTS)
#
# Test that no symbols are missed in eglib-remap.h
# Precompile the test assemblies in parallel
compile-tests:
$(MAKE) -j4 $(TESTSI_CS) $(TESTSI_IL) $(TESTBS) libtest.la $(PREREQSI_IL) $(PREREQSI_CS)
+if INSTALL_MOBILE_STATIC
+ $(MAKE) $(PREREQSI_IL_AOT) $(PREREQSI_CS_AOT) $(AOT_EXTRA_LIBS)
+endif
# Remove empty .stdout and .stderr files for wrench
rm-empty-logs:
$(MAKE) -C assemblyresolve prereq
TestDriver.dll:
- $(MCS) -target:library -out:$@ $(srcdir)/../mini/TestDriver.cs
+ $(MCS) -target:library -out:$@ $(srcdir)/../mini/TestDriver.cs $(srcdir)/../mini/TestHelpers.cs
test_cs: $(TEST_PROG) $(TESTSI_CS) libtest.la
@failed=0; \
runtest-managed: test-runner.exe $(TESTSI_CS) $(TESTSI_IL) $(TESTBS) libtest.la $(PREREQSI_IL) $(PREREQSI_CS)
@if [ "x$$CI" = "x1" ]; then disabled_tests="$(DISABLED_TESTS_WRENCH)"; else disabled_tests="$(DISABLED_TESTS)"; fi; \
- $(RUNTIME) --debug ./test-runner.exe $(TEST_RUNNER_ARGS) -j a --testsuite-name "runtime" --timeout 300 --disabled "$${disabled_tests}" $(TESTSI_CS) $(TESTBS) $(TESTSI_IL)
+ $(RUNTIME) --debug $(TEST_RUNNER) $(TEST_RUNNER_ARGS) -j a --testsuite-name "runtime" --timeout 300 --disabled "$${disabled_tests}" $(TESTSI_CS) $(TESTBS) $(TESTSI_IL)
runtest-managed-serial: test-runner.exe $(TESTSI_CS) $(TESTSI_IL) $(TESTBS) libtest.la $(PREREQSI_IL) $(PREREQSI_CS)
@if [ "x$$CI" = "x1" ]; then disabled_tests="$(DISABLED_TESTS_WRENCH)"; else disabled_tests="$(DISABLED_TESTS)"; fi; \
- $(RUNTIME) --debug ./test-runner.exe $(TEST_RUNNER_ARGS) -j 1 --testsuite-name "runtime" --disabled "$${disabled_tests}" $(TESTSI_CS) $(TESTBS) $(TESTSI_IL)
+ $(RUNTIME) --debug $(TEST_RUNNER) $(TEST_RUNNER_ARGS) -j 1 --testsuite-name "runtime" --disabled "$${disabled_tests}" $(TESTSI_CS) $(TESTBS) $(TESTSI_IL)
testjit:
@if test x$(M) != x0; then $(MAKE) runtest-managed; else $(MAKE) runtest; fi
@- rm -rf a.out
EXTRA_DIST += load-missing.il t-missing.cs load-exceptions.cs
-test-type-load: TestDriver.dll
+test-type-load: $(TEST_DRIVER_DEPEND)
@$(ILASM) /dll /output:load-missing.dll $(srcdir)/load-missing.il > /dev/null
@$(MCS) -t:library -out:t.dll -d:FOUND $(srcdir)/t-missing.cs
@$(MCS) -r:TestDriver.dll -r:load-missing.dll -r:t.dll -out:load-exceptions.exe $(srcdir)/load-exceptions.cs
@$(RUNTIME) load-exceptions.exe > load-exceptions.exe.stdout 2> load-exceptions.exe.stderr
EXTRA_DIST += custom-attr-errors.cs custom-attr-errors-lib.cs
-test-cattr-type-load: TestDriver.dll custom-attr-errors.cs custom-attr-errors-lib.cs
+test-cattr-type-load: $(TEST_DRIVER_DEPEND) custom-attr-errors.cs custom-attr-errors-lib.cs
$(MCS) -D:WITH_MEMBERS /t:library $(srcdir)/custom-attr-errors-lib.cs
$(MCS) -r:TestDriver.dll -r:custom-attr-errors-lib.dll $(srcdir)/custom-attr-errors.cs
$(MCS) /t:library $(srcdir)/custom-attr-errors-lib.cs
$(MAKE) sgen-bridge2-tests
endif
-SGEN_REGULAR_TESTS = \
+SGEN_REGULAR_TESTS_MOBILE_STATIC_NOT_SUPPORTED = \
+ sgen-domain-unload.exe \
+ sgen-domain-unload-2.exe
+
+SGEN_REGULAR_TESTS_UNIVERSAL = \
finalizer-wait.exe \
critical-finalizers.exe \
sgen-descriptors.exe \
sgen-gshared-vtype.exe \
- sgen-domain-unload.exe \
- sgen-domain-unload-2.exe \
sgen-weakref-stress.exe \
sgen-cementing-stress.exe \
sgen-case-23400.exe \
gc-graystack-stress.exe \
bug-17590.exe
+if INSTALL_MOBILE_STATIC
+SGEN_REGULAR_TESTS= \
+ $(SGEN_REGULAR_TESTS_UNIVERSAL)
+else
+SGEN_REGULAR_TESTS= \
+ $(SGEN_REGULAR_TESTS_MOBILE_STATIC_NOT_SUPPORTED) \
+ $(SGEN_REGULAR_TESTS_UNIVERSAL)
+endif
+
sgen-regular-tests: $(SGEN_REGULAR_TESTS)
$(MAKE) sgen-regular-tests-plain
$(MAKE) sgen-regular-tests-ms-conc
$(MAKE) sgen-regular-tests-ms-split-clear-at-gc
sgen-regular-tests-plain: $(SGEN_REGULAR_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
sgen-regular-tests-ms-conc: $(SGEN_REGULAR_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
sgen-regular-tests-ms-conc-split: $(SGEN_REGULAR_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="major=marksweep-conc,minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="major=marksweep-conc,minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
sgen-regular-tests-ms-split: $(SGEN_REGULAR_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
sgen-regular-tests-ms-split-95: $(SGEN_REGULAR_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="minor=split,alloc-ratio=95" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="minor=split,alloc-ratio=95" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
sgen-regular-tests-plain-clear-at-gc: $(SGEN_REGULAR_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
sgen-regular-tests-ms-conc-clear-at-gc: $(SGEN_REGULAR_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
sgen-regular-tests-ms-split-clear-at-gc: $(SGEN_REGULAR_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_REGULAR_TESTS)
SGEN_TOGGLEREF_TESTS= \
sgen-toggleref.exe
$(MAKE) sgen-toggleref-tests-ms-split-clear-at-gc
sgen-toggleref-tests-plain: $(SGEN_TOGGLEREF_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
sgen-toggleref-tests-ms-conc: $(SGEN_TOGGLEREF_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test,major=marksweep-conc" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test,major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
sgen-toggleref-tests-ms-conc-split: $(SGEN_TOGGLEREF_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test,major=marksweep-conc,minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test,major=marksweep-conc,minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
sgen-toggleref-tests-ms-split: $(SGEN_TOGGLEREF_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test,minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test,minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
sgen-toggleref-tests-ms-split-95: $(SGEN_TOGGLEREF_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test,minor=split,alloc-ratio=95" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="" MONO_GC_PARAMS="toggleref-test,minor=split,alloc-ratio=95" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
sgen-toggleref-tests-plain-clear-at-gc: $(SGEN_TOGGLEREF_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="toggleref-test" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="toggleref-test" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
sgen-toggleref-tests-ms-conc-clear-at-gc: $(SGEN_TOGGLEREF_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="toggleref-test,major=marksweep-conc" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="toggleref-test,major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
sgen-toggleref-tests-ms-split-clear-at-gc: $(SGEN_TOGGLEREF_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="toggleref-test,minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="clear-at-gc" MONO_GC_PARAMS="toggleref-test,minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_TOGGLEREF_TESTS)
SGEN_BRIDGE_TESTS= \
sgen-bridge.exe \
$(MAKE) sgen-bridge-tests-ms-split-tarjan-bridge
sgen-bridge-tests-plain: $(SGEN_BRIDGE_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
sgen-bridge-tests-ms-conc: $(SGEN_BRIDGE_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
sgen-bridge-tests-ms-split: $(SGEN_BRIDGE_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
sgen-bridge-tests-plain-new-bridge: $(SGEN_BRIDGE_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=new" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=new" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
sgen-bridge-tests-ms-conc-new-bridge: $(SGEN_BRIDGE_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=new,major=marksweep-conc" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=new,major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
sgen-bridge-tests-ms-split-new-bridge: $(SGEN_BRIDGE_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=new,minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=new,minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
sgen-bridge-tests-plain-tarjan-bridge: $(SGEN_BRIDGE_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
sgen-bridge-tests-ms-split-tarjan-bridge: $(SGEN_BRIDGE_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan,minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan,minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE_TESTS)
SGEN_BRIDGE2_TESTS= \
sgen-bridge-xref.exe
$(MAKE) sgen-bridge2-tests-ms-split-tarjan-bridge
sgen-bridge2-tests-plain: $(SGEN_BRIDGE2_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
sgen-bridge2-tests-ms-conc: $(SGEN_BRIDGE2_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
sgen-bridge2-tests-ms-split: $(SGEN_BRIDGE2_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
sgen-bridge2-tests-plain-new-bridge: $(SGEN_BRIDGE2_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=new" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=new" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
sgen-bridge2-tests-ms-conc-new-bridge: $(SGEN_BRIDGE2_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=new,major=marksweep-conc" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=new,major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
sgen-bridge2-tests-ms-split-new-bridge: $(SGEN_BRIDGE2_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=new,minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=new,minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
sgen-bridge2-tests-plain-tarjan-bridge: $(SGEN_BRIDGE2_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
sgen-bridge2-tests-ms-split-tarjan-bridge: $(SGEN_BRIDGE2_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan,minor=split" $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
-
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan,minor=split" $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
SGEN_BRIDGE3_TESTS= \
sgen-bridge-gchandle.exe
$(MAKE) sgen-bridge3-tests-ms-split-tarjan-bridge
sgen-bridge3-tests-plain: $(SGEN_bridge3_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="" $(RUNTIME) $(TEST_RUNNER) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
sgen-bridge3-tests-ms-conc: $(SGEN_BRIDGE3_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
sgen-bridge3-tests-ms-split: $(SGEN_BRIDGE3_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="minor=split" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="minor=split" $(RUNTIME) $(TEST_RUNNER) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
sgen-bridge3-tests-plain-new-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new" $(RUNTIME) $(TEST_RUNNER) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
sgen-bridge3-tests-ms-conc-new-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new,major=marksweep-conc" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new,major=marksweep-conc" $(RUNTIME) $(TEST_RUNNER) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
sgen-bridge3-tests-ms-split-new-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new,minor=split" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new,minor=split" $(RUNTIME) $(TEST_RUNNER) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
sgen-bridge3-tests-plain-tarjan-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan" $(RUNTIME) $(TEST_RUNNER) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
sgen-bridge3-tests-ms-split-tarjan-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
- MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan,minor=split" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan,minor=split" $(RUNTIME) $(TEST_RUNNER) --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
AOT_CONFIGURATIONS= \
# Generated tests for runtime invoke
EXTRA_DIST += gen-runtime-invoke.cs
-runtime-invoke.gen.exe: TestDriver.dll gen-runtime-invoke.exe
+runtime-invoke.gen.exe: $(TEST_DRIVER_DEPEND) gen-runtime-invoke.exe
$(RUNTIME) gen-runtime-invoke.exe > runtime-invoke.gen.cs
$(MCS) -out:runtime-invoke.gen.exe -r:TestDriver.dll runtime-invoke.gen.cs
EXTRA_DIST += make-imt-test.cs
-imt_big_iface_test.exe: TestDriver.dll make-imt-test.exe
+imt_big_iface_test.exe: $(TEST_DRIVER_DEPEND) make-imt-test.exe
$(RUNTIME) make-imt-test.exe > imt_big_iface_test.cs
$(MCS) -out:imt_big_iface_test.exe -r:TestDriver.dll imt_big_iface_test.cs
EXTRA_DIST += test-inline-call-stack-library.cs test-inline-call-stack.cs
-test-inline-call-stack-library.dll: TestDriver.dll $(srcdir)/test-inline-call-stack-library.cs
+test-inline-call-stack-library.dll: $(TEST_DRIVER_DEPEND) $(srcdir)/test-inline-call-stack-library.cs
$(MCS) -t:library -out:test-inline-call-stack-library.dll $(srcdir)/test-inline-call-stack-library.cs
-test-inline-call-stack.exe: TestDriver.dll test-inline-call-stack-library.dll $(srcdir)/test-inline-call-stack.cs
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
+
+test-inline-call-stack.exe: $(TEST_DRIVER_DEPEND) test-inline-call-stack-library.dll $(srcdir)/test-inline-call-stack.cs
$(MCS) -r:TestDriver.dll -r:test-inline-call-stack-library.dll -out:test-inline-call-stack.exe $(srcdir)/test-inline-call-stack.cs
EXTRA_DIST += unhandled-exception-base-configuration.config
$(MCS) -target:library -out:bug-81673-interface.dll $(srcdir)/bug-81673-interface.cs
$(MCS) -out:bug-81673.exe -r:bug-81673-interface.dll $(srcdir)/bug-81673.cs
$(MCS) -define:WITH_STOP -target:library -out:bug-81673-interface.dll $(srcdir)/bug-81673-interface.cs
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
EXTRA_DIST += bug-36848-a.cs
bug-36848.exe bug-36848-a.dll: $(srcdir)/bug-36848.cs $(srcdir)/bug-36848-a.cs
$(MCS) -target:library -out:bug-36848-a.dll $(srcdir)/bug-36848-a.cs
$(MCS) -r:bug-36848-a.dll -out:bug-36848.exe $(srcdir)/bug-36848.cs
$(MCS) -target:library -out:bug-36848-a.dll $(srcdir)/bug-36848-a.cs /define:WITH_STOP
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
EXTRA_DIST += bug-81691-a.cs bug-81691-b.cs
bug-81691.exe bug-81691-b.dll: $(srcdir)/bug-81691.cs $(srcdir)/bug-81691-a.cs $(srcdir)/bug-81691-b.cs
EXTRA_DIST += bug-81466-lib.il
bug-81466-lib.dll: bug-81466-lib.il
$(ILASM) /dll /output:bug-81466-lib.dll $(srcdir)/bug-81466-lib.il
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
bug-81466.exe: bug-81466.il bug-81466-lib.dll
$(ILASM) /exe /output:bug-81466.exe $(srcdir)/bug-81466.il
EXTRA_DIST += bug-324535-il.il
bug-324535-il.dll : bug-324535-il.il
$(ILASM) /dll /output:bug-324535-il.dll $(srcdir)/bug-324535-il.il
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
bug-324535.exe : bug-324535.cs bug-324535-il.dll
$(MCS) -r:bug-324535-il.dll -out:bug-324535.exe $(srcdir)/bug-324535.cs
EXTRA_DIST += custom-modifiers.2.cs custom-modifiers-lib.il
custom-modifiers-lib.dll: custom-modifiers-lib.il
$(ILASM) /dll /output:custom-modifiers-lib.dll $(srcdir)/custom-modifiers-lib.il
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
custom-modifiers.2.exe: custom-modifiers.2.cs custom-modifiers-lib.dll
$(MCS) -r:custom-modifiers-lib.dll -out:custom-modifiers.2.exe $(srcdir)/custom-modifiers.2.cs
EXTRA_DIST += bug-382986-lib.cs
bug-382986-lib.dll: bug-382986-lib.cs
$(MCS) -target:library -out:$@ $(srcdir)/bug-382986-lib.cs
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
+
bug-382986.exe: bug-382986.cs bug-382986-lib.dll
$(MCS) -out:$@ -r:bug-382986-lib.dll $(srcdir)/bug-382986.cs
EXTRA_DIST += generic-unboxing.2.il
generic-unboxing.2.dll : generic-unboxing.2.il
$(ILASM) /dll /output:generic-unboxing.2.dll $(srcdir)/generic-unboxing.2.il
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
EXTRA_DIST += generic-boxing.2.il
generic-boxing.2.dll : generic-boxing.2.il generic-unboxing.2.dll
$(ILASM) /dll /output:generic-boxing.2.dll $(srcdir)/generic-boxing.2.il
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
EXTRA_DIST += generic-unbox.2.cs
generic-unbox.2.exe : generic-unbox.2.cs generic-unboxing.2.dll
EXTRA_DIST += generic-delegate2.2.cs generic-delegate2-lib.2.il
generic-delegate2-lib.2.dll : generic-delegate2-lib.2.il
$(ILASM) /dll /output:$@ $(srcdir)/generic-delegate2-lib.2.il
+if INSTALL_MOBILE_STATIC
+ $(RUNTIME) $(AOT_BUILD_FLAGS) $@
+endif
generic-delegate2.2.exe : generic-delegate2.2.cs generic-delegate2-lib.2.dll
$(MCS) -r:generic-delegate2-lib.2.dll -out:$@ $(srcdir)/generic-delegate2.2.cs
gshared-aot:
@$(MAKE) AOT=1 gshared
-GSHARED_TESTS = \
+GSHARED_TESTS_MOBILE_STATIC_NOT_SUPPORTED = \
+ generic-type-builder.2.exe
+
+GSHARED_TESTS_UNIVERSAL = \
generics-sharing.2.exe shared-generic-methods.2.exe \
shared-generic-synchronized.2.exe generic-initobj.2.exe \
generics-sharing-other-exc.2.exe generic-box.2.exe \
generic-exceptions.2.exe generic-delegate2.2.exe \
generic-virtual2.2.exe generic-valuetype-interface.2.exe \
generic-valuetype-newobj.2.exe generic-valuetype-newobj2.2.exe \
- generic-getgenericarguments.2.exe generic-type-builder.2.exe \
+ generic-getgenericarguments.2.exe \
generic-synchronized.2.exe generic-delegate-ctor.2.exe \
generic-constrained.2.exe bug-431413.2.exe \
generic-virtual-invoke.2.exe generic-typedef.2.exe \
generic-type-load-exception.2.exe bug-616463.exe \
bug-1147.exe
+if INSTALL_MOBILE_STATIC
+GSHARED_TESTS= \
+ $(GSHARED_TESTS_UNIVERSAL)
+else
+GSHARED_TESTS= \
+ $(GSHARED_TESTS_MOBILE_STATIC_NOT_SUPPORTED) \
+ $(GSHARED_TESTS_UNIVERSAL)
+endif
+
test-generic-sharing-normal: $(GSHARED_TESTS)
@for fn in $+ ; do \
echo "Testing $$fn ..."; \
done
test-generic-sharing-managed: test-runner.exe $(GSHARED_TESTS)
- @$(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) -j a --testsuite-name "gshared" --opt-sets "gshared gshared,shared gshared,-inline gshared,-inline,shared" $(GSHARED_TESTS)
+ @$(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) -j a --testsuite-name "gshared" --disabled "$(DISABLED_TESTS)" --opt-sets "gshared gshared,shared gshared,-inline gshared,-inline,shared" $(GSHARED_TESTS)
if NACL_CODEGEN
test-generic-sharing:
EXTRA_DIST += modules.cs modules-m1.cs
modules-m1.netmodule: modules-m1.cs
$(MCS) -out:$@ /target:module $(srcdir)/modules-m1.cs
-modules.exe: modules.cs modules-m1.netmodule TestDriver.dll
+modules.exe: modules.cs modules-m1.netmodule $(TEST_DRIVER_DEPEND)
$(MCS) -out:$@ /addmodule:modules-m1.netmodule -r:TestDriver.dll $(srcdir)/modules.cs
# Useful if mono is compiled with --enable-shared=no
$(MAKE) test-unhandled-exception-2-255-without-managed-handler
test-unhandled-exception-2-1-with-managed-handler: $(UNHANDLED_EXCEPTION_1_TESTS) test-runner.exe
- $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) -j a --testsuite-name $@ --expected-exit-code 1 $(UNHANDLED_EXCEPTION_1_TESTS)
+ $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) -j a --testsuite-name $@ --disabled "$(DISABLED_TESTS)" --expected-exit-code 1 $(UNHANDLED_EXCEPTION_1_TESTS)
test-unhandled-exception-2-1-without-managed-handler: $(UNHANDLED_EXCEPTION_1_TESTS) test-runner.exe
- TEST_UNHANDLED_EXCEPTION_HANDLER=1 $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) -j a --testsuite-name $@ --expected-exit-code 1 $(UNHANDLED_EXCEPTION_1_TESTS)
+ TEST_UNHANDLED_EXCEPTION_HANDLER=1 $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) -j a --testsuite-name $@ --disabled "$(DISABLED_TESTS)" --expected-exit-code 1 $(UNHANDLED_EXCEPTION_1_TESTS)
test-unhandled-exception-2-255-with-managed-handler: $(UNHANDLED_EXCEPTION_255_TESTS) test-runner.exe
- $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) -j a --testsuite-name $@ --expected-exit-code 255 $(UNHANDLED_EXCEPTION_255_TESTS)
+ $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) -j a --testsuite-name $@ --disabled "$(DISABLED_TESTS)" --expected-exit-code 255 $(UNHANDLED_EXCEPTION_255_TESTS)
test-unhandled-exception-2-255-without-managed-handler: $(UNHANDLED_EXCEPTION_255_TESTS) test-runner.exe
- TEST_UNHANDLED_EXCEPTION_HANDLER=1 $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) -j a --testsuite-name $@ --expected-exit-code 255 $(UNHANDLED_EXCEPTION_255_TESTS)
+ TEST_UNHANDLED_EXCEPTION_HANDLER=1 $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) -j a --testsuite-name $@ --disabled "$(DISABLED_TESTS)" --expected-exit-code 255 $(UNHANDLED_EXCEPTION_255_TESTS)
endif
process-leak.exe
test-process-stress: $(PROCESS_STRESS_TESTS) test-runner.exe
- $(RUNTIME) ./test-runner.exe $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 600 $(PROCESS_STRESS_TESTS)
+ $(RUNTIME) $(TEST_RUNNER) $(TEST_RUNNER_ARGS) --testsuite-name $@ --timeout 600 $(PROCESS_STRESS_TESTS)
coreclr-gcstress:
$(MAKE) -C $(mono_build_root)/acceptance-tests coreclr-gcstress
with_mono_path = MONO_PATH=$(CLASS)
-RUNTIME = $(with_mono_path) $(top_builddir)/runtime/mono-wrapper --debug
-MCS = $(RUNTIME) $(mcs_topdir)/class/lib/build/mcs.exe -debug:full -target:library
+RUNTIME = $(top_builddir)/runtime/mono-wrapper --debug
+MCS = $(with_mono_path) $(RUNTIME) $(mcs_topdir)/class/lib/build/mcs.exe -debug:full -target:library
+if INSTALL_MOBILE_STATIC
+prereq: aot
+else
prereq: test/asm.dll
+endif
test/.dirstamp deps/.dirstamp:
-mkdir $(@D)
clean:
rm -f deps/*.dll test/*.dll
+
+.PHONY: aot
+aot: test/asm.dll
+ MONO_PATH="deps:$(CLASS)" $(RUNTIME) $(AOT_BUILD_FLAGS) deps/test.dll
+ MONO_PATH="deps:$(CLASS)" $(RUNTIME) $(AOT_BUILD_FLAGS) deps/TestBase.dll
+ MONO_PATH="deps:$(CLASS)" $(RUNTIME) $(AOT_BUILD_FLAGS) test/asm.dll
+
using System;
using System.Runtime.InteropServices;
+[AttributeUsage (AttributeTargets.Method)]
+sealed class MonoPInvokeCallbackAttribute : Attribute {
+ public MonoPInvokeCallbackAttribute (Type t) {}
+}
+
namespace TestApp
{
public delegate char MyDelegate(int x);
class Driver
{
+ [MonoPInvokeCallbackAttribute (typeof (MyDelegate))]
static char Test (int x) { return (char)x; }
static int Main()
using System;
+using System.Linq;
class C
{
{
string fullTrace = ex.StackTrace;
string[] frames = fullTrace.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
+
+ // Ignore metadata
+ frames = frames.Where (l => !l.StartsWith ("[")).ToArray ();
+
return frames.Length;
}
public class Tests {
+ [AttributeUsage (AttributeTargets.Method)]
+ sealed class MonoPInvokeCallbackAttribute : Attribute {
+ public MonoPInvokeCallbackAttribute (Type t) {}
+ }
+
public static int Main (string[] args) {
return TestDriver.RunTests (typeof (Tests), args);
}
public delegate int SimpleDelegate (int a);
+ [MonoPInvokeCallback (typeof (SimpleDelegate))]
public static int delegate_test (int a)
{
return a + 1;
using System;
using System.Runtime.InteropServices;
+[AttributeUsage (AttributeTargets.Method)]
+sealed class MonoPInvokeCallbackAttribute : Attribute {
+ public MonoPInvokeCallbackAttribute (Type t) {}
+}
+
public class Marshal1 : ICustomMarshaler
{
int param;
[DllImport ("libtest")]
private static extern int mono_test_marshal_pass_return_custom_null_in_delegate (pass_return_int_delegate del);
+ [MonoPInvokeCallback (typeof (pass_return_int_delegate))]
private static object pass_return_int (object i) {
return (int)i;
}
+ [MonoPInvokeCallback (typeof (pass_return_int_delegate))]
private static object pass_return_null (object i) {
return (i == null) ? null : new Object ();
}
return 0;
}
-
+
+ [MonoPInvokeCallback (typeof (custom_out_param_delegate))]
private static void custom_out_param (out object i)
{
i = new object();
public class marshalbool
{
+ [AttributeUsage (AttributeTargets.Method)]
+ sealed class MonoPInvokeCallbackAttribute : Attribute {
+ public MonoPInvokeCallbackAttribute (Type t) {}
+ }
+
[DllImport ("libtest")]
static extern int mono_test_marshal_bool_in (int arg, uint expected,
bool bDefaultMarsh,
public static int test_0_Default_In_Managed ()
{
- MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (new marshalbool ().MarshalBoolInHelper);
+ MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (MarshalBoolInHelper);
int ret;
ret = mono_test_managed_marshal_bool_in (1, 0, 0, fcn);
public static int test_0_Bool_In_Managed ()
{
- MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (new marshalbool ().MarshalBoolInHelper);
+ MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (MarshalBoolInHelper);
int ret;
ret = mono_test_managed_marshal_bool_in (2, 0, 0, fcn);
public static int test_0_I1_In_Managed ()
{
- MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (new marshalbool ().MarshalBoolInHelper);
+ MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (MarshalBoolInHelper);
int ret;
ret = mono_test_managed_marshal_bool_in (3, 0, 0, fcn);
public static int test_0_U1_In_Managed ()
{
- MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (new marshalbool ().MarshalBoolInHelper);
+ MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (MarshalBoolInHelper);
int ret;
ret = mono_test_managed_marshal_bool_in (4, 0, 0, fcn);
public static int test_0_VariantBool_In_Managed ()
{
- MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (new marshalbool ().MarshalBoolInHelper);
+ MarshalBoolInDelegate fcn = new MarshalBoolInDelegate (MarshalBoolInHelper);
int ret;
ret = mono_test_managed_marshal_bool_in (5, 0, 0, fcn);
public static int test_0_Default_Out_Managed ()
{
- MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (new marshalbool ().MarshalBoolOutHelper);
+ MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (MarshalBoolOutHelper);
int ret;
ret = mono_test_managed_marshal_bool_out (1, 0, 0, fcn);
public static int test_0_Bool_Out_Managed ()
{
- MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (new marshalbool ().MarshalBoolOutHelper);
+ MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (MarshalBoolOutHelper);
int ret;
ret = mono_test_managed_marshal_bool_out (2, 0, 0, fcn);
public static int test_0_I1_Out_Managed ()
{
- MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (new marshalbool ().MarshalBoolOutHelper);
+ MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (MarshalBoolOutHelper);
int ret;
ret = mono_test_managed_marshal_bool_out (3, 0, 0, fcn);
public static int test_0_U1_Out_Managed ()
{
- MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (new marshalbool ().MarshalBoolOutHelper);
+ MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (MarshalBoolOutHelper);
int ret;
ret = mono_test_managed_marshal_bool_out (4, 0, 0, fcn);
public static int test_0_VariantBool_Out_Managed ()
{
- MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (new marshalbool ().MarshalBoolOutHelper);
+ MarshalBoolOutDelegate fcn = new MarshalBoolOutDelegate (MarshalBoolOutHelper);
int ret;
ret = mono_test_managed_marshal_bool_out (5, 0, 0, fcn);
public static int test_0_Default_Ref_Managed ()
{
- MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (new marshalbool ().MarshalBoolRefHelper);
+ MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (MarshalBoolRefHelper);
int ret;
ret = mono_test_managed_marshal_bool_ref (1, 0, 0, 0, 0, fcn);
public static int test_0_Bool_Ref_Managed ()
{
- MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (new marshalbool ().MarshalBoolRefHelper);
+ MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (MarshalBoolRefHelper);
int ret;
ret = mono_test_managed_marshal_bool_ref (2, 0, 0, 0, 0, fcn);
public static int test_0_I1_Ref_Managed ()
{
- MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (new marshalbool ().MarshalBoolRefHelper);
+ MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (MarshalBoolRefHelper);
int ret;
ret = mono_test_managed_marshal_bool_ref (3, 0, 0, 0, 0, fcn);
public static int test_0_U1_Ref_Managed ()
{
- MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (new marshalbool ().MarshalBoolRefHelper);
+ MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (MarshalBoolRefHelper);
int ret;
ret = mono_test_managed_marshal_bool_ref (4, 0, 0, 0, 0, fcn);
public static int test_0_VariantBool_Ref_Managed ()
{
- MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (new marshalbool ().MarshalBoolRefHelper);
+ MarshalBoolRefDelegate fcn = new MarshalBoolRefDelegate (MarshalBoolRefHelper);
int ret;
ret = mono_test_managed_marshal_bool_ref (5, 0, 0, 0, 0, fcn);
///////////////////////////////////////////////////////////////////
- unsafe int MarshalBoolInHelper (int arg, uint expected, bool bDefaultMarsh, bool bBoolCustMarsh, bool bI1CustMarsh,
- bool bU1CustMarsh, bool bVBCustMarsh)
+ [MonoPInvokeCallback (typeof (MarshalBoolInDelegate))]
+ unsafe static int MarshalBoolInHelper (int arg, uint expected, bool bDefaultMarsh, bool bBoolCustMarsh, bool bI1CustMarsh,
+ bool bU1CustMarsh, bool bVBCustMarsh)
{
bool* ptestVal;
switch (arg) {
return 0;
}
- unsafe int MarshalBoolOutHelper (int arg, uint testVal, out bool bDefaultMarsh, out bool bBoolCustMarsh,
- out bool bI1CustMarsh, out bool bU1CustMarsh, out bool bVBCustMarsh)
+ [MonoPInvokeCallback (typeof (MarshalBoolOutDelegate))]
+ unsafe static int MarshalBoolOutHelper (int arg, uint testVal, out bool bDefaultMarsh, out bool bBoolCustMarsh,
+ out bool bI1CustMarsh, out bool bU1CustMarsh, out bool bVBCustMarsh)
{
bDefaultMarsh = bBoolCustMarsh = bI1CustMarsh = bU1CustMarsh = bVBCustMarsh = false;
switch (arg) {
return 0;
}
- unsafe int MarshalBoolRefHelper (int arg, uint expected, uint testVal, ref bool bDefaultMarsh, ref bool bBoolCustMarsh,
- ref bool bI1CustMarsh, ref bool bU1CustMarsh, ref bool bVBCustMarsh)
+ [MonoPInvokeCallback (typeof (MarshalBoolRefDelegate))]
+ unsafe static int MarshalBoolRefHelper (int arg, uint expected, uint testVal, ref bool bDefaultMarsh, ref bool bBoolCustMarsh,
+ ref bool bI1CustMarsh, ref bool bU1CustMarsh, ref bool bVBCustMarsh)
{
switch (arg) {
case 1:
private static void RunStuffMode()
{
- for (int i = 0; i < 1000; i++)
+ for (int i = 0; i < 100; i++)
{
Execute(Assembly.GetExecutingAssembly().Location, i.ToString());
}
t.Join ();
for (int i = 0; i < 5; ++i) {
+ Console.WriteLine("-GC {0}/5-", i);
GC.Collect ();
GC.WaitForPendingFinalizers ();
}
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
+using MonoTests.Helpers;
public class Toggleref {
public int __test;
static int test_0_root_keeps_child ()
{
Console.WriteLine ("test_0_root_keeps_child");
- var t = new Thread (SetupLinks);
- t.Start ();
- t.Join ();
+ FinalizerHelpers.PerformNoPinAction (SetupLinks);
GC.Collect ();
GC.WaitForPendingFinalizers ();
{
Console.WriteLine ("test_0_child_goes_away");
- var t = new Thread (SetupLinks2);
- t.Start ();
- t.Join ();
+ FinalizerHelpers.PerformNoPinAction (SetupLinks2);
GC.Collect ();
GC.WaitForPendingFinalizers ();
{
Console.WriteLine ("test_0_CWT_keep_child_alive");
- var t = new Thread (SetupLinks3);
- t.Start ();
- t.Join ();
+ FinalizerHelpers.PerformNoPinAction (SetupLinks3);
GC.Collect ();
GC.WaitForPendingFinalizers ();
return TestDriver.RunTests (typeof (Driver), args);
}
-}
\ No newline at end of file
+}
using System;
using System.IO;
using System.Threading;
-using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
using System.Globalization;
using System.Xml;
+using System.Text;
using System.Text.RegularExpressions;
+
+#if !MOBILE_STATIC
using Mono.Unix.Native;
+#endif
//
// This is a simple test runner with support for parallel execution
{
const string TEST_TIME_FORMAT = "mm\\:ss\\.fff";
const string ENV_TIMEOUT = "TEST_DRIVER_TIMEOUT_SEC";
+ const string MONO_PATH = "MONO_PATH";
class ProcessData {
public string test;
int concurrency = 1;
int timeout = 2 * 60; // in seconds
int expectedExitCode = 0;
+ bool verbose = false;
string testsuiteName = null;
string inputFile = null;
- // FIXME: Add support for runtime arguments + env variables
-
string disabled_tests = null;
string runtime = "mono";
string config = null;
+ string mono_path = null;
var opt_sets = new List<string> ();
+ string aot_run_flags = null;
+ string aot_build_flags = null;
+
// Process options
int i = 0;
while (i < args.Length) {
}
inputFile = args [i + 1];
i += 2;
+ } else if (args [i] == "--runtime") {
+ if (i + 1 >= args.Length) {
+ Console.WriteLine ("Missing argument to --runtime command line option.");
+ return 1;
+ }
+ runtime = args [i + 1];
+ i += 2;
+ } else if (args [i] == "--mono-path") {
+ if (i + 1 >= args.Length) {
+ Console.WriteLine ("Missing argument to --mono-path command line option.");
+ return 1;
+ }
+ mono_path = args [i + 1].Substring(0, args [i + 1].Length);
+
+ i += 2;
+ } else if (args [i] == "--aot-run-flags") {
+ if (i + 1 >= args.Length) {
+ Console.WriteLine ("Missing argument to --aot-run-flags command line option.");
+ return 1;
+ }
+ aot_run_flags = args [i + 1].Substring(0, args [i + 1].Length);
+ i += 2;
+ } else if (args [i] == "--aot-build-flags") {
+ if (i + 1 >= args.Length) {
+ Console.WriteLine ("Missing argument to --aot-build-flags command line option.");
+ return 1;
+ }
+ aot_build_flags = args [i + 1].Substring(0, args [i + 1].Length);
+ i += 2;
+ } else if (args [i] == "--verbose") {
+ verbose = true;
+ i ++;
} else {
Console.WriteLine ("Unknown command line option: '" + args [i] + "'.");
return 1;
output_width = Math.Min (120, ti.test.Length);
}
+ if (aot_build_flags != null) {
+ Console.WriteLine("AOT compiling tests");
+
+ object aot_monitor = new object ();
+ var aot_queue = new Queue<String> (tests);
+
+ List<Thread> build_threads = new List<Thread> (concurrency);
+
+ for (int j = 0; j < concurrency; ++j) {
+ Thread thread = new Thread (() => {
+ while (true) {
+ String test_name;
+
+ lock (aot_monitor) {
+ if (aot_queue.Count == 0)
+ break;
+ test_name = aot_queue.Dequeue ();
+ }
+
+ string test_bitcode_output = test_name + "_bitcode_tmp";
+ string test_bitcode_arg = ",temp-path=" + test_bitcode_output;
+ string aot_args = aot_build_flags + test_bitcode_arg + " " + test_name;
+
+ Directory.CreateDirectory(test_bitcode_output);
+
+ ProcessStartInfo job = new ProcessStartInfo (runtime, aot_args);
+ job.UseShellExecute = false;
+ job.EnvironmentVariables[ENV_TIMEOUT] = timeout.ToString();
+ job.EnvironmentVariables[MONO_PATH] = mono_path;
+ Process compiler = new Process ();
+ compiler.StartInfo = job;
+
+ compiler.Start ();
+
+ if (!compiler.WaitForExit (timeout * 1000)) {
+ try {
+ compiler.Kill ();
+ } catch {
+ }
+ throw new Exception(String.Format("Timeout AOT compiling tests, output in {0}", test_bitcode_output));
+ } else if (compiler.ExitCode != 0) {
+ throw new Exception(String.Format("Error AOT compiling tests, output in {0}", test_bitcode_output));
+ } else {
+ Directory.Delete (test_bitcode_output, true);
+ }
+ }
+ });
+
+ thread.Start ();
+
+ build_threads.Add (thread);
+ }
+
+ for (int j = 0; j < build_threads.Count; ++j)
+ build_threads [j].Join ();
+
+ Console.WriteLine("Done compiling");
+ }
+
List<Thread> threads = new List<Thread> (concurrency);
DateTime test_start_time = DateTime.UtcNow;
string test = ti.test;
string opt_set = ti.opt_set;
- output.Write (String.Format ("{{0,-{0}}} ", output_width), test);
+ if (verbose) {
+ output.Write (String.Format ("{{0,-{0}}} ", output_width), test);
+ } else {
+ Console.Write (".");
+ }
+
+ string test_invoke;
+
+ if (aot_run_flags != null)
+ test_invoke = aot_run_flags + " " + test;
+ else
+ test_invoke = test;
/* Spawn a new process */
string process_args;
if (opt_set == null)
- process_args = test;
+ process_args = test_invoke;
else
- process_args = "-O=" + opt_set + " " + test;
+ process_args = "-O=" + opt_set + " " + test_invoke;
+
ProcessStartInfo info = new ProcessStartInfo (runtime, process_args);
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.EnvironmentVariables[ENV_TIMEOUT] = timeout.ToString();
if (config != null)
info.EnvironmentVariables["MONO_CONFIG"] = config;
+ if (mono_path != null)
+ info.EnvironmentVariables[MONO_PATH] = mono_path;
Process p = new Process ();
p.StartInfo = info;
timedout.Add (data);
}
+#if !MOBILE_STATIC
// Force the process to print a thread dump
try {
Syscall.kill (p.Id, Signum.SIGQUIT);
Thread.Sleep (1000);
} catch {
}
+#endif
- output.Write ($"timed out ({timeout}s)");
+ if (verbose) {
+ output.Write ($"timed out ({timeout}s)");
+ }
try {
p.Kill ();
failed.Add (data);
}
- output.Write ("failed, time: {0}, exit code: {1}", (end - start).ToString (TEST_TIME_FORMAT), p.ExitCode);
+ if (verbose)
+ output.Write ("failed, time: {0}, exit code: {1}", (end - start).ToString (TEST_TIME_FORMAT), p.ExitCode);
} else {
var end = DateTime.UtcNow;
passed.Add (data);
}
- output.Write ("passed, time: {0}", (end - start).ToString (TEST_TIME_FORMAT));
+ if (verbose)
+ output.Write ("passed, time: {0}", (end - start).ToString (TEST_TIME_FORMAT));
}
p.Close ();
lock (monitor) {
- Console.WriteLine (output.ToString ());
+ if (verbose)
+ Console.WriteLine (output.ToString ());
}
}
});
writer.WriteEndDocument ();
}
- Console.WriteLine ();
- Console.WriteLine ("Time: {0}", test_time.ToString (TEST_TIME_FORMAT));
- Console.WriteLine ();
- Console.WriteLine ("{0,4} test(s) passed", npassed);
- Console.WriteLine ("{0,4} test(s) failed", nfailed);
- Console.WriteLine ("{0,4} test(s) timed out", ntimedout);
+ if (verbose) {
+ Console.WriteLine ();
+ Console.WriteLine ("Time: {0}", test_time.ToString (TEST_TIME_FORMAT));
+ Console.WriteLine ();
+ Console.WriteLine ("{0,4} test(s) passed", npassed);
+ Console.WriteLine ("{0,4} test(s) failed", nfailed);
+ Console.WriteLine ("{0,4} test(s) timed out", ntimedout);
+ } else {
+ Console.WriteLine ();
+ Console.WriteLine (String.Format ("{0} test(s) passed, {1} test(s) did not pass.", npassed, nfailed));
+ }
if (nfailed > 0) {
Console.WriteLine ();
using System;
using System.Runtime.InteropServices;
+[AttributeUsage (AttributeTargets.Method)]
+sealed class MonoPInvokeCallbackAttribute : Attribute {
+ public MonoPInvokeCallbackAttribute (Type t) {}
+}
+
[StructLayout (LayoutKind.Sequential)]
struct winx64_struct1
{
return 0;
}
+ [MonoPInvokeCallback (typeof (managed_struct1_delegate))]
public static int managed_struct1_test (winx64_struct1 var)
{
if (var.a != 5)
return 0;
}
+ [MonoPInvokeCallback (typeof (managed_struct5_delegate))]
public static int managed_struct5_test (winx64_struct5 var)
{
if (var.a != 5)
return 0;
}
+ [MonoPInvokeCallback (typeof (managed_struct1_struct5_delegate))]
public static int managed_struct1_struct5_test (winx64_struct1 var1, winx64_struct5 var2,
winx64_struct1 var3, winx64_struct5 var4,
winx64_struct1 var5, winx64_struct5 var6)
return 0;
}
+ [MonoPInvokeCallback (typeof (mono_test_Winx64_struct1_ret_delegate))]
public static winx64_struct1 mono_test_Winx64_struct1_ret_test ()
{
return new winx64_struct1 (0x45);
}
+ [MonoPInvokeCallback (typeof (mono_test_Winx64_struct5_ret_delegate))]
public static winx64_struct5 mono_test_Winx64_struct5_ret_test ()
{
return new winx64_struct5 (0x12, 0x34, 0x56);
parse.c \
parse.h \
checked-build.c \
- checked-build.h
+ checked-build.h \
+ w32handle.c \
+ w32handle.h
arch_sources =
mono_cond_t c;
};
-static inline gint
+static inline void
mono_coop_mutex_init (MonoCoopMutex *mutex)
{
- return mono_os_mutex_init (&mutex->m);
+ mono_os_mutex_init (&mutex->m);
}
-static inline gint
+static inline void
mono_coop_mutex_init_recursive (MonoCoopMutex *mutex)
{
- return mono_os_mutex_init_recursive (&mutex->m);
+ mono_os_mutex_init_recursive (&mutex->m);
}
static inline gint
return mono_os_mutex_destroy (&mutex->m);
}
-static inline gint
+static inline void
mono_coop_mutex_lock (MonoCoopMutex *mutex)
{
- gint res;
-
/* Avoid thread state switch if lock is not contended */
if (mono_os_mutex_trylock (&mutex->m) == 0)
- return 0;
+ return;
MONO_ENTER_GC_SAFE;
- res = mono_os_mutex_lock (&mutex->m);
+ mono_os_mutex_lock (&mutex->m);
MONO_EXIT_GC_SAFE;
-
- return res;
}
static inline gint
return mono_os_mutex_trylock (&mutex->m);
}
-static inline gint
+static inline void
mono_coop_mutex_unlock (MonoCoopMutex *mutex)
{
- return mono_os_mutex_unlock (&mutex->m);
+ mono_os_mutex_unlock (&mutex->m);
}
-static inline gint
+static inline void
mono_coop_cond_init (MonoCoopCond *cond)
{
- return mono_os_cond_init (&cond->c);
+ mono_os_cond_init (&cond->c);
}
static inline gint
return mono_os_cond_destroy (&cond->c);
}
-static inline gint
+static inline void
mono_coop_cond_wait (MonoCoopCond *cond, MonoCoopMutex *mutex)
{
- gint res;
-
MONO_ENTER_GC_SAFE;
- res = mono_os_cond_wait (&cond->c, &mutex->m);
+ mono_os_cond_wait (&cond->c, &mutex->m);
MONO_EXIT_GC_SAFE;
-
- return res;
}
static inline gint
return res;
}
-static inline gint
+static inline void
mono_coop_cond_signal (MonoCoopCond *cond)
{
- return mono_os_cond_signal (&cond->c);
+ mono_os_cond_signal (&cond->c);
}
-static inline gint
+static inline void
mono_coop_cond_broadcast (MonoCoopCond *cond)
{
- return mono_os_cond_broadcast (&cond->c);
+ mono_os_cond_broadcast (&cond->c);
}
G_END_DECLS
MonoSemType s;
};
-static inline gint
+static inline void
mono_coop_sem_init (MonoCoopSem *sem, int value)
{
- return mono_os_sem_init (&sem->s, value);
+ mono_os_sem_init (&sem->s, value);
}
-static inline gint
+static inline void
mono_coop_sem_destroy (MonoCoopSem *sem)
{
- return mono_os_sem_destroy (&sem->s);
+ mono_os_sem_destroy (&sem->s);
}
static inline gint
return res;
}
-static inline gint
+static inline MonoSemTimedwaitRet
mono_coop_sem_timedwait (MonoCoopSem *sem, guint timeout_ms, MonoSemFlags flags)
{
- gint res;
+ MonoSemTimedwaitRet res;
MONO_ENTER_GC_SAFE;
return res;
}
-static inline gint
+static inline void
mono_coop_sem_post (MonoCoopSem *sem)
{
- return mono_os_sem_post (&sem->s);
+ mono_os_sem_post (&sem->s);
}
G_END_DECLS
MONO_TRACE_THREADPOOL = (1<<7),
MONO_TRACE_IO_THREADPOOL = (1<<8),
MONO_TRACE_IO_LAYER = (1<<9),
+ MONO_TRACE_W32HANDLE = (1<<10),
MONO_TRACE_ALL = MONO_TRACE_ASSEMBLY |
MONO_TRACE_TYPE |
MONO_TRACE_DLLIMPORT |
MONO_TRACE_SECURITY |
MONO_TRACE_THREADPOOL |
MONO_TRACE_IO_THREADPOOL |
- MONO_TRACE_IO_LAYER
+ MONO_TRACE_IO_LAYER |
+ MONO_TRACE_W32HANDLE
} MonoTraceMask;
extern GLogLevelFlags mono_internal_current_level;
if(level_stack == NULL)
mono_trace_init();
- if ((dest != NULL) && (strcmp("syslog", dest) != 0)) {
+ if ((dest == NULL) || (strcmp("syslog", dest) != 0)) {
logger.opener = mono_log_open_logfile;
logger.writer = mono_log_write_logfile;
logger.closer = mono_log_close_logfile;
const char *tok;
guint32 flags = 0;
- const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "io-threadpool", "io-layer", "all", NULL};
+ const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "io-threadpool", "io-layer", "w32handle", "all", NULL};
const MonoTraceMask valid_masks[] = {MONO_TRACE_ASSEMBLY, MONO_TRACE_TYPE, MONO_TRACE_DLLIMPORT,
MONO_TRACE_GC, MONO_TRACE_CONFIG, MONO_TRACE_AOT, MONO_TRACE_SECURITY,
- MONO_TRACE_THREADPOOL, MONO_TRACE_IO_THREADPOOL, MONO_TRACE_IO_LAYER, MONO_TRACE_ALL };
+ MONO_TRACE_THREADPOOL, MONO_TRACE_IO_THREADPOOL, MONO_TRACE_IO_LAYER,
+ MONO_TRACE_W32HANDLE, MONO_TRACE_ALL };
if(!value)
return;
G_BEGIN_DECLS
+#ifndef MONO_INFINITE_WAIT
+#define MONO_INFINITE_WAIT ((guint32) 0xFFFFFFFF)
+#endif
+
+
#if !defined(HOST_WIN32)
typedef pthread_mutex_t mono_mutex_t;
typedef pthread_cond_t mono_cond_t;
-static inline int
+static inline void
mono_os_mutex_init (mono_mutex_t *mutex)
{
- return pthread_mutex_init (mutex, NULL);
+ int res;
+
+ res = pthread_mutex_init (mutex, NULL);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
}
-static inline int
+static inline void
mono_os_mutex_init_recursive (mono_mutex_t *mutex)
{
int res;
pthread_mutexattr_t attr;
- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+ res = pthread_mutexattr_init (&attr);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutexattr_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ res = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutexattr_settype failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
res = pthread_mutex_init (mutex, &attr);
- pthread_mutexattr_destroy (&attr);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
- return res;
+ res = pthread_mutexattr_destroy (&attr);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutexattr_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
}
static inline int
mono_os_mutex_destroy (mono_mutex_t *mutex)
{
- return pthread_mutex_destroy (mutex);
+ int res;
+
+ res = pthread_mutex_destroy (mutex);
+ if (G_UNLIKELY (res != 0 && res != EBUSY))
+ g_error ("%s: pthread_mutex_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ return res != 0 ? -1 : 0;
}
-static inline int
+static inline void
mono_os_mutex_lock (mono_mutex_t *mutex)
{
int res;
res = pthread_mutex_lock (mutex);
- g_assert (res != EINVAL);
-
- return res;
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutex_lock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
}
static inline int
mono_os_mutex_trylock (mono_mutex_t *mutex)
{
- return pthread_mutex_trylock (mutex);
+ int res;
+
+ res = pthread_mutex_trylock (mutex);
+ if (G_UNLIKELY (res != 0 && res != EBUSY))
+ g_error ("%s: pthread_mutex_trylock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ return res != 0 ? -1 : 0;
}
-static inline int
+static inline void
mono_os_mutex_unlock (mono_mutex_t *mutex)
{
- return pthread_mutex_unlock (mutex);
+ int res;
+
+ res = pthread_mutex_unlock (mutex);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutex_unlock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
}
-static inline int
+static inline void
mono_os_cond_init (mono_cond_t *cond)
{
- return pthread_cond_init (cond, NULL);
+ int res;
+
+ res = pthread_cond_init (cond, NULL);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
}
static inline int
mono_os_cond_destroy (mono_cond_t *cond)
{
- return pthread_cond_destroy (cond);
+ int res;
+
+ res = pthread_cond_destroy (cond);
+ if (G_UNLIKELY (res != 0 && res != EBUSY))
+ g_error ("%s: pthread_cond_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ return res != 0 ? -1 : 0;
}
-static inline int
+static inline void
mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
{
int res;
res = pthread_cond_wait (cond, mutex);
- g_assert (res != EINVAL);
-
- return res;
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
}
static inline int
gint64 usecs;
int res;
- if (timeout_ms == (guint32) 0xFFFFFFFF)
- return mono_os_cond_wait (cond, mutex);
+ if (timeout_ms == MONO_INFINITE_WAIT) {
+ mono_os_cond_wait (cond, mutex);
+ return 0;
+ }
/* ms = 10^-3, us = 10^-6, ns = 10^-9 */
- gettimeofday (&tv, NULL);
+ res = gettimeofday (&tv, NULL);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
tv.tv_sec += timeout_ms / 1000;
usecs = tv.tv_usec + ((timeout_ms % 1000) * 1000);
if (usecs >= 1000000) {
ts.tv_nsec = usecs * 1000;
res = pthread_cond_timedwait (cond, mutex, &ts);
- g_assert (res != EINVAL);
+ if (G_UNLIKELY (res != 0 && res != ETIMEDOUT))
+ g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
- return res;
+ return res != 0 ? -1 : 0;
}
-static inline int
+static inline void
mono_os_cond_signal (mono_cond_t *cond)
{
- return pthread_cond_signal (cond);
+ int res;
+
+ res = pthread_cond_signal (cond);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_signal failed with \"%s\" (%d)", __func__, g_strerror (res), res);
}
-static inline int
+static inline void
mono_os_cond_broadcast (mono_cond_t *cond)
{
- return pthread_cond_broadcast (cond);
+ int res;
+
+ res = pthread_cond_broadcast (cond);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_broadcast failed with \"%s\" (%d)", __func__, g_strerror (res), res);
}
#else
typedef CRITICAL_SECTION mono_mutex_t;
typedef CONDITION_VARIABLE mono_cond_t;
-static inline int
+static inline void
mono_os_mutex_init (mono_mutex_t *mutex)
{
- InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
- return 0;
+ BOOL res;
+
+ res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
}
-static inline int
+static inline void
mono_os_mutex_init_recursive (mono_mutex_t *mutex)
{
- InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
- return 0;
+ BOOL res;
+
+ res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
}
static inline int
return 0;
}
-static inline int
+static inline void
mono_os_mutex_lock (mono_mutex_t *mutex)
{
EnterCriticalSection (mutex);
- return 0;
}
static inline int
mono_os_mutex_trylock (mono_mutex_t *mutex)
{
- return TryEnterCriticalSection (mutex) != 0 ? 0 : 1;
+ return TryEnterCriticalSection (mutex) == 0 ? -1 : 0;
}
-static inline int
+static inline void
mono_os_mutex_unlock (mono_mutex_t *mutex)
{
LeaveCriticalSection (mutex);
- return 0;
}
-static inline int
+static inline void
mono_os_cond_init (mono_cond_t *cond)
{
InitializeConditionVariable (cond);
- return 0;
}
static inline int
return 0;
}
-static inline int
+static inline void
mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
{
- return SleepConditionVariableCS (cond, mutex, INFINITE) ? 0 : 1;
+ BOOL res;
+
+ res = SleepConditionVariableCS (cond, mutex, INFINITE);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
}
static inline int
mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
{
- return SleepConditionVariableCS (cond, mutex, timeout_ms) ? 0 : 1;
+ BOOL res;
+
+ res = SleepConditionVariableCS (cond, mutex, timeout_ms);
+ if (G_UNLIKELY (res == 0 && GetLastError () != ERROR_TIMEOUT))
+ g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
+
+ return res == 0 ? -1 : 0;
}
-static inline int
+static inline void
mono_os_cond_signal (mono_cond_t *cond)
{
WakeConditionVariable (cond);
- return 0;
}
-static inline int
+static inline void
mono_os_cond_broadcast (mono_cond_t *cond)
{
WakeAllConditionVariable (cond);
- return 0;
}
#endif
#define NSEC_PER_SEC (1000 * 1000 * 1000)
#endif
+#ifndef MONO_INFINITE_WAIT
+#define MONO_INFINITE_WAIT ((guint32) 0xFFFFFFFF)
+#endif
+
G_BEGIN_DECLS
typedef enum {
MONO_SEM_FLAGS_ALERTABLE = 1 << 0,
} MonoSemFlags;
+typedef enum {
+ MONO_SEM_TIMEDWAIT_RET_SUCCESS = 0,
+ MONO_SEM_TIMEDWAIT_RET_ALERTED = -1,
+ MONO_SEM_TIMEDWAIT_RET_TIMEDOUT = -2,
+} MonoSemTimedwaitRet;
+
#if defined(USE_MACH_SEMA)
typedef semaphore_t MonoSemType;
-static inline int
+static inline void
mono_os_sem_init (MonoSemType *sem, int value)
{
- return semaphore_create (current_task (), sem, SYNC_POLICY_FIFO, value) != KERN_SUCCESS ? -1 : 0;
+ kern_return_t res;
+
+ res = semaphore_create (current_task (), sem, SYNC_POLICY_FIFO, value);
+ if (G_UNLIKELY (res != KERN_SUCCESS))
+ g_error ("%s: semaphore_create failed with error %d", __func__, res);
}
-static inline int
+static inline void
mono_os_sem_destroy (MonoSemType *sem)
{
- return semaphore_destroy (current_task (), *sem) != KERN_SUCCESS ? -1 : 0;
+ kern_return_t res;
+
+ res = semaphore_destroy (current_task (), *sem);
+ if (G_UNLIKELY (res != KERN_SUCCESS))
+ g_error ("%s: semaphore_destroy failed with error %d", __func__, res);
}
static inline int
mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
{
- int res;
+ kern_return_t res;
retry:
res = semaphore_wait (*sem);
- g_assert (res != KERN_INVALID_ARGUMENT);
+ if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
+ g_error ("%s: semaphore_wait failed with error %d", __func__, res);
if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE))
goto retry;
return res != KERN_SUCCESS ? -1 : 0;
}
-static inline int
+static inline MonoSemTimedwaitRet
mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
{
+ kern_return_t res;
+ int resint;
mach_timespec_t ts, copy;
struct timeval start, current;
- int res = 0;
- if (timeout_ms == (guint32) 0xFFFFFFFF)
- return mono_os_sem_wait (sem, flags);
+ if (timeout_ms == MONO_INFINITE_WAIT)
+ return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
ts.tv_sec = timeout_ms / 1000;
ts.tv_nsec = (timeout_ms % 1000) * 1000000;
}
copy = ts;
- gettimeofday (&start, NULL);
+ resint = gettimeofday (&start, NULL);
+ if (G_UNLIKELY (resint != 0))
+ g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
retry:
res = semaphore_timedwait (*sem, ts);
- g_assert (res != KERN_INVALID_ARGUMENT);
+ if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED && res != KERN_OPERATION_TIMED_OUT))
+ g_error ("%s: semaphore_timedwait failed with error %d", __func__, res);
if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
ts = copy;
- gettimeofday (¤t, NULL);
+ resint = gettimeofday (¤t, NULL);
+ if (G_UNLIKELY (resint != 0))
+ g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
ts.tv_sec -= (current.tv_sec - start.tv_sec);
ts.tv_nsec -= (current.tv_usec - start.tv_usec) * 1000;
if (ts.tv_nsec < 0) {
goto retry;
}
- return res != KERN_SUCCESS ? -1 : 0;
+ switch (res) {
+ case KERN_SUCCESS:
+ return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+ case KERN_ABORTED:
+ return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+ case KERN_OPERATION_TIMED_OUT:
+ return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+ default:
+ g_assert_not_reached ();
+ }
}
-static inline int
+static inline void
mono_os_sem_post (MonoSemType *sem)
{
- int res;
+ kern_return_t res;
+
retry:
res = semaphore_signal (*sem);
- g_assert (res != KERN_INVALID_ARGUMENT);
+ if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
+ g_error ("%s: semaphore_signal failed with error %d", __func__, res);
if (res == KERN_ABORTED)
goto retry;
-
- return res != KERN_SUCCESS ? -1 : 0;
}
#elif !defined(HOST_WIN32) && defined(HAVE_SEMAPHORE_H)
typedef sem_t MonoSemType;
-static inline int
+static inline void
mono_os_sem_init (MonoSemType *sem, int value)
{
- return sem_init (sem, 0, value);
+ int res;
+
+ res = sem_init (sem, 0, value);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: sem_init failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
}
-static inline int
+static inline void
mono_os_sem_destroy (MonoSemType *sem)
{
- return sem_destroy (sem);
+ int res;
+
+ res = sem_destroy (sem);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: sem_destroy failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
}
static inline int
retry:
res = sem_wait (sem);
- if (res == -1)
- g_assert (errno != EINVAL);
+ if (G_UNLIKELY (res != 0 && errno != EINTR))
+ g_error ("%s: sem_wait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
- if (res == -1 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+ if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE))
goto retry;
return res != 0 ? -1 : 0;
}
-static inline int
+static inline MonoSemTimedwaitRet
mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
{
struct timespec ts, copy;
struct timeval t;
- int res = 0;
+ int res;
if (timeout_ms == 0) {
- res = sem_trywait (sem) != 0 ? -1 : 0;
- if (res == -1)
- g_assert (errno != EINVAL);
-
- return res != 0 ? -1 : 0;
+ res = sem_trywait (sem);
+ if (G_UNLIKELY (res != 0 && errno != EINTR && errno != EAGAIN))
+ g_error ("%s: sem_trywait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+ if (res == 0)
+ return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+ else if (errno == EINTR)
+ return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+ else if (errno == EAGAIN)
+ return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+ else
+ g_assert_not_reached ();
}
- if (timeout_ms == (guint32) 0xFFFFFFFF)
- return mono_os_sem_wait (sem, flags);
+ if (timeout_ms == MONO_INFINITE_WAIT)
+ return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
+
+ res = gettimeofday (&t, NULL);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
- gettimeofday (&t, NULL);
ts.tv_sec = timeout_ms / 1000 + t.tv_sec;
ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000;
while (ts.tv_nsec >= NSEC_PER_SEC) {
copy = ts;
retry:
-#if defined(__native_client__) && defined(USE_NEWLIB)
- res = sem_trywait (sem);
-#else
res = sem_timedwait (sem, &ts);
-#endif
- if (res == -1)
- g_assert (errno != EINVAL);
+ if (G_UNLIKELY (res != 0 && errno != EINTR && errno != ETIMEDOUT))
+ g_error ("%s: sem_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
- if (res == -1 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
+ if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
ts = copy;
goto retry;
}
- return res != 0 ? -1 : 0;
+ if (res == 0)
+ return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+ else if (errno == EINTR)
+ return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+ else if (errno == ETIMEDOUT)
+ return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+ else
+ g_assert_not_reached ();
}
-static inline int
+static inline void
mono_os_sem_post (MonoSemType *sem)
{
int res;
res = sem_post (sem);
- if (res == -1)
- g_assert (errno != EINVAL);
-
- return res;
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: sem_post failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
}
#else
typedef HANDLE MonoSemType;
-static inline int
+static inline void
mono_os_sem_init (MonoSemType *sem, int value)
{
*sem = CreateSemaphore (NULL, value, 0x7FFFFFFF, NULL);
- return *sem == NULL ? -1 : 0;
+ if (G_UNLIKELY (*sem == NULL))
+ g_error ("%s: CreateSemaphore failed with error %d", __func__, GetLastError ());
}
-static inline int
+static inline void
mono_os_sem_destroy (MonoSemType *sem)
{
- return !CloseHandle (*sem) ? -1 : 0;
+ BOOL res;
+
+ res = CloseHandle (*sem);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ());
}
-static inline int
+static inline MonoSemTimedwaitRet
mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
{
- gboolean res;
+ BOOL res;
retry:
res = WaitForSingleObjectEx (*sem, timeout_ms, flags & MONO_SEM_FLAGS_ALERTABLE);
+ if (G_UNLIKELY (res != WAIT_OBJECT_0 && res != WAIT_IO_COMPLETION && res != WAIT_TIMEOUT))
+ g_error ("%s: WaitForSingleObjectEx failed with error %d", __func__, GetLastError ());
if (res == WAIT_IO_COMPLETION && !(flags & MONO_SEM_FLAGS_ALERTABLE))
goto retry;
- return res != WAIT_OBJECT_0 ? -1 : 0;
+ switch (res) {
+ case WAIT_OBJECT_0:
+ return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+ case WAIT_IO_COMPLETION:
+ return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+ case WAIT_TIMEOUT:
+ return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+ default:
+ g_assert_not_reached ();
+ }
}
static inline int
mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
{
- return mono_os_sem_timedwait (sem, INFINITE, flags);
+ return mono_os_sem_timedwait (sem, INFINITE, flags) != 0 ? -1 : 0;
}
-static inline int
+static inline void
mono_os_sem_post (MonoSemType *sem)
{
- return !ReleaseSemaphore (*sem, 1, NULL) ? -1 : 0;
+ BOOL res;
+
+ res = ReleaseSemaphore (*sem, 1, NULL);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: ReleaseSemaphore failed with error %d", __func__, GetLastError ());
}
#endif
g_free (ptr);
}
+
+/**
+ * mono_set_allocator_vtable
+ *
+ * Make the runtime use the functions in @vtable for allocating memory.
+ * The provided functions must have the same semantics of their libc's equivalents.
+ *
+ * @return TRUE is the vtable was installed. FALSE if the version is incompatible.
+ */
+mono_bool
+mono_set_allocator_vtable (MonoAllocatorVTable* vtable)
+{
+ if (vtable->version != MONO_ALLOCATOR_VTABLE_VERSION)
+ return FALSE;
+ GMemVTable g_mem_vtable = { vtable->malloc, vtable->realloc, vtable->free, vtable->calloc};
+ g_mem_set_vtable (&g_mem_vtable);
+ return TRUE;
+}
#endif /* end of compiler-specific stuff */
+#include <stdlib.h>
+
#if defined(MONO_DLL_EXPORT)
#define MONO_API MONO_API_EXPORT
#elif defined(MONO_DLL_IMPORT)
MONO_API void mono_free (void *);
+#define MONO_ALLOCATOR_VTABLE_VERSION 1
+
+typedef struct {
+ int version;
+ void *(*malloc) (size_t size);
+ void *(*realloc) (void *mem, size_t count);
+ void (*free) (void *mem);
+ void *(*calloc) (size_t count, size_t size);
+} MonoAllocatorVTable;
+
+MONO_API mono_bool
+mono_set_allocator_vtable (MonoAllocatorVTable* vtable);
+
+
#define MONO_CONST_RETURN const
/*
/* Register the thread with the io-layer */
handle = wapi_create_thread_handle ();
if (!handle) {
- res = mono_coop_sem_post (&(start_info->registered));
- g_assert (!res);
+ mono_coop_sem_post (&(start_info->registered));
return NULL;
}
start_info->handle = handle;
}
/* start_info is not valid after this */
- res = mono_coop_sem_post (&(start_info->registered));
- g_assert (!res);
+ mono_coop_sem_post (&(start_info->registered));
start_info = NULL;
if (flags & CREATE_SUSPENDED) {
info->runtime_thread = TRUE;
info->create_suspended = suspend;
- post_result = mono_coop_sem_post (&(start_info->registered));
- g_assert (!post_result);
+ mono_coop_sem_post (&(start_info->registered));
if (suspend) {
WaitForSingleObject (suspend_event, INFINITE); /* caller will suspend the thread before setting the event. */
#define mono_thread_info_run_state(info) (((MonoThreadInfo*)info)->thread_state & THREAD_STATE_MASK)
/*warn at 50 ms*/
-#define SLEEP_DURATION_BEFORE_WARNING (10)
-/*abort at 1 sec*/
-#define SLEEP_DURATION_BEFORE_ABORT 200
+#define SLEEP_DURATION_BEFORE_WARNING (50)
+/*never aborts */
+#define SLEEP_DURATION_BEFORE_ABORT MONO_INFINITE_WAIT
-static long sleepWarnDuration = SLEEP_DURATION_BEFORE_WARNING,
+static guint32 sleepWarnDuration = SLEEP_DURATION_BEFORE_WARNING,
sleepAbortDuration = SLEEP_DURATION_BEFORE_ABORT;
static int suspend_posts, resume_posts, abort_posts, waits_done, pending_ops;
for (i = 0; i < pending_suspends; ++i) {
THREADS_SUSPEND_DEBUG ("[INITIATOR-WAIT-WAITING]\n");
InterlockedIncrement (&waits_done);
- if (!mono_os_sem_timedwait (&suspend_semaphore, sleepAbortDuration, MONO_SEM_FLAGS_NONE))
+ if (mono_os_sem_timedwait (&suspend_semaphore, sleepAbortDuration, MONO_SEM_FLAGS_NONE) == MONO_SEM_TIMEDWAIT_RET_SUCCESS)
continue;
mono_stopwatch_stop (&suspension_time);
if (threads_callbacks.thread_register) {
if (threads_callbacks.thread_register (info, baseptr) == NULL) {
// g_warning ("thread registation failed\n");
+ mono_native_tls_set_value (thread_info_key, NULL);
g_free (info);
return NULL;
}
gboolean res;
threads_callbacks = *callbacks;
thread_info_size = info_size;
- char *sleepLimit;
+ const char *sleepLimit;
#ifdef HOST_WIN32
res = mono_native_tls_alloc (&thread_info_key, NULL);
res = mono_native_tls_alloc (&thread_exited_key, NULL);
unified_suspend_enabled = g_getenv ("MONO_ENABLE_UNIFIED_SUSPEND") != NULL || mono_threads_is_coop_enabled ();
if ((sleepLimit = g_getenv ("MONO_SLEEP_ABORT_LIMIT")) != NULL) {
+ errno = 0;
long threshold = strtol(sleepLimit, NULL, 10);
if ((errno == 0) && (threshold >= 40)) {
sleepAbortDuration = threshold;
--- /dev/null
+/*
+ * w32handle.c: Generic and internal operations on handles
+ *
+ * Author:
+ * Dick Porter (dick@ximian.com)
+ * Ludovic Henry (luhenry@microsoft.com)
+ *
+ * (C) 2002-2011 Novell, Inc.
+ * Copyright 2011 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include <config.h>
+
+#if !defined(HOST_WIN32)
+
+#include <glib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#endif
+#include <sys/stat.h>
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
+#include "w32handle.h"
+
+#include "atomic.h"
+#include "mono-logger-internals.h"
+#include "mono-os-mutex.h"
+#include "mono-proclib.h"
+#include "mono-threads.h"
+
+#undef DEBUG_REFS
+
+#define SLOT_MAX (1024 * 16)
+
+/* must be a power of 2 */
+#define HANDLE_PER_SLOT (256)
+
+typedef struct {
+ MonoW32HandleType type;
+ guint ref;
+ gboolean signalled;
+ mono_mutex_t signal_mutex;
+ mono_cond_t signal_cond;
+ gpointer specific;
+} MonoW32HandleBase;
+
+static MonoW32HandleCapability handle_caps [MONO_W32HANDLE_COUNT];
+static MonoW32HandleOps *handle_ops [MONO_W32HANDLE_COUNT];
+
+/*
+ * We can hold SLOT_MAX * HANDLE_PER_SLOT handles.
+ * If 4M handles are not enough... Oh, well... we will crash.
+ */
+#define SLOT_INDEX(x) (x / HANDLE_PER_SLOT)
+#define SLOT_OFFSET(x) (x % HANDLE_PER_SLOT)
+
+static MonoW32HandleBase *private_handles [SLOT_MAX];
+static guint32 private_handles_count = 0;
+static guint32 private_handles_slots_count = 0;
+
+guint32 mono_w32handle_fd_reserve;
+
+/*
+ * This is an internal handle which is used for handling waiting for multiple handles.
+ * Threads which wait for multiple handles wait on this one handle, and when a handle
+ * is signalled, this handle is signalled too.
+ */
+static mono_mutex_t global_signal_mutex;
+static mono_cond_t global_signal_cond;
+
+static mono_mutex_t scan_mutex;
+
+static gboolean shutting_down = FALSE;
+
+static gboolean
+type_is_fd (MonoW32HandleType type)
+{
+ switch (type) {
+ case MONO_W32HANDLE_FILE:
+ case MONO_W32HANDLE_CONSOLE:
+ case MONO_W32HANDLE_SOCKET:
+ case MONO_W32HANDLE_PIPE:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static gboolean
+mono_w32handle_lookup_data (gpointer handle, MonoW32HandleBase **handle_data)
+{
+ gsize index, offset;
+
+ g_assert (handle_data);
+
+ index = SLOT_INDEX ((gsize) handle);
+ if (index >= SLOT_MAX)
+ return FALSE;
+ if (!private_handles [index])
+ return FALSE;
+
+ offset = SLOT_OFFSET ((gsize) handle);
+ if (private_handles [index][offset].type == MONO_W32HANDLE_UNUSED)
+ return FALSE;
+
+ *handle_data = &private_handles [index][offset];
+ return TRUE;
+}
+
+MonoW32HandleType
+mono_w32handle_get_type (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data))
+ return MONO_W32HANDLE_UNUSED; /* An impossible type */
+
+ return handle_data->type;
+}
+
+void
+mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast)
+{
+ MonoW32HandleBase *handle_data;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return;
+ }
+
+#ifdef DEBUG
+ g_message ("%s: setting state of %p to %s (broadcast %s)", __func__,
+ handle, state?"TRUE":"FALSE", broadcast?"TRUE":"FALSE");
+#endif
+
+ if (state == TRUE) {
+ /* Tell everyone blocking on a single handle */
+
+ /* The condition the global signal cond is waiting on is the signalling of
+ * _any_ handle. So lock it before setting the signalled state.
+ */
+ mono_os_mutex_lock (&global_signal_mutex);
+
+ /* This function _must_ be called with
+ * handle->signal_mutex locked
+ */
+ handle_data->signalled=state;
+
+ if (broadcast == TRUE) {
+ mono_os_cond_broadcast (&handle_data->signal_cond);
+ } else {
+ mono_os_cond_signal (&handle_data->signal_cond);
+ }
+
+ /* Tell everyone blocking on multiple handles that something
+ * was signalled
+ */
+ mono_os_cond_broadcast (&global_signal_cond);
+
+ mono_os_mutex_unlock (&global_signal_mutex);
+ } else {
+ handle_data->signalled=state;
+ }
+}
+
+gboolean
+mono_w32handle_issignalled (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(FALSE);
+ }
+
+ return handle_data->signalled;
+}
+
+int
+mono_w32handle_lock_signal_mutex (void)
+{
+#ifdef DEBUG
+ g_message ("%s: lock global signal mutex", __func__);
+#endif
+
+ mono_os_mutex_lock (&global_signal_mutex);
+
+ return 0;
+}
+
+int
+mono_w32handle_unlock_signal_mutex (void)
+{
+#ifdef DEBUG
+ g_message ("%s: unlock global signal mutex", __func__);
+#endif
+
+ mono_os_mutex_unlock (&global_signal_mutex);
+
+ return 0;
+}
+
+int
+mono_w32handle_lock_handle (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+
+#ifdef DEBUG
+ g_message ("%s: locking handle %p", __func__, handle);
+#endif
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(0);
+ }
+
+ mono_w32handle_ref (handle);
+
+ mono_os_mutex_lock (&handle_data->signal_mutex);
+
+ return 0;
+}
+
+int
+mono_w32handle_trylock_handle (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+ int ret;
+
+#ifdef DEBUG
+ g_message ("%s: locking handle %p", __func__, handle);
+#endif
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(0);
+ }
+
+ mono_w32handle_ref (handle);
+
+ ret = mono_os_mutex_trylock (&handle_data->signal_mutex);
+ if (ret != 0) {
+ mono_w32handle_unref (handle);
+ }
+
+ return(ret);
+}
+
+int
+mono_w32handle_unlock_handle (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+
+#ifdef DEBUG
+ g_message ("%s: unlocking handle %p", __func__, handle);
+#endif
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(0);
+ }
+
+ mono_os_mutex_unlock (&handle_data->signal_mutex);
+
+ mono_w32handle_unref (handle);
+
+ return 0;
+}
+
+/*
+ * wapi_init:
+ *
+ * Initialize the io-layer.
+ */
+void
+mono_w32handle_init (void)
+{
+ g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
+ == MONO_W32HANDLE_COUNT);
+
+ /* This is needed by the code in mono_w32handle_new_internal */
+ mono_w32handle_fd_reserve = (eg_getdtablesize () + (HANDLE_PER_SLOT - 1)) & ~(HANDLE_PER_SLOT - 1);
+
+ do {
+ /*
+ * The entries in private_handles reserved for fds are allocated lazily to
+ * save memory.
+ */
+
+ private_handles_count += HANDLE_PER_SLOT;
+ private_handles_slots_count ++;
+ } while(mono_w32handle_fd_reserve > private_handles_count);
+
+ mono_os_mutex_init (&scan_mutex);
+
+ mono_os_cond_init (&global_signal_cond);
+ mono_os_mutex_init (&global_signal_mutex);
+}
+
+static void mono_w32handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles);
+
+void
+mono_w32handle_cleanup (void)
+{
+ int i, j, k;
+
+ g_assert (!shutting_down);
+ shutting_down = TRUE;
+
+ /* Every shared handle we were using ought really to be closed
+ * by now, but to make sure just blow them all away. The
+ * exiting finalizer thread in particular races us to the
+ * program exit and doesn't always win, so it can be left
+ * cluttering up the shared file. Anything else left over is
+ * really a bug.
+ */
+ for(i = SLOT_INDEX (0); private_handles[i] != NULL; i++) {
+ for(j = SLOT_OFFSET (0); j < HANDLE_PER_SLOT; j++) {
+ MonoW32HandleBase *handle_data = &private_handles[i][j];
+ gpointer handle = GINT_TO_POINTER (i*HANDLE_PER_SLOT+j);
+
+ for(k = handle_data->ref; k > 0; k--) {
+ mono_w32handle_unref_full (handle, TRUE);
+ }
+ }
+ }
+
+ for (i = 0; i < SLOT_MAX; ++i)
+ g_free (private_handles [i]);
+}
+
+static void mono_w32handle_init_handle (MonoW32HandleBase *handle,
+ MonoW32HandleType type, gpointer handle_specific)
+{
+ g_assert (!shutting_down);
+
+ handle->type = type;
+ handle->signalled = FALSE;
+ handle->ref = 1;
+
+ mono_os_cond_init (&handle->signal_cond);
+ mono_os_mutex_init (&handle->signal_mutex);
+
+ if (handle_specific)
+ handle->specific = g_memdup (handle_specific, mono_w32handle_ops_typesize (type));
+}
+
+/*
+ * mono_w32handle_new_internal:
+ * @type: Init handle to this type
+ *
+ * Search for a free handle and initialize it. Return the handle on
+ * success and 0 on failure. This is only called from
+ * mono_w32handle_new, and scan_mutex must be held.
+ */
+static guint32 mono_w32handle_new_internal (MonoW32HandleType type,
+ gpointer handle_specific)
+{
+ guint32 i, k, count;
+ static guint32 last = 0;
+ gboolean retry = FALSE;
+
+ g_assert (!shutting_down);
+
+ /* A linear scan should be fast enough. Start from the last
+ * allocation, assuming that handles are allocated more often
+ * than they're freed. Leave the space reserved for file
+ * descriptors
+ */
+
+ if (last < mono_w32handle_fd_reserve) {
+ last = mono_w32handle_fd_reserve;
+ } else {
+ retry = TRUE;
+ }
+
+again:
+ count = last;
+ for(i = SLOT_INDEX (count); i < private_handles_slots_count; i++) {
+ if (private_handles [i]) {
+ for (k = SLOT_OFFSET (count); k < HANDLE_PER_SLOT; k++) {
+ MonoW32HandleBase *handle = &private_handles [i][k];
+
+ if(handle->type == MONO_W32HANDLE_UNUSED) {
+ last = count + 1;
+
+ mono_w32handle_init_handle (handle, type, handle_specific);
+ return (count);
+ }
+ count++;
+ }
+ }
+ }
+
+ if(retry && last > mono_w32handle_fd_reserve) {
+ /* Try again from the beginning */
+ last = mono_w32handle_fd_reserve;
+ goto again;
+ }
+
+ /* Will need to expand the array. The caller will sort it out */
+
+ return(0);
+}
+
+gpointer
+mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific)
+{
+ guint32 handle_idx = 0;
+ gpointer handle;
+
+ g_assert (!shutting_down);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Creating new handle of type %s", __func__,
+ mono_w32handle_ops_typename (type));
+
+ g_assert(!type_is_fd(type));
+
+ mono_os_mutex_lock (&scan_mutex);
+
+ while ((handle_idx = mono_w32handle_new_internal (type, handle_specific)) == 0) {
+ /* Try and expand the array, and have another go */
+ int idx = SLOT_INDEX (private_handles_count);
+ if (idx >= SLOT_MAX) {
+ break;
+ }
+
+ private_handles [idx] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
+
+ private_handles_count += HANDLE_PER_SLOT;
+ private_handles_slots_count ++;
+ }
+
+ mono_os_mutex_unlock (&scan_mutex);
+
+ if (handle_idx == 0) {
+ /* We ran out of slots */
+ handle = INVALID_HANDLE_VALUE;
+ goto done;
+ }
+
+ /* Make sure we left the space for fd mappings */
+ g_assert (handle_idx >= mono_w32handle_fd_reserve);
+
+ handle = GUINT_TO_POINTER (handle_idx);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Allocated new handle %p", __func__, handle);
+
+done:
+ return(handle);
+}
+
+gpointer mono_w32handle_new_fd (MonoW32HandleType type, int fd,
+ gpointer handle_specific)
+{
+ MonoW32HandleBase *handle_data;
+ int fd_index, fd_offset;
+
+ g_assert (!shutting_down);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Creating new handle of type %s", __func__,
+ mono_w32handle_ops_typename (type));
+
+ g_assert(type_is_fd(type));
+
+ if (fd >= mono_w32handle_fd_reserve) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: fd %d is too big", __func__, fd);
+
+ return(GUINT_TO_POINTER (INVALID_HANDLE_VALUE));
+ }
+
+ fd_index = SLOT_INDEX (fd);
+ fd_offset = SLOT_OFFSET (fd);
+
+ /* Initialize the array entries on demand */
+ if (!private_handles [fd_index]) {
+ mono_os_mutex_lock (&scan_mutex);
+
+ if (!private_handles [fd_index])
+ private_handles [fd_index] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT);
+
+ mono_os_mutex_unlock (&scan_mutex);
+ }
+
+ handle_data = &private_handles [fd_index][fd_offset];
+
+ if (handle_data->type != MONO_W32HANDLE_UNUSED) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: fd %d is already in use!", __func__, fd);
+ /* FIXME: clean up this handle? We can't do anything
+ * with the fd, cos thats the new one
+ */
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Assigning new fd handle %p", __func__, (gpointer)(gsize)fd);
+
+ mono_w32handle_init_handle (handle_data, type, handle_specific);
+
+ return(GUINT_TO_POINTER(fd));
+}
+
+gboolean
+mono_w32handle_lookup (gpointer handle, MonoW32HandleType type,
+ gpointer *handle_specific)
+{
+ MonoW32HandleBase *handle_data;
+
+ g_assert (handle_specific);
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(FALSE);
+ }
+
+ if (handle_data->type != type) {
+ return(FALSE);
+ }
+
+ *handle_specific = handle_data->specific;
+
+ return(TRUE);
+}
+
+void
+mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpointer user_data), gpointer user_data)
+{
+ MonoW32HandleBase *handle_data = NULL;
+ gpointer handle;
+ guint32 i, k;
+
+ mono_os_mutex_lock (&scan_mutex);
+
+ for (i = SLOT_INDEX (0); i < private_handles_slots_count; i++) {
+ if (private_handles [i]) {
+ for (k = SLOT_OFFSET (0); k < HANDLE_PER_SLOT; k++) {
+ handle_data = &private_handles [i][k];
+ if (handle_data->type == MONO_W32HANDLE_UNUSED)
+ continue;
+ handle = GUINT_TO_POINTER (i * HANDLE_PER_SLOT + k);
+ if (on_each (handle, handle_data->specific, user_data) == TRUE)
+ goto done;
+ }
+ }
+ }
+
+done:
+ mono_os_mutex_unlock (&scan_mutex);
+}
+
+/* This might list some shared handles twice if they are already
+ * opened by this process, and the check function returns FALSE the
+ * first time. Shared handles that are created during the search are
+ * unreffed if the check function returns FALSE, so callers must not
+ * rely on the handle persisting (unless the check function returns
+ * TRUE)
+ * The caller owns the returned handle.
+ */
+gpointer mono_w32handle_search (MonoW32HandleType type,
+ gboolean (*check)(gpointer test, gpointer user),
+ gpointer user_data,
+ gpointer *handle_specific,
+ gboolean search_shared)
+{
+ MonoW32HandleBase *handle_data = NULL;
+ gpointer ret = NULL;
+ guint32 i, k;
+ gboolean found = FALSE;
+
+ mono_os_mutex_lock (&scan_mutex);
+
+ for (i = SLOT_INDEX (0); !found && i < private_handles_slots_count; i++) {
+ if (private_handles [i]) {
+ for (k = SLOT_OFFSET (0); k < HANDLE_PER_SLOT; k++) {
+ handle_data = &private_handles [i][k];
+
+ if (handle_data->type == type) {
+ ret = GUINT_TO_POINTER (i * HANDLE_PER_SLOT + k);
+ if (check (ret, user_data) == TRUE) {
+ mono_w32handle_ref (ret);
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ mono_os_mutex_unlock (&scan_mutex);
+
+ if (!found) {
+ ret = NULL;
+ goto done;
+ }
+
+ if(handle_specific != NULL) {
+ *handle_specific = handle_data->specific;
+ }
+
+done:
+ return(ret);
+}
+
+void mono_w32handle_ref (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Attempting to ref invalid private handle %p", __func__, handle);
+ return;
+ }
+
+ InterlockedIncrement ((gint32 *)&handle_data->ref);
+
+#ifdef DEBUG_REFS
+ g_message ("%s: %s handle %p ref now %d",
+ __func__, mono_w32handle_ops_typename (handle_data->type), handle, handle_data->ref);
+#endif
+}
+
+static void (*_wapi_handle_ops_get_close_func (MonoW32HandleType type))(gpointer, gpointer);
+
+/* The handle must not be locked on entry to this function */
+static void mono_w32handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles)
+{
+ MonoW32HandleBase *handle_data;
+ gboolean destroy = FALSE, early_exit = FALSE;
+ int thr_ret;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Attempting to unref invalid private handle %p",
+ __func__, handle);
+ return;
+ }
+
+ /* Possible race condition here if another thread refs the
+ * handle between here and setting the type to UNUSED. I
+ * could lock a mutex, but I'm not sure that allowing a handle
+ * reference to reach 0 isn't an application bug anyway.
+ */
+ destroy = (InterlockedDecrement ((gint32 *)&handle_data->ref) ==0);
+
+#ifdef DEBUG_REFS
+ g_message ("%s: %s handle %p ref now %d (destroy %s)",
+ __func__, mono_w32handle_ops_typename (handle_data->type), handle, handle_data->ref, destroy?"TRUE":"FALSE");
+#endif
+
+ if(destroy==TRUE) {
+ /* Need to copy the handle info, reset the slot in the
+ * array, and _only then_ call the close function to
+ * avoid race conditions (eg file descriptors being
+ * closed, and another file being opened getting the
+ * same fd racing the memset())
+ */
+ MonoW32HandleType type;
+ gpointer handle_specific;
+ void (*close_func)(gpointer, gpointer);
+
+ type = handle_data->type;
+ handle_specific = handle_data->specific;
+
+ mono_os_mutex_lock (&scan_mutex);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Destroying handle %p", __func__, handle);
+
+ /* Destroy the mutex and cond var. We hope nobody
+ * tried to grab them between the handle unlock and
+ * now, but pthreads doesn't have a
+ * "unlock_and_destroy" atomic function.
+ */
+ thr_ret = mono_os_mutex_destroy (&handle_data->signal_mutex);
+ /*WARNING gross hack to make cleanup not crash when exiting without the whole runtime teardown.*/
+ if (thr_ret == EBUSY && ignore_private_busy_handles) {
+ early_exit = TRUE;
+ } else {
+ if (thr_ret != 0)
+ g_error ("Error destroying handle %p mutex due to %d\n", handle, thr_ret);
+
+ thr_ret = mono_os_cond_destroy (&handle_data->signal_cond);
+ if (thr_ret == EBUSY && ignore_private_busy_handles)
+ early_exit = TRUE;
+ else if (thr_ret != 0)
+ g_error ("Error destroying handle %p cond var due to %d\n", handle, thr_ret);
+ }
+
+ memset (handle_data, 0, sizeof (MonoW32HandleBase));
+
+ mono_os_mutex_unlock (&scan_mutex);
+
+ if (early_exit)
+ return;
+
+ close_func = _wapi_handle_ops_get_close_func (type);
+ if (close_func != NULL) {
+ close_func (handle, handle_specific);
+ }
+
+ g_free (handle_specific);
+ }
+}
+
+void mono_w32handle_unref (gpointer handle)
+{
+ mono_w32handle_unref_full (handle, FALSE);
+}
+
+void
+mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops)
+{
+ handle_ops [type] = ops;
+}
+
+void mono_w32handle_register_capabilities (MonoW32HandleType type,
+ MonoW32HandleCapability caps)
+{
+ handle_caps[type] = caps;
+}
+
+gboolean mono_w32handle_test_capabilities (gpointer handle,
+ MonoW32HandleCapability caps)
+{
+ MonoW32HandleBase *handle_data;
+ MonoW32HandleType type;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(FALSE);
+ }
+
+ type = handle_data->type;
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: testing 0x%x against 0x%x (%d)", __func__,
+ handle_caps[type], caps, handle_caps[type] & caps);
+
+ return((handle_caps[type] & caps) != 0);
+}
+
+static void (*_wapi_handle_ops_get_close_func (MonoW32HandleType type))(gpointer, gpointer)
+{
+ if (handle_ops[type] != NULL &&
+ handle_ops[type]->close != NULL) {
+ return (handle_ops[type]->close);
+ }
+
+ return (NULL);
+}
+
+void mono_w32handle_ops_close (gpointer handle, gpointer data)
+{
+ MonoW32HandleBase *handle_data;
+ MonoW32HandleType type;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return;
+ }
+
+ type = handle_data->type;
+
+ if (handle_ops[type] != NULL &&
+ handle_ops[type]->close != NULL) {
+ handle_ops[type]->close (handle, data);
+ }
+}
+
+void mono_w32handle_ops_details (MonoW32HandleType type, gpointer data)
+{
+ if (handle_ops[type] != NULL &&
+ handle_ops[type]->details != NULL) {
+ handle_ops[type]->details (data);
+ }
+}
+
+const gchar* mono_w32handle_ops_typename (MonoW32HandleType type)
+{
+ g_assert (handle_ops [type]);
+ g_assert (handle_ops [type]->typename);
+ return handle_ops [type]->typename ();
+}
+
+gsize mono_w32handle_ops_typesize (MonoW32HandleType type)
+{
+ g_assert (handle_ops [type]);
+ g_assert (handle_ops [type]->typesize);
+ return handle_ops [type]->typesize ();
+}
+
+void mono_w32handle_ops_signal (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+ MonoW32HandleType type;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return;
+ }
+
+ type = handle_data->type;
+
+ if (handle_ops[type] != NULL && handle_ops[type]->signal != NULL) {
+ handle_ops[type]->signal (handle);
+ }
+}
+
+gboolean mono_w32handle_ops_own (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+ MonoW32HandleType type;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(FALSE);
+ }
+
+ type = handle_data->type;
+
+ if (handle_ops[type] != NULL && handle_ops[type]->own_handle != NULL) {
+ return(handle_ops[type]->own_handle (handle));
+ } else {
+ return(FALSE);
+ }
+}
+
+gboolean mono_w32handle_ops_isowned (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+ MonoW32HandleType type;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(FALSE);
+ }
+
+ type = handle_data->type;
+
+ if (handle_ops[type] != NULL && handle_ops[type]->is_owned != NULL) {
+ return(handle_ops[type]->is_owned (handle));
+ } else {
+ return(FALSE);
+ }
+}
+
+guint32 mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean alertable)
+{
+ MonoW32HandleBase *handle_data;
+ MonoW32HandleType type;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return(WAIT_FAILED);
+ }
+
+ type = handle_data->type;
+
+ if (handle_ops[type] != NULL &&
+ handle_ops[type]->special_wait != NULL) {
+ return(handle_ops[type]->special_wait (handle, timeout, alertable));
+ } else {
+ return(WAIT_FAILED);
+ }
+}
+
+void mono_w32handle_ops_prewait (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+ MonoW32HandleType type;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data)) {
+ return;
+ }
+
+ type = handle_data->type;
+
+ if (handle_ops[type] != NULL &&
+ handle_ops[type]->prewait != NULL) {
+ handle_ops[type]->prewait (handle);
+ }
+}
+
+static void
+spin (guint32 ms)
+{
+ struct timespec sleepytime;
+
+ g_assert (ms < 1000);
+
+ sleepytime.tv_sec = 0;
+ sleepytime.tv_nsec = ms * 1000000;
+ nanosleep (&sleepytime, NULL);
+}
+
+gboolean
+mono_w32handle_count_signalled_handles (guint32 numhandles, gpointer *handles,
+ gboolean waitall, guint32 *retcount, guint32 *lowest)
+{
+ guint32 count, i, iter=0;
+ gboolean ret;
+ int thr_ret;
+
+ /* Lock all the handles, with backoff */
+again:
+ for(i=0; i<numhandles; i++) {
+ gpointer handle = handles[i];
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: attempting to lock %p", __func__, handle);
+
+ thr_ret = mono_w32handle_trylock_handle (handle);
+
+ if (thr_ret != 0) {
+ /* Bummer */
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: attempt failed for %p: %s", __func__,
+ handle, strerror (thr_ret));
+
+ while (i--) {
+ handle = handles[i];
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+ }
+
+ /* If iter ever reaches 100 the nanosleep will
+ * return EINVAL immediately, but we have a
+ * design flaw if that happens.
+ */
+ iter++;
+ if(iter==100) {
+ g_warning ("%s: iteration overflow!",
+ __func__);
+ iter=1;
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Backing off for %d ms", __func__,
+ iter*10);
+ spin (10 * iter);
+
+ goto again;
+ }
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Locked all handles", __func__);
+
+ count=0;
+ *lowest=numhandles;
+
+ for(i=0; i<numhandles; i++) {
+ gpointer handle = handles[i];
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Checking handle %p", __func__, handle);
+
+ if(((mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_OWN)==TRUE) &&
+ (mono_w32handle_ops_isowned (handle) == TRUE)) ||
+ (mono_w32handle_issignalled (handle))) {
+ count++;
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Handle %p signalled", __func__,
+ handle);
+ if(*lowest>i) {
+ *lowest=i;
+ }
+ }
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: %d event handles signalled", __func__, count);
+
+ if ((waitall == TRUE && count == numhandles) ||
+ (waitall == FALSE && count > 0)) {
+ ret=TRUE;
+ } else {
+ ret=FALSE;
+ }
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: Returning %d", __func__, ret);
+
+ *retcount=count;
+
+ return(ret);
+}
+
+void mono_w32handle_unlock_handles (guint32 numhandles, gpointer *handles)
+{
+ guint32 i;
+ int thr_ret;
+
+ for(i=0; i<numhandles; i++) {
+ gpointer handle = handles[i];
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: unlocking handle %p", __func__, handle);
+
+ thr_ret = mono_w32handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+ }
+}
+
+static int
+mono_w32handle_timedwait_signal_naked (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout, gboolean poll, gboolean *alerted)
+{
+ int res;
+
+ if (!poll) {
+ res = mono_os_cond_timedwait (cond, mutex, timeout);
+ } else {
+ /* This is needed when waiting for process handles */
+ if (!alerted) {
+ /*
+ * pthread_cond_(timed)wait() can return 0 even if the condition was not
+ * signalled. This happens at least on Darwin. We surface this, i.e., we
+ * get spurious wake-ups.
+ *
+ * http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
+ */
+ res = mono_os_cond_timedwait (cond, mutex, timeout);
+ } else {
+ if (timeout < 100) {
+ /* Real timeout is less than 100ms time */
+ res = mono_os_cond_timedwait (cond, mutex, timeout);
+ } else {
+ res = mono_os_cond_timedwait (cond, mutex, 100);
+
+ /* Mask the fake timeout, this will cause
+ * another poll if the cond was not really signaled
+ */
+ if (res == ETIMEDOUT)
+ res = 0;
+ }
+ }
+ }
+
+ return res;
+}
+
+static void
+signal_global (gpointer unused)
+{
+ /* If we reach here, then interrupt token is set to the flag value, which
+ * means that the target thread is either
+ * - before the first CAS in timedwait, which means it won't enter the wait.
+ * - it is after the first CAS, so it is already waiting, or it will enter
+ * the wait, and it will be interrupted by the broadcast. */
+ mono_os_mutex_lock (&global_signal_mutex);
+ mono_os_cond_broadcast (&global_signal_cond);
+ mono_os_mutex_unlock (&global_signal_mutex);
+}
+
+int
+mono_w32handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted)
+{
+ int res;
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: waiting for global", __func__);
+
+ if (alerted)
+ *alerted = FALSE;
+
+ if (alerted) {
+ mono_thread_info_install_interrupt (signal_global, NULL, alerted);
+ if (*alerted)
+ return 0;
+ }
+
+ res = mono_w32handle_timedwait_signal_naked (&global_signal_cond, &global_signal_mutex, timeout, poll, alerted);
+
+ if (alerted)
+ mono_thread_info_uninstall_interrupt (alerted);
+
+ return res;
+}
+
+static void
+signal_handle_and_unref (gpointer handle)
+{
+ MonoW32HandleBase *handle_data;
+ mono_cond_t *cond;
+ mono_mutex_t *mutex;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data))
+ g_error ("cannot signal unknown handle %p", handle);
+
+ /* If we reach here, then interrupt token is set to the flag value, which
+ * means that the target thread is either
+ * - before the first CAS in timedwait, which means it won't enter the wait.
+ * - it is after the first CAS, so it is already waiting, or it will enter
+ * the wait, and it will be interrupted by the broadcast. */
+ cond = &handle_data->signal_cond;
+ mutex = &handle_data->signal_mutex;
+
+ mono_os_mutex_lock (mutex);
+ mono_os_cond_broadcast (cond);
+ mono_os_mutex_unlock (mutex);
+
+ mono_w32handle_unref (handle);
+}
+
+int
+mono_w32handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted)
+{
+ MonoW32HandleBase *handle_data;
+ int res;
+
+ if (!mono_w32handle_lookup_data (handle, &handle_data))
+ g_error ("cannot wait on unknown handle %p", handle);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: waiting for %p (type %s)", __func__, handle,
+ mono_w32handle_ops_typename (mono_w32handle_get_type (handle)));
+
+ if (alerted)
+ *alerted = FALSE;
+
+ if (alerted) {
+ mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
+ if (*alerted)
+ return 0;
+ mono_w32handle_ref (handle);
+ }
+
+ res = mono_w32handle_timedwait_signal_naked (&handle_data->signal_cond, &handle_data->signal_mutex, timeout, poll, alerted);
+
+ if (alerted) {
+ mono_thread_info_uninstall_interrupt (alerted);
+ if (!*alerted) {
+ /* if it is alerted, then the handle is unref in the interrupt callback */
+ mono_w32handle_unref (handle);
+ }
+ }
+
+ return res;
+}
+
+void mono_w32handle_dump (void)
+{
+ MonoW32HandleBase *handle_data;
+ guint32 i, k;
+
+ mono_os_mutex_lock (&scan_mutex);
+
+ for(i = SLOT_INDEX (0); i < private_handles_slots_count; i++) {
+ if (private_handles [i]) {
+ for (k = SLOT_OFFSET (0); k < HANDLE_PER_SLOT; k++) {
+ handle_data = &private_handles [i][k];
+
+ if (handle_data->type == MONO_W32HANDLE_UNUSED) {
+ continue;
+ }
+
+ g_print ("%3x [%7s] %s %d ",
+ i * HANDLE_PER_SLOT + k,
+ mono_w32handle_ops_typename (handle_data->type),
+ handle_data->signalled?"Sg":"Un",
+ handle_data->ref);
+ mono_w32handle_ops_details (handle_data->type, handle_data->specific);
+ g_print ("\n");
+ }
+ }
+ }
+
+ mono_os_mutex_unlock (&scan_mutex);
+}
+
+#endif /* !defined(HOST_WIN32) */
--- /dev/null
+
+#ifndef _MONO_UTILS_W32HANDLE_H_
+#define _MONO_UTILS_W32HANDLE_H_
+
+#include <config.h>
+
+#if !defined(HOST_WIN32)
+
+#include <glib.h>
+
+#define INVALID_HANDLE_VALUE (gpointer)-1
+
+typedef enum {
+ MONO_W32HANDLE_UNUSED = 0,
+ MONO_W32HANDLE_FILE,
+ MONO_W32HANDLE_CONSOLE,
+ MONO_W32HANDLE_THREAD,
+ MONO_W32HANDLE_SEM,
+ MONO_W32HANDLE_MUTEX,
+ MONO_W32HANDLE_EVENT,
+ MONO_W32HANDLE_SOCKET,
+ MONO_W32HANDLE_FIND,
+ MONO_W32HANDLE_PROCESS,
+ MONO_W32HANDLE_PIPE,
+ MONO_W32HANDLE_NAMEDMUTEX,
+ MONO_W32HANDLE_NAMEDSEM,
+ MONO_W32HANDLE_NAMEDEVENT,
+ MONO_W32HANDLE_COUNT
+} MonoW32HandleType;
+
+typedef struct
+{
+ void (*close)(gpointer handle, gpointer data);
+
+ /* SignalObjectAndWait */
+ void (*signal)(gpointer signal);
+
+ /* Called by WaitForSingleObject and WaitForMultipleObjects,
+ * with the handle locked (shared handles aren't locked.)
+ * Returns TRUE if ownership was established, false otherwise.
+ */
+ gboolean (*own_handle)(gpointer handle);
+
+ /* Called by WaitForSingleObject and WaitForMultipleObjects, if the
+ * handle in question is "ownable" (ie mutexes), to see if the current
+ * thread already owns this handle
+ */
+ gboolean (*is_owned)(gpointer handle);
+
+ /* Called by WaitForSingleObject and WaitForMultipleObjects,
+ * if the handle in question needs a special wait function
+ * instead of using the normal handle signal mechanism.
+ * Returns the WaitForSingleObject return code.
+ */
+ guint32 (*special_wait)(gpointer handle, guint32 timeout, gboolean alertable);
+
+ /* Called by WaitForSingleObject and WaitForMultipleObjects,
+ * if the handle in question needs some preprocessing before the
+ * signal wait.
+ */
+ void (*prewait)(gpointer handle);
+
+ /* Called when dumping the handles */
+ void (*details)(gpointer data);
+
+ /* Called to get the name of the handle type */
+ const gchar* (*typename) (void);
+
+ /* Called to get the size of the handle type */
+ gsize (*typesize) (void);
+} MonoW32HandleOps;
+
+typedef enum {
+ MONO_W32HANDLE_CAP_WAIT = 0x01,
+ MONO_W32HANDLE_CAP_SIGNAL = 0x02,
+ MONO_W32HANDLE_CAP_OWN = 0x04,
+ MONO_W32HANDLE_CAP_SPECIAL_WAIT = 0x08,
+} MonoW32HandleCapability;
+
+extern guint32 mono_w32handle_fd_reserve;
+
+void
+mono_w32handle_init (void);
+
+void
+mono_w32handle_cleanup (void);
+
+void
+mono_w32handle_register_ops (MonoW32HandleType type, MonoW32HandleOps *ops);
+
+gpointer
+mono_w32handle_new (MonoW32HandleType type, gpointer handle_specific);
+
+gpointer
+mono_w32handle_new_fd (MonoW32HandleType type, int fd, gpointer handle_specific);
+
+MonoW32HandleType
+mono_w32handle_get_type (gpointer handle);
+
+gboolean
+mono_w32handle_lookup (gpointer handle, MonoW32HandleType type, gpointer *handle_specific);
+
+gpointer
+mono_w32handle_search (MonoW32HandleType type, gboolean (*check)(gpointer, gpointer), gpointer user_data, gpointer *handle_specific, gboolean search_shared);
+
+void
+mono_w32handle_foreach (gboolean (*on_each)(gpointer handle, gpointer data, gpointer user_data), gpointer user_data);
+
+void
+mono_w32handle_dump (void);
+
+void
+mono_w32handle_ref (gpointer handle);
+
+void
+mono_w32handle_unref (gpointer handle);
+
+void
+mono_w32handle_register_capabilities (MonoW32HandleType type, MonoW32HandleCapability caps);
+
+gboolean
+mono_w32handle_test_capabilities (gpointer handle, MonoW32HandleCapability caps);
+
+void
+mono_w32handle_ops_close (gpointer handle, gpointer data);
+
+void
+mono_w32handle_ops_signal (gpointer handle);
+
+gboolean
+mono_w32handle_ops_own (gpointer handle);
+
+gboolean
+mono_w32handle_ops_isowned (gpointer handle);
+
+guint32
+mono_w32handle_ops_specialwait (gpointer handle, guint32 timeout, gboolean alertable);
+
+void
+mono_w32handle_ops_prewait (gpointer handle);
+
+void
+mono_w32handle_ops_details (MonoW32HandleType type, gpointer data);
+
+const gchar*
+mono_w32handle_ops_typename (MonoW32HandleType type);
+
+gsize
+mono_w32handle_ops_typesize (MonoW32HandleType type);
+
+gboolean
+mono_w32handle_count_signalled_handles (guint32 numhandles, gpointer *handles, gboolean waitall, guint32 *retcount, guint32 *lowest);
+
+void
+mono_w32handle_unlock_handles (guint32 numhandles, gpointer *handles);
+
+int
+mono_w32handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean poll, gboolean *alerted);
+
+int
+mono_w32handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted);
+
+void
+mono_w32handle_set_signal_state (gpointer handle, gboolean state, gboolean broadcast);
+
+gboolean
+mono_w32handle_issignalled (gpointer handle);
+
+int
+mono_w32handle_lock_handle (gpointer handle);
+
+int
+mono_w32handle_trylock_handle (gpointer handle);
+
+int
+mono_w32handle_unlock_handle (gpointer handle);
+
+int
+mono_w32handle_lock_signal_mutex (void);
+
+int
+mono_w32handle_unlock_signal_mutex (void);
+
+#endif /* !defined(HOST_WIN32) */
+
+#endif /* _MONO_UTILS_W32HANDLE_H_ */
open (OUT, ">$outfile") || die "Cannot open '$outfile': $!\n";
print OUT "; file generated by create-windef.pl\n";
-#print OUT "LIBRARY $dllname\nEXPORTS\n";
+print OUT "EXPORTS\n";
print OUT join ("\n", @symbols);
print OUT "\n";
-<?xml version="1.0" encoding="utf-8"?>\r
+<?xml version="1.0" encoding="utf-8"?>\r
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
<ItemGroup Label="ProjectConfigurations">\r
<ProjectConfiguration Include="Debug|Win32">\r
<ClCompile Include="..\eglib\src\gtimer-win32.c" />\r
<ClCompile Include="..\eglib\src\gunicode.c" />\r
<ClCompile Include="..\eglib\src\gutf8.c" />\r
- <ClCompile Include="..\eglib\src\vasprintf.c" />\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\eglib\src\glib.h" />\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<ImportGroup Label="ExtensionTargets">\r
</ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
mono_get_uintptr_class
mono_get_void_class
mono_guid_to_string
+mono_guid_to_string_minimal
mono_image_add_to_name_cache
mono_image_addref
mono_image_close
mono_lock_free_queue_node_init
mono_lock_free_queue_node_unpoison
mono_locks_dump
+mono_log_close_logfile
+mono_log_close_syslog
+mono_log_open_logfile
+mono_log_open_syslog
+mono_log_write_logfile
+mono_log_write_syslog
mono_lookup_icall_symbol
mono_lookup_internal_call
mono_lookup_pinvoke_call
mono_security_core_clr_set_options
mono_security_enable_core_clr
mono_security_set_core_clr_platform_callback
+mono_set_allocator_vtable
mono_set_assemblies_path
mono_set_break_policy
mono_set_config_dir
mono_threads_attach_tools_thread
mono_threads_detach_coop
mono_threads_enter_gc_safe_region
+mono_threads_enter_gc_safe_region_unbalanced
mono_threads_enter_gc_unsafe_region
+mono_threads_enter_gc_unsafe_region_unbalanced
mono_threads_exit_gc_safe_region
+mono_threads_exit_gc_safe_region_unbalanced
mono_threads_exit_gc_unsafe_region
+mono_threads_exit_gc_unsafe_region_unbalanced
mono_threads_get_default_stacksize
mono_threads_request_thread_dump
mono_threads_set_default_stacksize
mono_trace_set_level_string
mono_trace_set_log_handler
+mono_trace_set_logdest_string
+mono_trace_set_logheader_string
mono_trace_set_mask_string
mono_trace_set_print_handler
mono_trace_set_printerr_handler
mono_get_uintptr_class
mono_get_void_class
mono_guid_to_string
+mono_guid_to_string_minimal
mono_image_add_to_name_cache
mono_image_addref
mono_image_close
mono_lock_free_queue_node_init
mono_lock_free_queue_node_unpoison
mono_locks_dump
+mono_log_close_logfile
+mono_log_close_syslog
+mono_log_open_logfile
+mono_log_open_syslog
+mono_log_write_logfile
+mono_log_write_syslog
mono_lookup_icall_symbol
mono_lookup_internal_call
mono_lookup_pinvoke_call
mono_security_core_clr_set_options
mono_security_enable_core_clr
mono_security_set_core_clr_platform_callback
+mono_set_allocator_vtable
mono_set_assemblies_path
mono_set_break_policy
mono_set_config_dir
mono_threads_attach_tools_thread
mono_threads_detach_coop
mono_threads_enter_gc_safe_region
+mono_threads_enter_gc_safe_region_unbalanced
mono_threads_enter_gc_unsafe_region
+mono_threads_enter_gc_unsafe_region_unbalanced
mono_threads_exit_gc_safe_region
+mono_threads_exit_gc_safe_region_unbalanced
mono_threads_exit_gc_unsafe_region
+mono_threads_exit_gc_unsafe_region_unbalanced
mono_threads_get_default_stacksize
mono_threads_request_thread_dump
mono_threads_set_default_stacksize
mono_trace_set_level_string
mono_trace_set_log_handler
+mono_trace_set_logdest_string
+mono_trace_set_logheader_string
mono_trace_set_mask_string
mono_trace_set_print_handler
mono_trace_set_printerr_handler
PLATFORM_PATH_SEPARATOR = :
endif
+if INSTALL_MOBILE_STATIC
+# ILASM.exe has features which a mobile_static runtime will not support.
+# It is invoked with an external mono when used in the runtime.
+# We skip it here because otherwise it will fail to verify.
+MOBILE_STATIC_FILTER=grep -v ilasm
+else
+MOBILE_STATIC_FILTER=echo
+endif
+
# Compile all assemblies with the verifier turned on. Code must be valid but not verifiable.
# TODO it would be nice to split assemblies without unsafe code to use the verifier with verifiable mode.
# Skip binary_reference_assemblies because they contain metadata only
mcs-compileall: mono-wrapper etc/mono/config
+ export verifiable_files=`ls "$(mcs_topdir)/class/lib/$$profile/" | grep -E '\.(dll|exe)$$' | $(MOBILE_STATIC_FILTER)` ; \
save_MONO_PATH=$$MONO_PATH; mcs_topdir=`cd $(mcs_topdir) && $(cur_dir_cmd)`; ok=:; \
for profile in $(test_profiles); do \
if [ "binary_reference_assemblies" = "$$profile" ]; then \
MONO_PATH="$$mcs_topdir/class/lib/$$profile$(PLATFORM_PATH_SEPARATOR)$$save_MONO_PATH"; \
fi; \
export MONO_PATH; \
- for i in $(mcs_topdir)/class/lib/$$profile/*.{dll,exe}; do \
+ for stub in $$verifiable_files; do \
+ i=$(mcs_topdir)/class/lib/$$profile/$$stub ; \
+ echo $$i ; \
if [ ! -f $$i ] ; then \
continue ; \
fi ; \
#include <mono/jit/jit.h>
#include <mono/metadata/environment.h>
+#include <mono/utils/mono-publib.h>
#include <stdlib.h>
/*
mono_jit_exec (domain, assembly, argc, argv);
}
+static int malloc_count = 0;
+
+static void* custom_malloc(size_t bytes)
+{
+ ++malloc_count;
+ return malloc(bytes);
+}
int
main(int argc, char* argv[]) {
}
file = argv [1];
+ MonoAllocatorVTable mem_vtable = {custom_malloc};
+ mono_set_allocator_vtable (&mem_vtable);
+
/*
* Load the default Mono configuration file, this is needed
* if you are planning on using the dllmaps defined on the
retval = mono_environment_exitcode_get ();
mono_jit_cleanup (domain);
+
+ fprintf (stdout, "custom malloc calls = %d\n", malloc_count);
+
return retval;
}
if [[ ${CI_TAGS} == 'mobile_static' ]];
then
EXTRA_CONF_FLAGS="${EXTRA_CONF_FLAGS} --with-runtime_preset=mobile_static";
+elif [[ ${CI_TAGS} == 'acceptance-tests' ]];
+ then
+ EXTRA_CONF_FLAGS="${EXTRA_CONF_FLAGS} --prefix=${WORKSPACE}/tmp/mono-acceptance-tests --with-sgen-default-concurrent=yes";
elif [[ ${label} != w* ]] && [[ ${label} != 'debian-ppc64el' ]] && [[ ${label} != 'centos-s390x' ]];
then
# Override the defaults to skip profiles
# we don't run the test suite on Windows PRs, we just ensure the build succeeds, so end here
fi
-make check-ci
+if [[ ${CI_TAGS} == 'acceptance-tests' ]];
+then $(dirname "${BASH_SOURCE[0]}")/run-test-acceptance-tests.sh
+else make check-ci
+fi
\ No newline at end of file
--- /dev/null
+#!/bin/bash -e
+
+export TESTCMD=`dirname "${BASH_SOURCE[0]}"`/run-step.sh
+
+make install # Roslyn tests need a Mono installation
+
+LANG=en_US.UTF-8 ${TESTCMD} --label=check-ms-test-suite --timeout=30m make -C acceptance-tests check-ms-test-suite
+
+total_tests=$(find acceptance-tests/ -name TestResult*xml | xargs cat | grep -c "<test-case")
+if [ "$total_tests" -lt "1600" ]
+ then echo "*** NOT ENOUGH TEST RESULTS RECORDED, MARKING FAILURE ***"
+ exit 1
+fi
+
+${TESTCMD} --label=check-roslyn --timeout=30m make -C acceptance-tests check-roslyn PREFIX=${WORKSPACE}/tmp/mono-acceptance-tests
+rm -rf ${WORKSPACE}/tmp/mono-acceptance-tests # cleanup the Mono installation used for Roslyn tests
+
+${TESTCMD} --label=coreclr-compile-tests --timeout=80m --fatal make -C acceptance-tests coreclr-compile-tests
+${TESTCMD} --label=coreclr-runtest-basic --timeout=10m make -C acceptance-tests coreclr-runtest-basic
+${TESTCMD} --label=coreclr-runtest-coremanglib --timeout=10m make -C acceptance-tests coreclr-runtest-coremanglib
+${TESTCMD} --label=coreclr-gcstress --timeout=1200m make -C acceptance-tests coreclr-gcstress
export TESTCMD=`dirname "${BASH_SOURCE[0]}"`/run-step.sh
-${TESTCMD} --label=mini --timeout=5m make -w -C mono/mini -k check
+${TESTCMD} --label=mini --timeout=5m make -w -C mono/mini -k check check-seq-points EMIT_NUNIT=1
${TESTCMD} --label=runtime --timeout=160m make -w -C mono/tests -k test-wrench V=1 CI=1
${TESTCMD} --label=corlib --timeout=30m make -w -C mcs/class/corlib run-test
${TESTCMD} --label=verify --timeout=15m make -w -C runtime mcs-compileall
${TESTCMD} --label=Microsoft.Build.Tasks --timeout=5m make -w -C mcs/class/Microsoft.Build.Tasks run-test
${TESTCMD} --label=Microsoft.Build.Utilities --timeout=5m make -w -C mcs/class/Microsoft.Build.Utilities run-test
${TESTCMD} --label=Mono.C5 --timeout=5m make -w -C mcs/class/Mono.C5 run-test
+${TESTCMD} --label=Mono.Tasklets --timeout=5m make -w -C mcs/class/Mono.Tasklets run-test
${TESTCMD} --label=System.Configuration --timeout=5m make -w -C mcs/class/System.Configuration run-test
${TESTCMD} --label=System.Transactions --timeout=5m make -w -C mcs/class/System.Transactions run-test
${TESTCMD} --label=System.Web.Extensions --timeout=5m make -w -C mcs/class/System.Web.Extensions run-test
${TESTCMD} --label=corlib --timeout=30m make -w -C mcs/class/corlib run-test
${TESTCMD} --label=verify --timeout=15m make -w -C runtime mcs-compileall
${TESTCMD} --label=profiler --timeout=30m make -w -C mono/profiler -k check
-${TESTCMD} --label=compiler --timeout=30m make -w -C mcs/tests run-test
-${TESTCMD} --label=compiler-errors --timeout=30m make -w -C mcs/errors run-test
${TESTCMD} --label=System --timeout=10m make -w -C mcs/class/System run-test
${TESTCMD} --label=System.XML --timeout=5m make -w -C mcs/class/System.XML run-test
${TESTCMD} --label=Mono.Security --timeout=5m make -w -C mcs/class/Mono.Security run-test
#
# This is a python script and a set of make targets to implement support for conditional submodules
-# There should be a SUBMODULES.json file which contains information about the submodules.
+# Set the SUBMODULES_CONFIG_FILE make variable to the srcdir path of a SUBMODULES.json file which contains information about the submodules.
#
-CONFIG=SUBMODULES.json
SCRIPT=$(top_srcdir)/scripts/submodules/versions.py
# usage $(call ValidateVersionTemplate (name,MAKEFILE VAR,repo name))
define ValidateVersionTemplate
#$(eval REPOSITORY_$(2):=$(shell test -z $(3) && echo $(1) || echo "$(3)"))
-#$(eval DIRECTORY_$(2):=$(shell python $(SCRIPT) get-dir $(1)))
+#$(eval DIRECTORY_$(2):=$(shell python $(SCRIPT) $(SUBMODULES_CONFIG_FILE) get-dir $(1)))
#$(eval DIRECTORY_$(2):=$(shell test -z $(DIRECTORY_$(2)) && echo $(1) || echo $(DIRECTORY_$(2))))
-#$(eval MODULE_$(2):=$(shell python $(SCRIPT) get-url $(1)))
-#$(eval NEEDED_$(2)_VERSION:=$(shell python $(SCRIPT) get-rev $(1)))
-#$(eval $(2)_BRANCH_AND_REMOTE:=$(shell python $(SCRIPT) get-remote-branch $(1)))
+#$(eval MODULE_$(2):=$(shell python $(SCRIPT) $(SUBMODULES_CONFIG_FILE) get-url $(1)))
+#$(eval NEEDED_$(2)_VERSION:=$(shell python $(SCRIPT) $(SUBMODULES_CONFIG_FILE) get-rev $(1)))
+#$(eval $(2)_BRANCH_AND_REMOTE:=$(shell python $(SCRIPT) $(SUBMODULES_CONFIG_FILE) get-remote-branch $(1)))
#$(eval $(2)_VERSION:=$$$$(shell cd $($(2)_PATH) 2>/dev/null && git rev-parse HEAD ))
__bump-version-%:
@if [ "$(REV)" = "" ]; then echo "Usage: make bump-version-$* REV=<ref>"; exit 1; fi
- python $(SCRIPT) set-rev $* $(REV)
- @if [ "$(COMMIT)" = "1" ]; then echo "[submodules] Bump $* to pick up $(REV)." | git commit -F - $(CONFIG); fi
+ python $(SCRIPT) $(SUBMODULES_CONFIG_FILE) set-rev $* $(REV)
+ @if [ "$(COMMIT)" = "1" ]; then echo "[submodules] Bump $* to pick up $(REV)." | git commit -F - $(SUBMODULES_CONFIG_FILE); fi
__bump-branch-%:
@if [ "$(BRANCH)" = "" ]; then echo "Usage: make bump-branch-$* BRANCH=<branch> REMOTE_BRANCH=<remote branch>"; exit 1; fi
@if [ "$(REMOTE_BRANCH)" == "" ]; then echo "Usage: make bump-branch-$* BRANCH=<branch> REMOTE_BRANCH=<remote branch>"; exit 1; fi
- python $(SCRIPT) set-branch $* $(BRANCH)
- python $(SCRIPT) set-remote-branch $* $(REMOTE_BRANCH)
- @if [ "$(COMMIT)" = "1" ]; then echo "[submodules] Bump $* to switch to $(BRANCH) $(REMOTE BRANCH)." | git commit -F - $(CONFIG); fi
+ python $(SCRIPT) $(SUBMODULES_CONFIG_FILE) set-branch $* $(BRANCH)
+ python $(SCRIPT) $(SUBMODULES_CONFIG_FILE) set-remote-branch $* $(REMOTE_BRANCH)
+ @if [ "$(COMMIT)" = "1" ]; then echo "[submodules] Bump $* to switch to $(BRANCH) $(REMOTE BRANCH)." | git commit -F - $(SUBMODULES_CONFIG_FILE); fi
__bump-current-version-%:
REV=$(shell cd $(ACCEPTANCE_TESTS_PATH)/$* && git log -1 --pretty=format:%H); \
- python $(SCRIPT) set-rev $* $$REV; \
- if [ "$(COMMIT)" = "1" ]; then echo "[submodules] Bump $* to pick up $$REV:" | git commit -F - $(CONFIG); fi
+ python $(SCRIPT) $(SUBMODULES_CONFIG_FILE) set-rev $* $$REV; \
+ if [ "$(COMMIT)" = "1" ]; then echo "[submodules] Bump $* to pick up $$REV:" | git commit -F - $(SUBMODULES_CONFIG_FILE); fi
sys.exit(1)
-if len(sys.argv) < 2:
- print("Usage: versions.py <command>")
+if len(sys.argv) < 3:
+ print("Usage: versions.py <path to SUBMODULES.json> <command>")
sys.exit(1)
-CONFIG_FILE = "SUBMODULES.json"
-command = sys.argv[1]
+CONFIG_FILE = sys.argv[1]
+command = sys.argv[2]
submodules = json.load(open(CONFIG_FILE))
if command == "get-rev":
- mod = find_module(submodules, sys.argv[2])
+ mod = find_module(submodules, sys.argv[3])
print(mod["rev"])
elif command == "get-url":
- mod = find_module(submodules, sys.argv[2])
+ mod = find_module(submodules, sys.argv[3])
print(mod["url"])
elif command == "get-dir":
- mod = find_module(submodules, sys.argv[2])
+ mod = find_module(submodules, sys.argv[3])
print(mod["directory"])
elif command == "get-remote-branch":
- mod = find_module(submodules, sys.argv[2])
+ mod = find_module(submodules, sys.argv[3])
print(mod["remote-branch"])
elif command == "set-rev":
- mod = find_module(submodules, sys.argv[2])
- mod["rev"] = sys.argv[3]
+ mod = find_module(submodules, sys.argv[3])
+ mod["rev"] = sys.argv[4]
json.dump(submodules, open(CONFIG_FILE, "w"), indent = 2)
elif command == "set-branch":
- mod = find_module(submodules, sys.argv[2])
- mod["branch"] = sys.argv[3]
+ mod = find_module(submodules, sys.argv[3])
+ mod["branch"] = sys.argv[4]
json.dump(submodules, open(CONFIG_FILE, "w"), indent = 2)
elif command == "set-remote-branch":
- mod = find_module(submodules, sys.argv[2])
- mod["remote-branch"] = sys.argv[3]
+ mod = find_module(submodules, sys.argv[3])
+ mod["remote-branch"] = sys.argv[4]
json.dump(submodules, open(CONFIG_FILE, "w"), indent = 2)
elif command == "cat":
print(json.dumps(submodules, indent = 2))
static List<string> Abis = new List<string> ();
static string OutputDir;
+ static bool XamarinAndroid;
static string MonodroidDir = @"";
+ static string AndroidNdkPath = @"";
static string MaccoreDir = @"";
public enum TargetPlatform
Targets.Add (new Target {
Platform = TargetPlatform.Android,
Triple = "i686-none-linux-android",
- Build = "mono-x86",
+ Build = XamarinAndroid ? "x86" : "mono-x86",
Defines = { "TARGET_X86" }
});
Targets.Add (new Target {
Platform = TargetPlatform.Android,
Triple = "x86_64-none-linux-android",
- Build = "mono-x86_64",
+ Build = XamarinAndroid ? "x86_64" : "mono-x86_64",
Defines = { "TARGET_AMD64" }
});
Targets.Add (new Target {
Platform = TargetPlatform.Android,
Triple = "armv5-none-linux-androideabi",
- Build = "mono-armv6",
+ Build = XamarinAndroid ? "armeabi" : "mono-armv6",
Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5" }
});
Targets.Add (new Target {
Platform = TargetPlatform.Android,
Triple = "armv7-none-linux-androideabi",
- Build = "mono-armv7",
+ Build = XamarinAndroid ? "armeabi-v7a" : "mono-armv7",
Defines = { "TARGET_ARM", "ARM_FPU_VFP", "HAVE_ARMV5", "HAVE_ARMV6",
"HAVE_ARMV7"
}
Targets.Add (new Target {
Platform = TargetPlatform.Android,
Triple = "aarch64-v8a-linux-android",
- Build = "mono-aarch64",
+ Build = XamarinAndroid ? "arm64-v8a" : "mono-aarch64",
Defines = { "TARGET_ARM64" }
});
static string GetAndroidNdkPath()
{
+ if (!String.IsNullOrEmpty (AndroidNdkPath))
+ return AndroidNdkPath;
+
// Find the Android NDK's path from Monodroid's config.
var configFile = Path.Combine(MonodroidDir, "env.config");
if (!File.Exists(configFile))
{ "abi=", "ABI triple to generate", v => Abis.Add(v) },
{ "o|out=", "output directory", v => OutputDir = v },
{ "maccore=", "include directory", v => MaccoreDir = v },
- { "monodroid=", "include directory", v => MonodroidDir = v },
+ { "monodroid=", "top monodroid directory", v => MonodroidDir = v },
+ { "android-ndk=", "Path to Android NDK", v => AndroidNdkPath = v },
+ { "xamarin-android", "Generate for Xamarin.Android instead of monodroid", v => XamarinAndroid = true },
{ "mono=", "include directory", v => MonoDir = v },
{ "h|help", "show this message and exit", v => showHelp = v != null },
};
string targetPath;
switch (target.Platform) {
case TargetPlatform.Android:
- targetPath = Path.Combine (MonodroidDir, "builds");
+ targetPath = Path.Combine (MonodroidDir, XamarinAndroid ? "build-tools/mono-runtimes/obj/Debug" : "builds");
break;
case TargetPlatform.WatchOS:
case TargetPlatform.iOS: