From: Marcos Henrich Date: Wed, 13 Jul 2016 16:41:22 +0000 (+0100) Subject: Merge pull request #3248 from esdrubal/web_request_abort X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=725892b35c29fe919d6e58305ac241f6cbd01018;hp=6f261e6bb65835133e582d77c56545372197af0d;p=mono.git Merge pull request #3248 from esdrubal/web_request_abort [System] EndRead now throws WebException on abort. --- diff --git a/eglib/configure.ac b/eglib/configure.ac index 7622701ef45..dbca788afd6 100644 --- a/eglib/configure.ac +++ b/eglib/configure.ac @@ -138,6 +138,15 @@ AC_CHECK_FUNCS(strlcpy stpcpy strtok_r rewinddir vasprintf) 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 @@ -151,7 +160,7 @@ elif test x$target_ios = xno; then 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) diff --git a/eglib/src/Makefile.am b/eglib/src/Makefile.am index 31771dfd9a1..1527ba26d30 100644 --- a/eglib/src/Makefile.am +++ b/eglib/src/Makefile.am @@ -11,14 +11,6 @@ unix_files = \ 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 @@ -32,7 +24,6 @@ libeglib_la_SOURCES = \ garray.c \ gbytearray.c \ gerror.c \ - vasprintf.h \ ghashtable.c \ giconv.c \ gmem.c \ @@ -55,8 +46,7 @@ libeglib_la_SOURCES = \ gutf8.c \ gunicode.c \ unicode-data.h \ - $(os_files) \ - $(vasprintf_files) + $(os_files) libeglib_la_CFLAGS = -g -Wall -D_FORTIFY_SOURCE=2 diff --git a/eglib/src/gerror.c b/eglib/src/gerror.c index 2ec089c9956..43fef97cc43 100644 --- a/eglib/src/gerror.c +++ b/eglib/src/gerror.c @@ -28,10 +28,8 @@ #include #include #include +#include #include - -#include "vasprintf.h" - GError * g_error_new (gpointer domain, gint code, const char *format, ...) { @@ -42,7 +40,7 @@ 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); @@ -57,7 +55,7 @@ g_error_vnew (gpointer domain, gint code, const char *format, va_list ap) 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; @@ -77,7 +75,7 @@ g_error_free (GError *error) { g_return_if_fail (error != NULL); - free (error->message); + g_free (error->message); g_free (error); } diff --git a/eglib/src/glib.h b/eglib/src/glib.h index 72770b2f44f..23781c16852 100644 --- a/eglib/src/glib.h +++ b/eglib/src/glib.h @@ -1,6 +1,5 @@ #ifndef __GLIB_H #define __GLIB_H - #include #include #include @@ -9,6 +8,7 @@ #include #include + #ifdef _MSC_VER #pragma include_alias(, ) #endif @@ -126,6 +126,7 @@ void g_free (void *ptr); 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); @@ -138,7 +139,7 @@ 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 { @@ -146,11 +147,9 @@ 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; @@ -223,11 +222,11 @@ gint g_printf (gchar const *format, ...); 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); @@ -772,6 +771,8 @@ const gchar *g_get_user_name (void); gchar *g_get_prgname (void); void g_set_prgname (const gchar *prgname); +gboolean g_ensure_directory_exists (const gchar *filename); + /* * Shell */ diff --git a/eglib/src/gmarkup.c b/eglib/src/gmarkup.c index 6a0b246a957..4e6c6641fef 100644 --- a/eglib/src/gmarkup.c +++ b/eglib/src/gmarkup.c @@ -367,7 +367,7 @@ g_markup_parse_context_parse (GMarkupParseContext *context, 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; } } diff --git a/eglib/src/gmem.c b/eglib/src/gmem.c index 565239d1cb8..eff478dcbfa 100644 --- a/eglib/src/gmem.c +++ b/eglib/src/gmem.c @@ -25,15 +25,45 @@ * 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 #include #include #include +#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 @@ -58,7 +88,7 @@ gpointer g_realloc (gpointer obj, gsize size) 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); @@ -70,27 +100,31 @@ g_malloc (gsize x) 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; } @@ -98,8 +132,8 @@ gpointer g_try_malloc (gsize x) 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); } diff --git a/eglib/src/gmisc-win32.c b/eglib/src/gmisc-win32.c index f89f37c2204..625fd15a84f 100644 --- a/eglib/src/gmisc-win32.c +++ b/eglib/src/gmisc-win32.c @@ -92,7 +92,7 @@ g_win32_getlocale(void) 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 @@ -128,6 +128,9 @@ g_get_home_dir (void) } } + g_free (drive); + g_free (path); + return home_dir; } diff --git a/eglib/src/goutput.c b/eglib/src/goutput.c index 779ca96fd21..ef80cff0347 100644 --- a/eglib/src/goutput.c +++ b/eglib/src/goutput.c @@ -31,8 +31,6 @@ #include #include -#include "vasprintf.h" - /* The current fatal levels, error is always fatal */ static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR; static GLogFunc default_log_func; @@ -49,7 +47,7 @@ g_print (const gchar *format, ...) va_list args; va_start (args, format); - if (vasprintf (&msg, format, args) < 0) + if (g_vasprintf (&msg, format, args) < 0) return; va_end (args); @@ -57,7 +55,7 @@ g_print (const gchar *format, ...) stdout_handler = default_stdout_handler; stdout_handler (msg); - free (msg); + g_free (msg); } void @@ -67,7 +65,7 @@ g_printerr (const gchar *format, ...) va_list args; va_start (args, format); - if (vasprintf (&msg, format, args) < 0) + if (g_vasprintf (&msg, format, args) < 0) return; va_end (args); @@ -75,7 +73,7 @@ g_printerr (const gchar *format, ...) stderr_handler = default_stderr_handler; stderr_handler (msg); - free (msg); + g_free (msg); } GLogLevelFlags @@ -107,11 +105,11 @@ g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, 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 diff --git a/eglib/src/gpath.c b/eglib/src/gpath.c index 5302f427925..59f5923125b 100644 --- a/eglib/src/gpath.c +++ b/eglib/src/gpath.c @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef G_OS_WIN32 #include @@ -294,3 +295,95 @@ g_get_prgname (void) { 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 +} + diff --git a/eglib/src/gstr.c b/eglib/src/gstr.c index 3e976c5a2ed..8b64da572f6 100644 --- a/eglib/src/gstr.c +++ b/eglib/src/gstr.c @@ -32,13 +32,17 @@ #include #include -#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) { @@ -52,6 +56,37 @@ g_strndup (const gchar *str, gsize n) #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) { @@ -133,7 +168,7 @@ g_strdup_vprintf (const gchar *format, va_list args) int n; char *ret; - n = vasprintf (&ret, format, args); + n = g_vasprintf (&ret, format, args); if (n == -1) return NULL; @@ -148,7 +183,7 @@ g_strdup_printf (const gchar *format, ...) 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; diff --git a/eglib/src/vasprintf.c b/eglib/src/vasprintf.c deleted file mode 100644 index 3c21ca4dc0a..00000000000 --- a/eglib/src/vasprintf.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include - -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; -} - diff --git a/eglib/src/vasprintf.h b/eglib/src/vasprintf.h deleted file mode 100644 index 3d294541a5b..00000000000 --- a/eglib/src/vasprintf.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __VASPRINTF_H -#define __VASPRINTF_H - -#include -#include - -#ifndef HAVE_VASPRINTF -int vasprintf(char **ret, const char *fmt, va_list ap); -#endif - -#endif /* __VASPRINTF_H */ diff --git a/eglib/test/test.c b/eglib/test/test.c index 6dd7bf47469..7c870e9c766 100644 --- a/eglib/test/test.c +++ b/eglib/test/test.c @@ -46,13 +46,6 @@ #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 @@ -183,7 +176,7 @@ FAILED(const gchar *format, ...) return NULL; #else va_start(args, format); - n = vasprintf(&ret, format, args); + n = g_vasprintf(&ret, format, args); va_end(args); if(n == -1) { diff --git a/man/mono.1 b/man/mono.1 index 7bd449dd455..81f5ae98389 100644 --- a/man/mono.1 +++ b/man/mono.1 @@ -142,10 +142,10 @@ instead of going through the operating system symbol lookup operation. .I llvm-path= Same for the llvm tools 'opt' and 'llc'. .TP -.I gen-seq-points-file=FILE.msym +.I msym-dir= 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 named as the +compilation AOTID. .TP .I mtriple= Use the GNU style target triple to determine some code generation options, i.e. @@ -1652,11 +1652,11 @@ Automatically generates sequence points where the 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 diff --git a/mcs/build/profiles/mobile.make b/mcs/build/profiles/mobile.make index 4cb0fabc2db..e531f44a4b5 100644 --- a/mcs/build/profiles/mobile.make +++ b/mcs/build/profiles/mobile.make @@ -23,6 +23,7 @@ PROFILE_MCS_FLAGS = \ -d:NET_4_0 \ -d:NET_4_5 \ -d:MONO \ + -d:NETSTANDARD \ -nowarn:1699 \ -nostdlib \ $(DEFAULT_REFERENCES) \ diff --git a/mcs/build/profiles/mobile_static.make b/mcs/build/profiles/mobile_static.make index 4dd77182c7b..5663124343a 100644 --- a/mcs/build/profiles/mobile_static.make +++ b/mcs/build/profiles/mobile_static.make @@ -21,6 +21,7 @@ PROFILE_MCS_FLAGS = \ -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 \ diff --git a/mcs/build/profiles/monodroid.make b/mcs/build/profiles/monodroid.make index 9aacd7f48b5..65919907c27 100644 --- a/mcs/build/profiles/monodroid.make +++ b/mcs/build/profiles/monodroid.make @@ -25,6 +25,7 @@ PROFILE_MCS_FLAGS = \ -d:MOBILE_DYNAMIC \ -d:MONODROID \ -d:ANDROID \ + -d:NETSTANDARD \ -nowarn:1699 \ -nostdlib \ $(DEFAULT_REFERENCES) \ diff --git a/mcs/build/profiles/monotouch_runtime.make b/mcs/build/profiles/monotouch_runtime.make index 2ff609c1a7d..e4370cf4f98 100644 --- a/mcs/build/profiles/monotouch_runtime.make +++ b/mcs/build/profiles/monotouch_runtime.make @@ -27,6 +27,7 @@ PROFILE_MCS_FLAGS = \ -d:DISABLE_REMOTING \ -d:DISABLE_COM \ -d:FEATURE_INTERCEPTABLE_THREADPOOL_CALLBACK \ + -d:NETSTANDARD \ -nowarn:1699 \ -nostdlib \ $(DEFAULT_REFERENCES) \ diff --git a/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/Microsoft.Win32.Registry.AccessControl.dll.sources b/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/Microsoft.Win32.Registry.AccessControl.dll.sources index 8e33d4ddeae..9cd503ee025 100644 --- a/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/Microsoft.Win32.Registry.AccessControl.dll.sources +++ b/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/Microsoft.Win32.Registry.AccessControl.dll.sources @@ -1,3 +1,5 @@ TypeForwarders.cs AssemblyInfo.cs +../../../build/common/MonoTODOAttribute.cs +RegistryAclExtensions.cs diff --git a/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/RegistryAclExtensions.cs b/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/RegistryAclExtensions.cs new file mode 100644 index 00000000000..deb3458cc86 --- /dev/null +++ b/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/RegistryAclExtensions.cs @@ -0,0 +1,57 @@ +// +// 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 diff --git a/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/TypeForwarders.cs b/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/TypeForwarders.cs index cb252be1af3..bdef1972306 100644 --- a/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/TypeForwarders.cs +++ b/mcs/class/Facades/Microsoft.Win32.Registry.AccessControl/TypeForwarders.cs @@ -23,4 +23,3 @@ [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))] diff --git a/mcs/class/Facades/Microsoft.Win32.Registry/TypeForwarders.cs b/mcs/class/Facades/Microsoft.Win32.Registry/TypeForwarders.cs index ecf772dd7ec..fae8514159e 100644 --- a/mcs/class/Facades/Microsoft.Win32.Registry/TypeForwarders.cs +++ b/mcs/class/Facades/Microsoft.Win32.Registry/TypeForwarders.cs @@ -20,13 +20,11 @@ // 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))] diff --git a/mcs/class/Facades/System.ComponentModel.Primitives/TypeForwarders.cs b/mcs/class/Facades/System.ComponentModel.Primitives/TypeForwarders.cs index 81a899b5e01..710df4ecd20 100644 --- a/mcs/class/Facades/System.ComponentModel.Primitives/TypeForwarders.cs +++ b/mcs/class/Facades/System.ComponentModel.Primitives/TypeForwarders.cs @@ -20,9 +20,27 @@ // 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))] diff --git a/mcs/class/Facades/System.ComponentModel.TypeConverter/TypeForwarders.cs b/mcs/class/Facades/System.ComponentModel.TypeConverter/TypeForwarders.cs index 4a50ae332d0..12d2434bfcf 100644 --- a/mcs/class/Facades/System.ComponentModel.TypeConverter/TypeForwarders.cs +++ b/mcs/class/Facades/System.ComponentModel.TypeConverter/TypeForwarders.cs @@ -21,34 +21,61 @@ // [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))] diff --git a/mcs/class/Facades/System.Console/TypeForwarders.cs b/mcs/class/Facades/System.Console/TypeForwarders.cs index fae3bad3783..c1695f51f4b 100644 --- a/mcs/class/Facades/System.Console/TypeForwarders.cs +++ b/mcs/class/Facades/System.Console/TypeForwarders.cs @@ -24,7 +24,7 @@ [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))] diff --git a/mcs/class/Facades/System.Data.Common/DbColumn.cs b/mcs/class/Facades/System.Data.Common/DbColumn.cs new file mode 100644 index 00000000000..f7bc5c713e8 --- /dev/null +++ b/mcs/class/Facades/System.Data.Common/DbColumn.cs @@ -0,0 +1,64 @@ +// +// DbColumn.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Data.Common/DbDataReaderExtensions.Facade.cs b/mcs/class/Facades/System.Data.Common/DbDataReaderExtensions.Facade.cs new file mode 100644 index 00000000000..ba1913ff9fc --- /dev/null +++ b/mcs/class/Facades/System.Data.Common/DbDataReaderExtensions.Facade.cs @@ -0,0 +1,85 @@ +// 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(SchemaTableColumn.AllowDBNull); + BaseCatalogName = GetDbColumnValue(SchemaTableOptionalColumn.BaseCatalogName); + BaseColumnName = GetDbColumnValue(SchemaTableColumn.BaseColumnName); + BaseSchemaName = GetDbColumnValue(SchemaTableColumn.BaseSchemaName); + BaseServerName = GetDbColumnValue(SchemaTableOptionalColumn.BaseServerName); + BaseTableName = GetDbColumnValue(SchemaTableColumn.BaseTableName); + ColumnName = GetDbColumnValue(SchemaTableColumn.ColumnName); + ColumnOrdinal = GetDbColumnValue(SchemaTableColumn.ColumnOrdinal); + ColumnSize = GetDbColumnValue(SchemaTableColumn.ColumnSize); + IsAliased = GetDbColumnValue(SchemaTableColumn.IsAliased); + IsAutoIncrement = GetDbColumnValue(SchemaTableOptionalColumn.IsAutoIncrement); + IsExpression = GetDbColumnValue(SchemaTableColumn.IsExpression); + IsHidden = GetDbColumnValue(SchemaTableOptionalColumn.IsHidden); + IsIdentity = GetDbColumnValue("IsIdentity"); + IsKey = GetDbColumnValue(SchemaTableColumn.IsKey); + IsLong = GetDbColumnValue(SchemaTableColumn.IsLong); + IsReadOnly = GetDbColumnValue(SchemaTableOptionalColumn.IsReadOnly); + IsUnique = GetDbColumnValue(SchemaTableColumn.IsUnique); + NumericPrecision = GetDbColumnValue(SchemaTableColumn.NumericPrecision); + NumericScale = GetDbColumnValue(SchemaTableColumn.NumericScale); + UdtAssemblyQualifiedName = GetDbColumnValue("UdtAssemblyQualifiedName"); + DataType = GetDbColumnValue(SchemaTableColumn.DataType); + DataTypeName = GetDbColumnValue("DataTypeName"); + } + + private T GetDbColumnValue(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 GetColumnSchema(this DbDataReader reader) + { + IList columnSchema = new List(); + 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 readOnlyColumnSchema = new System.Collections.ObjectModel.ReadOnlyCollection(columnSchema); + return readOnlyColumnSchema; + } + + public static bool CanGetColumnSchema(this DbDataReader reader) + { + return true; + } + } +} \ No newline at end of file diff --git a/mcs/class/Facades/System.Data.Common/IDbColumnSchemaGenerator.cs b/mcs/class/Facades/System.Data.Common/IDbColumnSchemaGenerator.cs new file mode 100644 index 00000000000..ed6c519bf14 --- /dev/null +++ b/mcs/class/Facades/System.Data.Common/IDbColumnSchemaGenerator.cs @@ -0,0 +1,35 @@ +// +// IDbColumnSchemaGenerator.cs +// +// Authors: +// Marek Safar +// +// 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 GetColumnSchema(); + } +} \ No newline at end of file diff --git a/mcs/class/Facades/System.Data.Common/Makefile b/mcs/class/Facades/System.Data.Common/Makefile index 30bf3dd0181..ff6d0356789 100644 --- a/mcs/class/Facades/System.Data.Common/Makefile +++ b/mcs/class/Facades/System.Data.Common/Makefile @@ -11,7 +11,7 @@ LIBRARY = System.Data.Common.dll 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 = diff --git a/mcs/class/Facades/System.Data.Common/System.Data.Common.dll.sources b/mcs/class/Facades/System.Data.Common/System.Data.Common.dll.sources index 8e33d4ddeae..6b723549733 100644 --- a/mcs/class/Facades/System.Data.Common/System.Data.Common.dll.sources +++ b/mcs/class/Facades/System.Data.Common/System.Data.Common.dll.sources @@ -1,3 +1,5 @@ TypeForwarders.cs AssemblyInfo.cs - +IDbColumnSchemaGenerator.cs +DbColumn.cs +DbDataReaderExtensions.Facade.cs diff --git a/mcs/class/Facades/System.Data.Common/TypeForwarders.cs b/mcs/class/Facades/System.Data.Common/TypeForwarders.cs index 52b199a2e67..9470c9c78b2 100644 --- a/mcs/class/Facades/System.Data.Common/TypeForwarders.cs +++ b/mcs/class/Facades/System.Data.Common/TypeForwarders.cs @@ -20,24 +20,36 @@ // 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))] diff --git a/mcs/class/Facades/System.Data.SqlClient/TypeForwarders.cs b/mcs/class/Facades/System.Data.SqlClient/TypeForwarders.cs index d930326b45e..3237d9eb98f 100644 --- a/mcs/class/Facades/System.Data.SqlClient/TypeForwarders.cs +++ b/mcs/class/Facades/System.Data.SqlClient/TypeForwarders.cs @@ -24,6 +24,10 @@ [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))] @@ -36,6 +40,8 @@ [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))] diff --git a/mcs/class/Facades/System.Diagnostics.Process/TypeForwarders.cs b/mcs/class/Facades/System.Diagnostics.Process/TypeForwarders.cs index 7601feb313e..e91a664406d 100644 --- a/mcs/class/Facades/System.Diagnostics.Process/TypeForwarders.cs +++ b/mcs/class/Facades/System.Diagnostics.Process/TypeForwarders.cs @@ -20,7 +20,7 @@ // 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))] diff --git a/mcs/class/Facades/System.Diagnostics.StackTrace/StackFrameExtensions.cs b/mcs/class/Facades/System.Diagnostics.StackTrace/StackFrameExtensions.cs new file mode 100644 index 00000000000..1fb375f6fa6 --- /dev/null +++ b/mcs/class/Facades/System.Diagnostics.StackTrace/StackFrameExtensions.cs @@ -0,0 +1,61 @@ +// +// 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 diff --git a/mcs/class/Facades/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.dll.sources b/mcs/class/Facades/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.dll.sources index 8e33d4ddeae..9d113cec203 100644 --- a/mcs/class/Facades/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.dll.sources +++ b/mcs/class/Facades/System.Diagnostics.StackTrace/System.Diagnostics.StackTrace.dll.sources @@ -1,3 +1,5 @@ TypeForwarders.cs AssemblyInfo.cs +../../../build/common/MonoTODOAttribute.cs +StackFrameExtensions.cs diff --git a/mcs/class/Facades/System.Diagnostics.StackTrace/TypeForwarders.cs b/mcs/class/Facades/System.Diagnostics.StackTrace/TypeForwarders.cs index b07464db3e2..3643429a219 100644 --- a/mcs/class/Facades/System.Diagnostics.StackTrace/TypeForwarders.cs +++ b/mcs/class/Facades/System.Diagnostics.StackTrace/TypeForwarders.cs @@ -22,5 +22,4 @@ [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))] diff --git a/mcs/class/Facades/System.Diagnostics.Tracing/EventCounter.cs b/mcs/class/Facades/System.Diagnostics.Tracing/EventCounter.cs new file mode 100644 index 00000000000..7fedc406886 --- /dev/null +++ b/mcs/class/Facades/System.Diagnostics.Tracing/EventCounter.cs @@ -0,0 +1,41 @@ +// +// EventCounter.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Diagnostics.Tracing/System.Diagnostics.Tracing.dll.sources b/mcs/class/Facades/System.Diagnostics.Tracing/System.Diagnostics.Tracing.dll.sources index 8e33d4ddeae..99a7bf69439 100644 --- a/mcs/class/Facades/System.Diagnostics.Tracing/System.Diagnostics.Tracing.dll.sources +++ b/mcs/class/Facades/System.Diagnostics.Tracing/System.Diagnostics.Tracing.dll.sources @@ -1,3 +1,3 @@ TypeForwarders.cs AssemblyInfo.cs - +EventCounter.cs diff --git a/mcs/class/Facades/System.Diagnostics.Tracing/TypeForwarders.cs b/mcs/class/Facades/System.Diagnostics.Tracing/TypeForwarders.cs index 80cc7e2006a..5c8ab29d77a 100644 --- a/mcs/class/Facades/System.Diagnostics.Tracing/TypeForwarders.cs +++ b/mcs/class/Facades/System.Diagnostics.Tracing/TypeForwarders.cs @@ -20,27 +20,27 @@ // 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))] diff --git a/mcs/class/Facades/System.Drawing.Primitives/AssemblyInfo.cs b/mcs/class/Facades/System.Drawing.Primitives/AssemblyInfo.cs new file mode 100644 index 00000000000..fd9a20bfefc --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/AssemblyInfo.cs @@ -0,0 +1,39 @@ +// +// 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] diff --git a/mcs/class/Facades/System.Drawing.Primitives/Makefile b/mcs/class/Facades/System.Drawing.Primitives/Makefile new file mode 100644 index 00000000000..e788928d5b3 --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/Makefile @@ -0,0 +1,27 @@ +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) + +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 diff --git a/mcs/class/Facades/System.Drawing.Primitives/System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..719628dc7c6 --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/System.Drawing.Primitives.dll.sources @@ -0,0 +1,2 @@ +TypeForwarders.cs +AssemblyInfo.cs diff --git a/mcs/class/Facades/System.Drawing.Primitives/TypeForwarders.cs b/mcs/class/Facades/System.Drawing.Primitives/TypeForwarders.cs new file mode 100644 index 00000000000..af29167e6b1 --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/TypeForwarders.cs @@ -0,0 +1,28 @@ +// +// 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))] diff --git a/mcs/class/Facades/System.Drawing.Primitives/mobile_System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/mobile_System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..dd5e4210119 --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/mobile_System.Drawing.Primitives.dll.sources @@ -0,0 +1,8 @@ +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 diff --git a/mcs/class/Facades/System.Drawing.Primitives/mobile_static_System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/mobile_static_System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..006657ab21b --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/mobile_static_System.Drawing.Primitives.dll.sources @@ -0,0 +1 @@ +#include mobile_System.Drawing.Primitives.dll.sources diff --git a/mcs/class/Facades/System.Drawing.Primitives/monodroid_System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/monodroid_System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..006657ab21b --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/monodroid_System.Drawing.Primitives.dll.sources @@ -0,0 +1 @@ +#include mobile_System.Drawing.Primitives.dll.sources diff --git a/mcs/class/Facades/System.Drawing.Primitives/monotouch_System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/monotouch_System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..006657ab21b --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/monotouch_System.Drawing.Primitives.dll.sources @@ -0,0 +1 @@ +#include mobile_System.Drawing.Primitives.dll.sources diff --git a/mcs/class/Facades/System.Drawing.Primitives/monotouch_tv_System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/monotouch_tv_System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..006657ab21b --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/monotouch_tv_System.Drawing.Primitives.dll.sources @@ -0,0 +1 @@ +#include mobile_System.Drawing.Primitives.dll.sources diff --git a/mcs/class/Facades/System.Drawing.Primitives/monotouch_watch_System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/monotouch_watch_System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..006657ab21b --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/monotouch_watch_System.Drawing.Primitives.dll.sources @@ -0,0 +1 @@ +#include mobile_System.Drawing.Primitives.dll.sources diff --git a/mcs/class/Facades/System.Drawing.Primitives/xammac_System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/xammac_System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..006657ab21b --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/xammac_System.Drawing.Primitives.dll.sources @@ -0,0 +1 @@ +#include mobile_System.Drawing.Primitives.dll.sources diff --git a/mcs/class/Facades/System.Drawing.Primitives/xammac_net_4_5_System.Drawing.Primitives.dll.sources b/mcs/class/Facades/System.Drawing.Primitives/xammac_net_4_5_System.Drawing.Primitives.dll.sources new file mode 100644 index 00000000000..006657ab21b --- /dev/null +++ b/mcs/class/Facades/System.Drawing.Primitives/xammac_net_4_5_System.Drawing.Primitives.dll.sources @@ -0,0 +1 @@ +#include mobile_System.Drawing.Primitives.dll.sources diff --git a/mcs/class/Facades/System.Globalization.Extensions/GlobalizationExtensions.cs b/mcs/class/Facades/System.Globalization.Extensions/GlobalizationExtensions.cs new file mode 100644 index 00000000000..43c1494eca7 --- /dev/null +++ b/mcs/class/Facades/System.Globalization.Extensions/GlobalizationExtensions.cs @@ -0,0 +1,98 @@ +// 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); + } + } +} diff --git a/mcs/class/Facades/System.Globalization.Extensions/SR.cs b/mcs/class/Facades/System.Globalization.Extensions/SR.cs new file mode 100644 index 00000000000..52a75a8e6dc --- /dev/null +++ b/mcs/class/Facades/System.Globalization.Extensions/SR.cs @@ -0,0 +1,4 @@ +partial class SR +{ + public const string Argument_InvalidFlag = "Value of flags is invalid."; +} \ No newline at end of file diff --git a/mcs/class/Facades/System.Globalization.Extensions/StringNormalizationExtensions.cs b/mcs/class/Facades/System.Globalization.Extensions/StringNormalizationExtensions.cs new file mode 100644 index 00000000000..7953b29b9ab --- /dev/null +++ b/mcs/class/Facades/System.Globalization.Extensions/StringNormalizationExtensions.cs @@ -0,0 +1,61 @@ +// +// 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 (); + } + } +} + diff --git a/mcs/class/Facades/System.Globalization.Extensions/System.Globalization.Extensions.dll.sources b/mcs/class/Facades/System.Globalization.Extensions/System.Globalization.Extensions.dll.sources index 8e33d4ddeae..8cec8fa1ac3 100644 --- a/mcs/class/Facades/System.Globalization.Extensions/System.Globalization.Extensions.dll.sources +++ b/mcs/class/Facades/System.Globalization.Extensions/System.Globalization.Extensions.dll.sources @@ -1,3 +1,7 @@ TypeForwarders.cs AssemblyInfo.cs +../../../build/common/MonoTODOAttribute.cs +SR.cs +GlobalizationExtensions.cs +StringNormalizationExtensions.cs diff --git a/mcs/class/Facades/System.Globalization.Extensions/TypeForwarders.cs b/mcs/class/Facades/System.Globalization.Extensions/TypeForwarders.cs index 2f88c337195..ae5a0bbb413 100644 --- a/mcs/class/Facades/System.Globalization.Extensions/TypeForwarders.cs +++ b/mcs/class/Facades/System.Globalization.Extensions/TypeForwarders.cs @@ -22,5 +22,3 @@ [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))] diff --git a/mcs/class/Facades/System.IO.Compression/Missing.cs b/mcs/class/Facades/System.IO.Compression/Missing.cs new file mode 100644 index 00000000000..cd06b1c6842 --- /dev/null +++ b/mcs/class/Facades/System.IO.Compression/Missing.cs @@ -0,0 +1,40 @@ +// 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 Entries { get { return default(System.Collections.ObjectModel.ReadOnlyCollection); } } + 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 diff --git a/mcs/class/Facades/System.IO.Compression/System.IO.Compression.dll.sources b/mcs/class/Facades/System.IO.Compression/System.IO.Compression.dll.sources index 8e33d4ddeae..402d066e4c3 100644 --- a/mcs/class/Facades/System.IO.Compression/System.IO.Compression.dll.sources +++ b/mcs/class/Facades/System.IO.Compression/System.IO.Compression.dll.sources @@ -1,3 +1,3 @@ TypeForwarders.cs AssemblyInfo.cs - +Missing.cs diff --git a/mcs/class/Facades/System.IO.FileSystem.AccessControl/FileSystemAclExtensions.cs b/mcs/class/Facades/System.IO.FileSystem.AccessControl/FileSystemAclExtensions.cs new file mode 100644 index 00000000000..1dd8d97ab5e --- /dev/null +++ b/mcs/class/Facades/System.IO.FileSystem.AccessControl/FileSystemAclExtensions.cs @@ -0,0 +1,83 @@ +// +// 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 diff --git a/mcs/class/Facades/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.dll.sources b/mcs/class/Facades/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.dll.sources index 8e33d4ddeae..d226e0d4c80 100644 --- a/mcs/class/Facades/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.dll.sources +++ b/mcs/class/Facades/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.dll.sources @@ -1,3 +1,5 @@ TypeForwarders.cs AssemblyInfo.cs +../../../build/common/MonoTODOAttribute.cs +FileSystemAclExtensions.cs diff --git a/mcs/class/Facades/System.IO.FileSystem.AccessControl/TypeForwarders.cs b/mcs/class/Facades/System.IO.FileSystem.AccessControl/TypeForwarders.cs index 12daecd0383..18351db171e 100644 --- a/mcs/class/Facades/System.IO.FileSystem.AccessControl/TypeForwarders.cs +++ b/mcs/class/Facades/System.IO.FileSystem.AccessControl/TypeForwarders.cs @@ -27,5 +27,3 @@ [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))] diff --git a/mcs/class/Facades/System.IO.FileSystem.Watcher/TypeForwarders.cs b/mcs/class/Facades/System.IO.FileSystem.Watcher/TypeForwarders.cs index 6237d34bfc4..b25bcf38598 100644 --- a/mcs/class/Facades/System.IO.FileSystem.Watcher/TypeForwarders.cs +++ b/mcs/class/Facades/System.IO.FileSystem.Watcher/TypeForwarders.cs @@ -29,5 +29,6 @@ [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))] diff --git a/mcs/class/Facades/System.IO.Packaging/AssemblyInfo.cs b/mcs/class/Facades/System.IO.Packaging/AssemblyInfo.cs new file mode 100644 index 00000000000..7b0813f74ff --- /dev/null +++ b/mcs/class/Facades/System.IO.Packaging/AssemblyInfo.cs @@ -0,0 +1,39 @@ +// +// 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] diff --git a/mcs/class/Facades/System.IO.Packaging/Makefile b/mcs/class/Facades/System.IO.Packaging/Makefile new file mode 100644 index 00000000000..cbf6d68139c --- /dev/null +++ b/mcs/class/Facades/System.IO.Packaging/Makefile @@ -0,0 +1,21 @@ +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 diff --git a/mcs/class/Facades/System.IO.Packaging/System.IO.Packaging.dll.sources b/mcs/class/Facades/System.IO.Packaging/System.IO.Packaging.dll.sources new file mode 100644 index 00000000000..719628dc7c6 --- /dev/null +++ b/mcs/class/Facades/System.IO.Packaging/System.IO.Packaging.dll.sources @@ -0,0 +1,2 @@ +TypeForwarders.cs +AssemblyInfo.cs diff --git a/mcs/class/Facades/System.IO.Packaging/TypeForwarders.cs b/mcs/class/Facades/System.IO.Packaging/TypeForwarders.cs new file mode 100644 index 00000000000..a3c45042f14 --- /dev/null +++ b/mcs/class/Facades/System.IO.Packaging/TypeForwarders.cs @@ -0,0 +1,37 @@ +// +// 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))] diff --git a/mcs/class/Facades/System.Net.Ping/AssemblyInfo.cs b/mcs/class/Facades/System.Net.Ping/AssemblyInfo.cs new file mode 100644 index 00000000000..507e590b98f --- /dev/null +++ b/mcs/class/Facades/System.Net.Ping/AssemblyInfo.cs @@ -0,0 +1,39 @@ +// +// 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] diff --git a/mcs/class/Facades/System.Net.Ping/Makefile b/mcs/class/Facades/System.Net.Ping/Makefile new file mode 100644 index 00000000000..750ace69439 --- /dev/null +++ b/mcs/class/Facades/System.Net.Ping/Makefile @@ -0,0 +1,21 @@ +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 diff --git a/mcs/class/Facades/System.Net.Ping/System.Net.Ping.dll.sources b/mcs/class/Facades/System.Net.Ping/System.Net.Ping.dll.sources new file mode 100644 index 00000000000..719628dc7c6 --- /dev/null +++ b/mcs/class/Facades/System.Net.Ping/System.Net.Ping.dll.sources @@ -0,0 +1,2 @@ +TypeForwarders.cs +AssemblyInfo.cs diff --git a/mcs/class/Facades/System.Net.Ping/TypeForwarders.cs b/mcs/class/Facades/System.Net.Ping/TypeForwarders.cs new file mode 100644 index 00000000000..2f79a42a82f --- /dev/null +++ b/mcs/class/Facades/System.Net.Ping/TypeForwarders.cs @@ -0,0 +1,27 @@ +// +// 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))] diff --git a/mcs/class/Facades/System.Net.Security/TypeForwarders.cs b/mcs/class/Facades/System.Net.Security/TypeForwarders.cs index 884e50a3fd2..3167d764e13 100644 --- a/mcs/class/Facades/System.Net.Security/TypeForwarders.cs +++ b/mcs/class/Facades/System.Net.Security/TypeForwarders.cs @@ -20,8 +20,11 @@ // 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))] @@ -29,5 +32,6 @@ [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))] diff --git a/mcs/class/Facades/System.Net.Sockets/SocketReceiveFromResult.cs b/mcs/class/Facades/System.Net.Sockets/SocketReceiveFromResult.cs new file mode 100644 index 00000000000..2add0e6daf7 --- /dev/null +++ b/mcs/class/Facades/System.Net.Sockets/SocketReceiveFromResult.cs @@ -0,0 +1,36 @@ +// +// SocketReceiveFromResult.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Net.Sockets/SocketReceiveMessageFromResult.cs b/mcs/class/Facades/System.Net.Sockets/SocketReceiveMessageFromResult.cs new file mode 100644 index 00000000000..ab5ed1022fa --- /dev/null +++ b/mcs/class/Facades/System.Net.Sockets/SocketReceiveMessageFromResult.cs @@ -0,0 +1,38 @@ +// +// SocketReceiveMessageFromResult.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Net.Sockets/SocketTaskExtensions.cs b/mcs/class/Facades/System.Net.Sockets/SocketTaskExtensions.cs new file mode 100644 index 00000000000..a3e24ede013 --- /dev/null +++ b/mcs/class/Facades/System.Net.Sockets/SocketTaskExtensions.cs @@ -0,0 +1,250 @@ +// 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 AcceptAsync(this Socket socket) + { + return Task.Factory.FromAsync( + (callback, state) => ((Socket)state).BeginAccept(callback, state), + asyncResult => ((Socket)asyncResult.AsyncState).EndAccept(asyncResult), + state: socket); + } + + public static Task AcceptAsync(this Socket socket, Socket acceptSocket) + { + const int ReceiveSize = 0; + return Task.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 ReceiveAsync(this Socket socket, ArraySegment buffer, SocketFlags socketFlags) + { + return Task.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 ReceiveAsync( + this Socket socket, + IList> buffers, + SocketFlags socketFlags) + { + return Task.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 ReceiveFromAsync( + this Socket socket, + ArraySegment buffer, + SocketFlags socketFlags, + EndPoint remoteEndPoint) + { + object[] packedArguments = new object[] { socket, remoteEndPoint }; + + return Task.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 ReceiveMessageFromAsync( + this Socket socket, + ArraySegment buffer, + SocketFlags socketFlags, + EndPoint remoteEndPoint) + { + object[] packedArguments = new object[] { socket, socketFlags, remoteEndPoint }; + + return Task.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 SendAsync(this Socket socket, ArraySegment buffer, SocketFlags socketFlags) + { + return Task.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 SendAsync( + this Socket socket, + IList> buffers, + SocketFlags socketFlags) + { + return Task.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 SendToAsync( + this Socket socket, + ArraySegment buffer, + SocketFlags socketFlags, + EndPoint remoteEndPoint) + { + return Task.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 diff --git a/mcs/class/Facades/System.Net.Sockets/System.Net.Sockets.dll.sources b/mcs/class/Facades/System.Net.Sockets/System.Net.Sockets.dll.sources index 8e33d4ddeae..a4cab35a66b 100644 --- a/mcs/class/Facades/System.Net.Sockets/System.Net.Sockets.dll.sources +++ b/mcs/class/Facades/System.Net.Sockets/System.Net.Sockets.dll.sources @@ -1,3 +1,5 @@ TypeForwarders.cs AssemblyInfo.cs - +SocketReceiveFromResult.cs +SocketReceiveMessageFromResult.cs +SocketTaskExtensions.cs diff --git a/mcs/class/Facades/System.Reflection.Primitives/TypeForwarders.cs b/mcs/class/Facades/System.Reflection.Primitives/TypeForwarders.cs index cfa70ce24a5..a3dd7e7c887 100644 --- a/mcs/class/Facades/System.Reflection.Primitives/TypeForwarders.cs +++ b/mcs/class/Facades/System.Reflection.Primitives/TypeForwarders.cs @@ -20,7 +20,6 @@ // 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))] @@ -28,7 +27,6 @@ [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))] diff --git a/mcs/class/Facades/System.Reflection.TypeExtensions/Requires.cs b/mcs/class/Facades/System.Reflection.TypeExtensions/Requires.cs new file mode 100644 index 00000000000..339981b9afc --- /dev/null +++ b/mcs/class/Facades/System.Reflection.TypeExtensions/Requires.cs @@ -0,0 +1,17 @@ +// 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 diff --git a/mcs/class/Facades/System.Reflection.TypeExtensions/SR.cs b/mcs/class/Facades/System.Reflection.TypeExtensions/SR.cs new file mode 100644 index 00000000000..0a1ae286b52 --- /dev/null +++ b/mcs/class/Facades/System.Reflection.TypeExtensions/SR.cs @@ -0,0 +1,4 @@ +partial class SR +{ + public const string NoMetadataTokenAvailable = "There is no metadata token available for the given member."; +} \ No newline at end of file diff --git a/mcs/class/Facades/System.Reflection.TypeExtensions/System.Reflection.TypeExtensions.dll.sources b/mcs/class/Facades/System.Reflection.TypeExtensions/System.Reflection.TypeExtensions.dll.sources index 8e33d4ddeae..06522762fb9 100644 --- a/mcs/class/Facades/System.Reflection.TypeExtensions/System.Reflection.TypeExtensions.dll.sources +++ b/mcs/class/Facades/System.Reflection.TypeExtensions/System.Reflection.TypeExtensions.dll.sources @@ -1,3 +1,6 @@ TypeForwarders.cs AssemblyInfo.cs +SR.cs +Requires.cs +TypeExtensions.CoreCLR.cs diff --git a/mcs/class/Facades/System.Reflection.TypeExtensions/TypeExtensions.CoreCLR.cs b/mcs/class/Facades/System.Reflection.TypeExtensions/TypeExtensions.CoreCLR.cs new file mode 100644 index 00000000000..661cd67a0ea --- /dev/null +++ b/mcs/class/Facades/System.Reflection.TypeExtensions/TypeExtensions.CoreCLR.cs @@ -0,0 +1,400 @@ +// 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 + { + + /// + /// Determines if there is a metadata token available for the given member. + /// throws otherwise. + /// + /// This maybe + 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; + } + } + + /// + /// Gets a metadata token for the given member if available. The returned token is never nil. + /// + /// + /// There is no metadata token available. returns false in this case. + /// + 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); + } + } +} diff --git a/mcs/class/Facades/System.Reflection.TypeExtensions/TypeForwarders.cs b/mcs/class/Facades/System.Reflection.TypeExtensions/TypeForwarders.cs index a6b0138ff61..757cd130355 100644 --- a/mcs/class/Facades/System.Reflection.TypeExtensions/TypeForwarders.cs +++ b/mcs/class/Facades/System.Reflection.TypeExtensions/TypeForwarders.cs @@ -22,8 +22,3 @@ [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))] diff --git a/mcs/class/Facades/System.Runtime.Serialization.Formatters/AssemblyInfo.cs b/mcs/class/Facades/System.Runtime.Serialization.Formatters/AssemblyInfo.cs new file mode 100644 index 00000000000..9b921172c12 --- /dev/null +++ b/mcs/class/Facades/System.Runtime.Serialization.Formatters/AssemblyInfo.cs @@ -0,0 +1,41 @@ +// +// 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] + + diff --git a/mcs/class/Facades/System.Runtime.Serialization.Formatters/Makefile b/mcs/class/Facades/System.Runtime.Serialization.Formatters/Makefile new file mode 100644 index 00000000000..a8c237d1da4 --- /dev/null +++ b/mcs/class/Facades/System.Runtime.Serialization.Formatters/Makefile @@ -0,0 +1,23 @@ +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 + + diff --git a/mcs/class/Facades/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.dll.sources b/mcs/class/Facades/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.dll.sources new file mode 100644 index 00000000000..8e33d4ddeae --- /dev/null +++ b/mcs/class/Facades/System.Runtime.Serialization.Formatters/System.Runtime.Serialization.Formatters.dll.sources @@ -0,0 +1,3 @@ +TypeForwarders.cs +AssemblyInfo.cs + diff --git a/mcs/class/Facades/System.Runtime.Serialization.Formatters/TypeForwarders.cs b/mcs/class/Facades/System.Runtime.Serialization.Formatters/TypeForwarders.cs new file mode 100644 index 00000000000..31daa7cdcb4 --- /dev/null +++ b/mcs/class/Facades/System.Runtime.Serialization.Formatters/TypeForwarders.cs @@ -0,0 +1,32 @@ +// +// 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))] + + diff --git a/mcs/class/Facades/System.Runtime.Serialization.Primitives/ISerializationSurrogateProvider.cs b/mcs/class/Facades/System.Runtime.Serialization.Primitives/ISerializationSurrogateProvider.cs new file mode 100644 index 00000000000..b14b6df5409 --- /dev/null +++ b/mcs/class/Facades/System.Runtime.Serialization.Primitives/ISerializationSurrogateProvider.cs @@ -0,0 +1,32 @@ +// +// 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); + } +} + diff --git a/mcs/class/Facades/System.Runtime.Serialization.Primitives/System.Runtime.Serialization.Primitives.dll.sources b/mcs/class/Facades/System.Runtime.Serialization.Primitives/System.Runtime.Serialization.Primitives.dll.sources index 8e33d4ddeae..75ec1201b8f 100644 --- a/mcs/class/Facades/System.Runtime.Serialization.Primitives/System.Runtime.Serialization.Primitives.dll.sources +++ b/mcs/class/Facades/System.Runtime.Serialization.Primitives/System.Runtime.Serialization.Primitives.dll.sources @@ -1,3 +1,3 @@ TypeForwarders.cs AssemblyInfo.cs - +ISerializationSurrogateProvider.cs diff --git a/mcs/class/Facades/System.Runtime.Serialization.Primitives/TypeForwarders.cs b/mcs/class/Facades/System.Runtime.Serialization.Primitives/TypeForwarders.cs index ce3180fe1f1..57b2d4db09c 100644 --- a/mcs/class/Facades/System.Runtime.Serialization.Primitives/TypeForwarders.cs +++ b/mcs/class/Facades/System.Runtime.Serialization.Primitives/TypeForwarders.cs @@ -33,4 +33,4 @@ [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))] diff --git a/mcs/class/Facades/System.Runtime.Serialization.Xml/DataContractSerializerExtensions.cs b/mcs/class/Facades/System.Runtime.Serialization.Xml/DataContractSerializerExtensions.cs new file mode 100644 index 00000000000..3ccdff7a346 --- /dev/null +++ b/mcs/class/Facades/System.Runtime.Serialization.Xml/DataContractSerializerExtensions.cs @@ -0,0 +1,84 @@ +// 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 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 diff --git a/mcs/class/Facades/System.Runtime.Serialization.Xml/Makefile b/mcs/class/Facades/System.Runtime.Serialization.Xml/Makefile index 774289eb4de..dc0a84d0229 100644 --- a/mcs/class/Facades/System.Runtime.Serialization.Xml/Makefile +++ b/mcs/class/Facades/System.Runtime.Serialization.Xml/Makefile @@ -11,9 +11,13 @@ LIBRARY = System.Runtime.Serialization.Xml.dll 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 diff --git a/mcs/class/Facades/System.Runtime.Serialization.Xml/NotImplemented.cs b/mcs/class/Facades/System.Runtime.Serialization.Xml/NotImplemented.cs new file mode 100644 index 00000000000..26e5342aaf4 --- /dev/null +++ b/mcs/class/Facades/System.Runtime.Serialization.Xml/NotImplemented.cs @@ -0,0 +1,32 @@ +// 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 diff --git a/mcs/class/Facades/System.Runtime.Serialization.Xml/System.Runtime.Serialization.Xml.dll.sources b/mcs/class/Facades/System.Runtime.Serialization.Xml/System.Runtime.Serialization.Xml.dll.sources index 8e33d4ddeae..d23128800bb 100644 --- a/mcs/class/Facades/System.Runtime.Serialization.Xml/System.Runtime.Serialization.Xml.dll.sources +++ b/mcs/class/Facades/System.Runtime.Serialization.Xml/System.Runtime.Serialization.Xml.dll.sources @@ -1,3 +1,6 @@ TypeForwarders.cs AssemblyInfo.cs + +DataContractSerializerExtensions.cs +NotImplemented.cs diff --git a/mcs/class/Facades/System.Runtime.Serialization.Xml/TypeForwarders.cs b/mcs/class/Facades/System.Runtime.Serialization.Xml/TypeForwarders.cs index bfd4e7e4711..38eea612a47 100644 --- a/mcs/class/Facades/System.Runtime.Serialization.Xml/TypeForwarders.cs +++ b/mcs/class/Facades/System.Runtime.Serialization.Xml/TypeForwarders.cs @@ -36,3 +36,4 @@ [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))] diff --git a/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECCurve.cs b/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECCurve.cs new file mode 100644 index 00000000000..3e1733e0c3b --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECCurve.cs @@ -0,0 +1,85 @@ +// +// ECCurve.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECParameters.cs b/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECParameters.cs new file mode 100644 index 00000000000..6f1e4211c8b --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECParameters.cs @@ -0,0 +1,39 @@ +// +// ECPArameters.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECPoint.cs b/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECPoint.cs new file mode 100644 index 00000000000..5693959d0e5 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Algorithms/ECPoint.cs @@ -0,0 +1,37 @@ +// +// ECPoint.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Security.Cryptography.Algorithms/IncrementalHash.cs b/mcs/class/Facades/System.Security.Cryptography.Algorithms/IncrementalHash.cs new file mode 100644 index 00000000000..7b39b0d9889 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Algorithms/IncrementalHash.cs @@ -0,0 +1,42 @@ +// +// IncrementalHash.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Security.Cryptography.Algorithms/System.Security.Cryptography.Algorithms.dll.sources b/mcs/class/Facades/System.Security.Cryptography.Algorithms/System.Security.Cryptography.Algorithms.dll.sources index 8e33d4ddeae..dcb3ff9de88 100644 --- a/mcs/class/Facades/System.Security.Cryptography.Algorithms/System.Security.Cryptography.Algorithms.dll.sources +++ b/mcs/class/Facades/System.Security.Cryptography.Algorithms/System.Security.Cryptography.Algorithms.dll.sources @@ -1,3 +1,6 @@ TypeForwarders.cs AssemblyInfo.cs - +ECCurve.cs +ECPoint.cs +ECParameters.cs +IncrementalHash.cs diff --git a/mcs/class/Facades/System.Security.Cryptography.Cng/AssemblyInfo.cs b/mcs/class/Facades/System.Security.Cryptography.Cng/AssemblyInfo.cs new file mode 100644 index 00000000000..b902325fdef --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Cng/AssemblyInfo.cs @@ -0,0 +1,41 @@ +// +// 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] + + diff --git a/mcs/class/Facades/System.Security.Cryptography.Cng/Makefile b/mcs/class/Facades/System.Security.Cryptography.Cng/Makefile new file mode 100644 index 00000000000..4912aa302c0 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Cng/Makefile @@ -0,0 +1,23 @@ +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 + + diff --git a/mcs/class/Facades/System.Security.Cryptography.Cng/System.Security.Cryptography.Cng.dll.sources b/mcs/class/Facades/System.Security.Cryptography.Cng/System.Security.Cryptography.Cng.dll.sources new file mode 100644 index 00000000000..8e33d4ddeae --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Cng/System.Security.Cryptography.Cng.dll.sources @@ -0,0 +1,3 @@ +TypeForwarders.cs +AssemblyInfo.cs + diff --git a/mcs/class/Facades/System.Security.Cryptography.Cng/TypeForwarders.cs b/mcs/class/Facades/System.Security.Cryptography.Cng/TypeForwarders.cs new file mode 100644 index 00000000000..309d6fb5ce3 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Cng/TypeForwarders.cs @@ -0,0 +1,46 @@ +// +// 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))] diff --git a/mcs/class/Facades/System.Security.Cryptography.Csp/AssemblyInfo.cs b/mcs/class/Facades/System.Security.Cryptography.Csp/AssemblyInfo.cs new file mode 100644 index 00000000000..0d630533adb --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Csp/AssemblyInfo.cs @@ -0,0 +1,41 @@ +// +// 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] + + diff --git a/mcs/class/Facades/System.Security.Cryptography.Csp/Makefile b/mcs/class/Facades/System.Security.Cryptography.Csp/Makefile new file mode 100644 index 00000000000..91d09321a61 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Csp/Makefile @@ -0,0 +1,23 @@ +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 + + diff --git a/mcs/class/Facades/System.Security.Cryptography.Csp/System.Security.Cryptography.Csp.dll.sources b/mcs/class/Facades/System.Security.Cryptography.Csp/System.Security.Cryptography.Csp.dll.sources new file mode 100644 index 00000000000..8e33d4ddeae --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Csp/System.Security.Cryptography.Csp.dll.sources @@ -0,0 +1,3 @@ +TypeForwarders.cs +AssemblyInfo.cs + diff --git a/mcs/class/Facades/System.Security.Cryptography.Csp/TypeForwarders.cs b/mcs/class/Facades/System.Security.Cryptography.Csp/TypeForwarders.cs new file mode 100644 index 00000000000..a854f1fba52 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Csp/TypeForwarders.cs @@ -0,0 +1,30 @@ +// +// 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))] + + diff --git a/mcs/class/Facades/System.Security.Cryptography.OpenSsl/AssemblyInfo.cs b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/AssemblyInfo.cs new file mode 100644 index 00000000000..3560bf23570 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/AssemblyInfo.cs @@ -0,0 +1,41 @@ +// +// 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] + + diff --git a/mcs/class/Facades/System.Security.Cryptography.OpenSsl/ECDsaOpenSsl.cs b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/ECDsaOpenSsl.cs new file mode 100644 index 00000000000..1a2771a4f36 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/ECDsaOpenSsl.cs @@ -0,0 +1,45 @@ +// +// ECDsaOpenSsl.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Security.Cryptography.OpenSsl/Makefile b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/Makefile new file mode 100644 index 00000000000..aa30bc935a1 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/Makefile @@ -0,0 +1,23 @@ +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 + + diff --git a/mcs/class/Facades/System.Security.Cryptography.OpenSsl/RSAOpenSsl.cs b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/RSAOpenSsl.cs new file mode 100644 index 00000000000..4bdcd80917c --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/RSAOpenSsl.cs @@ -0,0 +1,55 @@ +// +// RSAOpenSsl.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Security.Cryptography.OpenSsl/SafeEvpPKeyHandle.cs b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/SafeEvpPKeyHandle.cs new file mode 100644 index 00000000000..85fd74539b8 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/SafeEvpPKeyHandle.cs @@ -0,0 +1,50 @@ +// +// SafeEvpPKeyHandle.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/Facades/System.Security.Cryptography.OpenSsl/System.Security.Cryptography.OpenSsl.dll.sources b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/System.Security.Cryptography.OpenSsl.dll.sources new file mode 100644 index 00000000000..9e2bb4b66f8 --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.OpenSsl/System.Security.Cryptography.OpenSsl.dll.sources @@ -0,0 +1,4 @@ +AssemblyInfo.cs +ECDsaOpenSsl.cs +RSAOpenSsl.cs +SafeEvpPKeyHandle.cs diff --git a/mcs/class/Facades/System.Security.Cryptography.Pkcs/AssemblyInfo.cs b/mcs/class/Facades/System.Security.Cryptography.Pkcs/AssemblyInfo.cs new file mode 100644 index 00000000000..06089b35e6f --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Pkcs/AssemblyInfo.cs @@ -0,0 +1,41 @@ +// +// 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] + + diff --git a/mcs/class/Facades/System.Security.Cryptography.Pkcs/Makefile b/mcs/class/Facades/System.Security.Cryptography.Pkcs/Makefile new file mode 100644 index 00000000000..b98a24269be --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Pkcs/Makefile @@ -0,0 +1,23 @@ +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 + + diff --git a/mcs/class/Facades/System.Security.Cryptography.Pkcs/System.Security.Cryptography.Pkcs.dll.sources b/mcs/class/Facades/System.Security.Cryptography.Pkcs/System.Security.Cryptography.Pkcs.dll.sources new file mode 100644 index 00000000000..8e33d4ddeae --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Pkcs/System.Security.Cryptography.Pkcs.dll.sources @@ -0,0 +1,3 @@ +TypeForwarders.cs +AssemblyInfo.cs + diff --git a/mcs/class/Facades/System.Security.Cryptography.Pkcs/TypeForwarders.cs b/mcs/class/Facades/System.Security.Cryptography.Pkcs/TypeForwarders.cs new file mode 100644 index 00000000000..db96723509e --- /dev/null +++ b/mcs/class/Facades/System.Security.Cryptography.Pkcs/TypeForwarders.cs @@ -0,0 +1,51 @@ +// +// 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))] + + diff --git a/mcs/class/Facades/System.Security.Principal.Windows/TypeForwarders.cs b/mcs/class/Facades/System.Security.Principal.Windows/TypeForwarders.cs index 8ce4172c842..ec9f05c6245 100644 --- a/mcs/class/Facades/System.Security.Principal.Windows/TypeForwarders.cs +++ b/mcs/class/Facades/System.Security.Principal.Windows/TypeForwarders.cs @@ -20,7 +20,7 @@ // 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))] diff --git a/mcs/class/Facades/System.Security.SecureString/SecureStringMarshal.cs b/mcs/class/Facades/System.Security.SecureString/SecureStringMarshal.cs new file mode 100644 index 00000000000..59c85a4291e --- /dev/null +++ b/mcs/class/Facades/System.Security.SecureString/SecureStringMarshal.cs @@ -0,0 +1,47 @@ +// +// 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 (); + } + } +} diff --git a/mcs/class/Facades/System.Security.SecureString/System.Security.SecureString.dll.sources b/mcs/class/Facades/System.Security.SecureString/System.Security.SecureString.dll.sources index 8e33d4ddeae..870ef245887 100644 --- a/mcs/class/Facades/System.Security.SecureString/System.Security.SecureString.dll.sources +++ b/mcs/class/Facades/System.Security.SecureString/System.Security.SecureString.dll.sources @@ -1,3 +1,3 @@ TypeForwarders.cs AssemblyInfo.cs - +SecureStringMarshal.cs diff --git a/mcs/class/Facades/System.Security.SecureString/TypeForwarders.cs b/mcs/class/Facades/System.Security.SecureString/TypeForwarders.cs index d8898cbe774..4267f40e03b 100644 --- a/mcs/class/Facades/System.Security.SecureString/TypeForwarders.cs +++ b/mcs/class/Facades/System.Security.SecureString/TypeForwarders.cs @@ -21,5 +21,3 @@ // [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.SecureString))] - -//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Security.SecureStringMarshal))] diff --git a/mcs/class/Facades/System.ServiceModel.Duplex/TypeForwarders.cs b/mcs/class/Facades/System.ServiceModel.Duplex/TypeForwarders.cs index 89df0553778..09d884b1527 100644 --- a/mcs/class/Facades/System.ServiceModel.Duplex/TypeForwarders.cs +++ b/mcs/class/Facades/System.ServiceModel.Duplex/TypeForwarders.cs @@ -20,9 +20,7 @@ // 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))] diff --git a/mcs/class/Facades/System.ServiceModel.Http/TypeForwarders.cs b/mcs/class/Facades/System.ServiceModel.Http/TypeForwarders.cs index 57276e7078c..4aa28e9e49f 100644 --- a/mcs/class/Facades/System.ServiceModel.Http/TypeForwarders.cs +++ b/mcs/class/Facades/System.ServiceModel.Http/TypeForwarders.cs @@ -24,6 +24,9 @@ [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))] @@ -35,5 +38,6 @@ [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))] diff --git a/mcs/class/Facades/System.ServiceModel.NetTcp/TypeForwarders.cs b/mcs/class/Facades/System.ServiceModel.NetTcp/TypeForwarders.cs index a80d1c6fd12..f03bc06d93c 100644 --- a/mcs/class/Facades/System.ServiceModel.NetTcp/TypeForwarders.cs +++ b/mcs/class/Facades/System.ServiceModel.NetTcp/TypeForwarders.cs @@ -20,7 +20,6 @@ // 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))] @@ -30,5 +29,4 @@ [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))] diff --git a/mcs/class/Facades/System.ServiceModel.Primitives/Makefile b/mcs/class/Facades/System.ServiceModel.Primitives/Makefile index 5f65e0599a3..b89ba3525c8 100644 --- a/mcs/class/Facades/System.ServiceModel.Primitives/Makefile +++ b/mcs/class/Facades/System.ServiceModel.Primitives/Makefile @@ -11,7 +11,12 @@ LIBRARY = System.ServiceModel.Primitives.dll 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 = diff --git a/mcs/class/Facades/System.ServiceModel.Primitives/System.ServiceModel.Primitives.dll.sources b/mcs/class/Facades/System.ServiceModel.Primitives/System.ServiceModel.Primitives.dll.sources index 8e33d4ddeae..f43e364288e 100644 --- a/mcs/class/Facades/System.ServiceModel.Primitives/System.ServiceModel.Primitives.dll.sources +++ b/mcs/class/Facades/System.ServiceModel.Primitives/System.ServiceModel.Primitives.dll.sources @@ -1,3 +1,9 @@ TypeForwarders.cs AssemblyInfo.cs +../../../build/common/MonoTODOAttribute.cs +X509ServiceCertificateAuthentication_mobile.cs +X509CertificateValidator_mobile.cs +X509CertificateValidationMode_mobile.cs +X509CertificateRecipientClientCredential_mobile.cs +X509CertificateInitiatorClientCredential_mobile.cs diff --git a/mcs/class/Facades/System.ServiceModel.Primitives/TypeForwarders.cs b/mcs/class/Facades/System.ServiceModel.Primitives/TypeForwarders.cs index 38f834268c4..b584fc0b8ee 100644 --- a/mcs/class/Facades/System.ServiceModel.Primitives/TypeForwarders.cs +++ b/mcs/class/Facades/System.ServiceModel.Primitives/TypeForwarders.cs @@ -136,6 +136,7 @@ [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))] @@ -158,3 +159,16 @@ [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 diff --git a/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateInitiatorClientCredential_mobile.cs b/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateInitiatorClientCredential_mobile.cs new file mode 100644 index 00000000000..daf321c22ef --- /dev/null +++ b/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateInitiatorClientCredential_mobile.cs @@ -0,0 +1,72 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateRecipientClientCredential_mobile.cs b/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateRecipientClientCredential_mobile.cs new file mode 100644 index 00000000000..3545b724b5b --- /dev/null +++ b/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateRecipientClientCredential_mobile.cs @@ -0,0 +1,117 @@ +// +// 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 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 diff --git a/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateValidationMode_mobile.cs b/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateValidationMode_mobile.cs new file mode 100644 index 00000000000..34b1d241c65 --- /dev/null +++ b/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateValidationMode_mobile.cs @@ -0,0 +1,45 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateValidator_mobile.cs b/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateValidator_mobile.cs new file mode 100644 index 00000000000..734e99020d9 --- /dev/null +++ b/mcs/class/Facades/System.ServiceModel.Primitives/X509CertificateValidator_mobile.cs @@ -0,0 +1,43 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceModel.Primitives/X509ServiceCertificateAuthentication_mobile.cs b/mcs/class/Facades/System.ServiceModel.Primitives/X509ServiceCertificateAuthentication_mobile.cs new file mode 100644 index 00000000000..725cbd91538 --- /dev/null +++ b/mcs/class/Facades/System.ServiceModel.Primitives/X509ServiceCertificateAuthentication_mobile.cs @@ -0,0 +1,95 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceModel.Security/TypeForwarders.cs b/mcs/class/Facades/System.ServiceModel.Security/TypeForwarders.cs index 61d5b5a0446..a11a6f59a06 100644 --- a/mcs/class/Facades/System.ServiceModel.Security/TypeForwarders.cs +++ b/mcs/class/Facades/System.ServiceModel.Security/TypeForwarders.cs @@ -24,20 +24,16 @@ [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 diff --git a/mcs/class/Facades/System.ServiceProcess.ServiceController/Makefile b/mcs/class/Facades/System.ServiceProcess.ServiceController/Makefile index 2724a34a105..5fa4c609b0b 100644 --- a/mcs/class/Facades/System.ServiceProcess.ServiceController/Makefile +++ b/mcs/class/Facades/System.ServiceProcess.ServiceController/Makefile @@ -11,7 +11,14 @@ LIBRARY = System.ServiceProcess.ServiceController.dll 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 = diff --git a/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceControllerStatus_mobile.cs b/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceControllerStatus_mobile.cs new file mode 100644 index 00000000000..f233c8bd468 --- /dev/null +++ b/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceControllerStatus_mobile.cs @@ -0,0 +1,49 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceController_mobile.cs b/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceController_mobile.cs new file mode 100644 index 00000000000..f84a27d1c9a --- /dev/null +++ b/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceController_mobile.cs @@ -0,0 +1,246 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceStartMode_mobile.cs b/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceStartMode_mobile.cs new file mode 100644 index 00000000000..3c875c3eb64 --- /dev/null +++ b/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceStartMode_mobile.cs @@ -0,0 +1,47 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceType_mobile.cs b/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceType_mobile.cs new file mode 100644 index 00000000000..ba4f144067c --- /dev/null +++ b/mcs/class/Facades/System.ServiceProcess.ServiceController/ServiceType_mobile.cs @@ -0,0 +1,50 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceProcess.ServiceController/System.ServiceProcess.ServiceController.dll.sources b/mcs/class/Facades/System.ServiceProcess.ServiceController/System.ServiceProcess.ServiceController.dll.sources index 8e33d4ddeae..56e080d93c7 100644 --- a/mcs/class/Facades/System.ServiceProcess.ServiceController/System.ServiceProcess.ServiceController.dll.sources +++ b/mcs/class/Facades/System.ServiceProcess.ServiceController/System.ServiceProcess.ServiceController.dll.sources @@ -1,3 +1,9 @@ TypeForwarders.cs AssemblyInfo.cs +../../../build/common/MonoTODOAttribute.cs +ServiceController_mobile.cs +ServiceControllerStatus_mobile.cs +ServiceStartMode_mobile.cs +ServiceType_mobile.cs +TimeoutException_mobile.cs diff --git a/mcs/class/Facades/System.ServiceProcess.ServiceController/TimeoutException_mobile.cs b/mcs/class/Facades/System.ServiceProcess.ServiceController/TimeoutException_mobile.cs new file mode 100644 index 00000000000..c6448d899ff --- /dev/null +++ b/mcs/class/Facades/System.ServiceProcess.ServiceController/TimeoutException_mobile.cs @@ -0,0 +1,59 @@ +// +// 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 diff --git a/mcs/class/Facades/System.ServiceProcess.ServiceController/TypeForwarders.cs b/mcs/class/Facades/System.ServiceProcess.ServiceController/TypeForwarders.cs index 6a21dfc46f1..b14584243c2 100644 --- a/mcs/class/Facades/System.ServiceProcess.ServiceController/TypeForwarders.cs +++ b/mcs/class/Facades/System.ServiceProcess.ServiceController/TypeForwarders.cs @@ -20,10 +20,14 @@ // 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 diff --git a/mcs/class/Facades/System.Text.Encoding.CodePages/AssemblyInfo.cs b/mcs/class/Facades/System.Text.Encoding.CodePages/AssemblyInfo.cs new file mode 100644 index 00000000000..568942dca14 --- /dev/null +++ b/mcs/class/Facades/System.Text.Encoding.CodePages/AssemblyInfo.cs @@ -0,0 +1,41 @@ +// +// 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] + + diff --git a/mcs/class/Facades/System.Text.Encoding.CodePages/CodePagesEncodingProvider.cs b/mcs/class/Facades/System.Text.Encoding.CodePages/CodePagesEncodingProvider.cs new file mode 100644 index 00000000000..d97ad54eb89 --- /dev/null +++ b/mcs/class/Facades/System.Text.Encoding.CodePages/CodePagesEncodingProvider.cs @@ -0,0 +1,37 @@ +// +// 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 partial class CodePagesEncodingProvider + { + private CodePagesEncodingProvider () + { + } + + public static System.Text.EncodingProvider Instance { + get { + throw new NotImplementedException (); + } + } + } +} \ No newline at end of file diff --git a/mcs/class/Facades/System.Text.Encoding.CodePages/Makefile b/mcs/class/Facades/System.Text.Encoding.CodePages/Makefile new file mode 100644 index 00000000000..7430a65175b --- /dev/null +++ b/mcs/class/Facades/System.Text.Encoding.CodePages/Makefile @@ -0,0 +1,23 @@ +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 + + diff --git a/mcs/class/Facades/System.Text.Encoding.CodePages/System.Text.Encoding.CodePages.dll.sources b/mcs/class/Facades/System.Text.Encoding.CodePages/System.Text.Encoding.CodePages.dll.sources new file mode 100644 index 00000000000..db2c267a189 --- /dev/null +++ b/mcs/class/Facades/System.Text.Encoding.CodePages/System.Text.Encoding.CodePages.dll.sources @@ -0,0 +1,2 @@ +AssemblyInfo.cs +CodePagesEncodingProvider.cs diff --git a/mcs/class/Facades/System.Threading.AccessControl/System.Threading.AccessControl.dll.sources b/mcs/class/Facades/System.Threading.AccessControl/System.Threading.AccessControl.dll.sources index 8e33d4ddeae..0d28c343986 100644 --- a/mcs/class/Facades/System.Threading.AccessControl/System.Threading.AccessControl.dll.sources +++ b/mcs/class/Facades/System.Threading.AccessControl/System.Threading.AccessControl.dll.sources @@ -1,3 +1,5 @@ TypeForwarders.cs AssemblyInfo.cs +../../../build/common/MonoTODOAttribute.cs +ThreadingAclExtensions.cs diff --git a/mcs/class/Facades/System.Threading.AccessControl/ThreadingAclExtensions.cs b/mcs/class/Facades/System.Threading.AccessControl/ThreadingAclExtensions.cs new file mode 100644 index 00000000000..af61a50a0e6 --- /dev/null +++ b/mcs/class/Facades/System.Threading.AccessControl/ThreadingAclExtensions.cs @@ -0,0 +1,75 @@ +// +// 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 diff --git a/mcs/class/Facades/System.Threading.AccessControl/TypeForwarders.cs b/mcs/class/Facades/System.Threading.AccessControl/TypeForwarders.cs index 8871794f349..02fbd79cc8f 100644 --- a/mcs/class/Facades/System.Threading.AccessControl/TypeForwarders.cs +++ b/mcs/class/Facades/System.Threading.AccessControl/TypeForwarders.cs @@ -33,4 +33,3 @@ [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))] diff --git a/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolBoundHandle.cs b/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolBoundHandle.cs new file mode 100644 index 00000000000..40253fbc05a --- /dev/null +++ b/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolBoundHandle.cs @@ -0,0 +1,315 @@ +// 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 + // + + /// + /// 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. + /// + public sealed partial class ThreadPoolBoundHandle : IDisposable + { + private readonly SafeHandle _handle; + private bool _isDisposed; + + private ThreadPoolBoundHandle(SafeHandle handle) + { + _handle = handle; + } + + /// + /// Gets the bound operating system handle. + /// + /// + /// A object that holds the bound operating system handle. + /// + public SafeHandle Handle + { + get { return _handle; } + } + + /// + /// Returns a for the specific handle, + /// which is bound to the system thread pool. + /// + /// + /// A object that holds the operating system handle. The + /// handle must have been opened for overlapped I/O on the unmanaged side. + /// + /// + /// for , which + /// is bound to the system thread pool. + /// + /// + /// is . + /// + /// + /// has been disposed. + /// + /// -or- + /// + /// does not refer to a valid I/O handle. + /// + /// -or- + /// + /// refers to a handle that has not been opened + /// for overlapped I/O. + /// + /// -or- + /// + /// refers to a handle that has already been bound. + /// + /// + /// This method should be called once per handle. + /// + /// -or- + /// + /// does not take ownership of , + /// it remains the responsibility of the caller to call . + /// + 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); + } + + /// + /// Returns an unmanaged pointer to a 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. + /// + /// + /// An delegate that represents the callback method + /// invoked when the asynchronous I/O operation completes. + /// + /// + /// A user-provided object that distinguishes this from other + /// instances. Can be . + /// + /// + /// 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 . + /// + /// + /// An unmanaged pointer to a structure. + /// + /// + /// + /// The unmanaged pointer returned by this method can be passed to the operating system in + /// overlapped I/O operations. The structure is fixed in + /// physical memory until is called. + /// + /// + /// The buffer or buffers specified in must be the same as those passed + /// to the unmanaged operating system function that performs the asynchronous I/O. + /// + /// + /// The buffers specified in are pinned for the duration of + /// the I/O operation. + /// + /// + /// + /// is . + /// + /// + /// This method was called after the was disposed. + /// + 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; + } + + /// + /// Returns an unmanaged pointer to a structure, using the callback, + /// state, and buffers associated with the specified object. + /// + /// + /// A object from which to create the NativeOverlapped pointer. + /// + /// + /// An unmanaged pointer to a structure. + /// + /// + /// + /// The unmanaged pointer returned by this method can be passed to the operating system in + /// overlapped I/O operations. The structure is fixed in + /// physical memory until is called. + /// + /// + /// + /// is . + /// + /// + /// is currently in use for another I/O operation. + /// + /// + /// This method was called after the was disposed, or + /// this method was called after was disposed. + /// + /// + 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; + } + } + + /// + /// Frees the unmanaged memory associated with a structure + /// allocated by the method. + /// + /// + /// An unmanaged pointer to the structure to be freed. + /// + /// + /// + /// You must call the method exactly once + /// on every unmanaged pointer allocated using the + /// method. + /// If you do not call the method, you will + /// leak memory. If you call the method more + /// than once on the same unmanaged pointer, memory will be corrupted. + /// + /// + /// + /// is . + /// + /// + /// This method was called after the was disposed. + /// + 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); + } + + /// + /// Returns the user-provided object specified when the instance was + /// allocated using the . + /// + /// + /// An unmanaged pointer to the structure from which to return the + /// asscociated user-provided object. + /// + /// + /// A user-provided object that distinguishes this + /// from other instances, otherwise, if one was + /// not specified when the instance was allocated using . + /// + /// + /// is . + /// + 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 diff --git a/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolBoundHandleOverlapped.cs b/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolBoundHandleOverlapped.cs new file mode 100644 index 00000000000..2245254ed2f --- /dev/null +++ b/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolBoundHandleOverlapped.cs @@ -0,0 +1,50 @@ +// 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 +{ + /// + /// Overlapped subclass adding data needed by ThreadPoolBoundHandle. + /// + 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 diff --git a/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolPreAllocatedOverlapped.cs b/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolPreAllocatedOverlapped.cs new file mode 100644 index 00000000000..dfc7d472726 --- /dev/null +++ b/mcs/class/Facades/System.Threading.Overlapped/ClrThreadPoolPreAllocatedOverlapped.cs @@ -0,0 +1,104 @@ +// 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 +{ + /// + /// Represents pre-allocated state for native overlapped I/O operations. + /// + /// + public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable + { + internal readonly ThreadPoolBoundHandleOverlapped _overlapped; + private DeferredDisposableLifetime _lifetime; + + /// + /// Initializes a new instance of the 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. + /// + /// + /// An delegate that represents the callback method + /// invoked when each asynchronous I/O operation completes. + /// + /// + /// A user-provided object that distinguishes instance produced from this + /// object from other instances. Can be . + /// + /// + /// 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 . + /// + /// + /// The new instance can be passed to + /// , to produce + /// a instance that can be passed to the operating system in overlapped + /// I/O operations. A single instance can only be used for + /// a single native I/O operation at a time. However, the state stored in the + /// instance can be reused for subsequent native operations. + /// + /// The buffers specified in are pinned until is called. + /// + /// + /// + /// is . + /// + /// + /// This method was called after the was disposed. + /// + 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); + } + + /// + /// Frees the resources associated with this instance. + /// + 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 diff --git a/mcs/class/Facades/System.Threading.Overlapped/DeferredDisposableLifetime.cs b/mcs/class/Facades/System.Threading.Overlapped/DeferredDisposableLifetime.cs new file mode 100644 index 00000000000..24509062c74 --- /dev/null +++ b/mcs/class/Facades/System.Threading.Overlapped/DeferredDisposableLifetime.cs @@ -0,0 +1,116 @@ +// 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 +{ + /// + /// Provides callbacks to objects whose lifetime is managed by . + /// + internal interface IDeferredDisposable + { + /// + /// Called when the object's refcount reaches zero. + /// + /// + /// Indicates whether the object has been disposed. + /// + /// + /// If the refount reaches zero before the object is disposed, this method will be called with + /// set to false. If the object is then disposed, this method will be + /// called again, with set to true. If the refcount reaches zero + /// after the object has already been disposed, this will be called a single time, with + /// set to true. + /// + void OnFinalRelease(bool disposed); + } + + /// + /// 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. + /// + /// The type of object whose lifetime will be managed. + /// + /// This type maintains a reference count, and tracks whether the object has been disposed. When + /// Callbacks are made to 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 when + /// 'disposed' is true. + /// + internal struct DeferredDisposableLifetime 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 diff --git a/mcs/class/Facades/System.Threading.Overlapped/HResults.cs b/mcs/class/Facades/System.Threading.Overlapped/HResults.cs new file mode 100644 index 00000000000..ef9a772aaa1 --- /dev/null +++ b/mcs/class/Facades/System.Threading.Overlapped/HResults.cs @@ -0,0 +1,38 @@ +// +// 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 diff --git a/mcs/class/Facades/System.Threading.Overlapped/Makefile b/mcs/class/Facades/System.Threading.Overlapped/Makefile index 460fb4aff26..061c46b236b 100644 --- a/mcs/class/Facades/System.Threading.Overlapped/Makefile +++ b/mcs/class/Facades/System.Threading.Overlapped/Makefile @@ -12,7 +12,7 @@ LIBRARY = System.Threading.Overlapped.dll 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 = diff --git a/mcs/class/Facades/System.Threading.Overlapped/SR.cs b/mcs/class/Facades/System.Threading.Overlapped/SR.cs new file mode 100644 index 00000000000..a65446d4b50 --- /dev/null +++ b/mcs/class/Facades/System.Threading.Overlapped/SR.cs @@ -0,0 +1,11 @@ +// 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 diff --git a/mcs/class/Facades/System.Threading.Overlapped/System.Threading.Overlapped.dll.sources b/mcs/class/Facades/System.Threading.Overlapped/System.Threading.Overlapped.dll.sources index 8e33d4ddeae..eb1041a8bbb 100644 --- a/mcs/class/Facades/System.Threading.Overlapped/System.Threading.Overlapped.dll.sources +++ b/mcs/class/Facades/System.Threading.Overlapped/System.Threading.Overlapped.dll.sources @@ -1,3 +1,9 @@ TypeForwarders.cs AssemblyInfo.cs +ClrThreadPoolBoundHandle.cs +ClrThreadPoolBoundHandleOverlapped.cs +ClrThreadPoolPreAllocatedOverlapped.cs +DeferredDisposableLifetime.cs +SR.cs +HResults.cs diff --git a/mcs/class/Facades/System.Threading.Overlapped/TypeForwarders.cs b/mcs/class/Facades/System.Threading.Overlapped/TypeForwarders.cs index 127e5a1f080..dd272df5d99 100644 --- a/mcs/class/Facades/System.Threading.Overlapped/TypeForwarders.cs +++ b/mcs/class/Facades/System.Threading.Overlapped/TypeForwarders.cs @@ -22,6 +22,3 @@ [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))] diff --git a/mcs/class/Facades/System.Xml.ReaderWriter/TypeForwarders.cs b/mcs/class/Facades/System.Xml.ReaderWriter/TypeForwarders.cs index 1b3e7a3a46b..a4915b94613 100644 --- a/mcs/class/Facades/System.Xml.ReaderWriter/TypeForwarders.cs +++ b/mcs/class/Facades/System.Xml.ReaderWriter/TypeForwarders.cs @@ -47,4 +47,5 @@ [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))] diff --git a/mcs/class/Facades/System.Xml.XPath.XDocument/Makefile b/mcs/class/Facades/System.Xml.XPath.XDocument/Makefile index 45ffe3482e0..16a26f2c55d 100644 --- a/mcs/class/Facades/System.Xml.XPath.XDocument/Makefile +++ b/mcs/class/Facades/System.Xml.XPath.XDocument/Makefile @@ -11,7 +11,7 @@ LIBRARY = System.Xml.XPath.XDocument.dll 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 = diff --git a/mcs/class/Facades/System.Xml.XPath.XDocument/System.Xml.XPath.XDocument.dll.sources b/mcs/class/Facades/System.Xml.XPath.XDocument/System.Xml.XPath.XDocument.dll.sources index 8e33d4ddeae..dc18bbbbcbe 100644 --- a/mcs/class/Facades/System.Xml.XPath.XDocument/System.Xml.XPath.XDocument.dll.sources +++ b/mcs/class/Facades/System.Xml.XPath.XDocument/System.Xml.XPath.XDocument.dll.sources @@ -1,3 +1,3 @@ TypeForwarders.cs AssemblyInfo.cs - +XDocumentExtensions.cs diff --git a/mcs/class/Facades/System.Xml.XPath.XDocument/TypeForwarders.cs b/mcs/class/Facades/System.Xml.XPath.XDocument/TypeForwarders.cs index a9ce64258f8..0fec9f720b4 100644 --- a/mcs/class/Facades/System.Xml.XPath.XDocument/TypeForwarders.cs +++ b/mcs/class/Facades/System.Xml.XPath.XDocument/TypeForwarders.cs @@ -22,4 +22,3 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XPath.Extensions))] -//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Xml.XPath.XDocumentExtensions))] diff --git a/mcs/class/Facades/System.Xml.XPath.XDocument/XDocumentExtensions.cs b/mcs/class/Facades/System.Xml.XPath.XDocument/XDocumentExtensions.cs new file mode 100644 index 00000000000..d254f73fe4a --- /dev/null +++ b/mcs/class/Facades/System.Xml.XPath.XDocument/XDocumentExtensions.cs @@ -0,0 +1,29 @@ + +// 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 diff --git a/mcs/class/Facades/subdirs.make b/mcs/class/Facades/subdirs.make index ebece6f697a..e7d21881798 100644 --- a/mcs/class/Facades/subdirs.make +++ b/mcs/class/Facades/subdirs.make @@ -3,13 +3,13 @@ # 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 \ @@ -22,25 +22,45 @@ System.Net.Utilities System.Net.WebHeaderCollection System.Net.WebSockets System 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.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 \ +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) +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) 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) diff --git a/mcs/class/Makefile b/mcs/class/Makefile index efc8181c02e..46db72b36c7 100644 --- a/mcs/class/Makefile +++ b/mcs/class/Makefile @@ -23,6 +23,7 @@ mobile_common_dirs := \ Mono.Security \ System \ System.Core \ + System.Security \ System.XML \ I18N \ System.ServiceModel.Internals \ @@ -36,6 +37,7 @@ mobile_common_dirs := \ Mono.Data.Tds \ System.Transactions \ System.Numerics \ + System.Numerics.Vectors \ System.Data \ Mono.Cairo \ Mono.Data.Sqlite \ @@ -54,7 +56,11 @@ mobile_common_dirs := \ 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) \ @@ -95,6 +101,7 @@ xammac_4_5_dirs := \ System \ Mono.Posix \ System.Core \ + System.Security \ System.XML \ I18N \ System.ServiceModel.Internals \ @@ -130,11 +137,14 @@ xammac_4_5_dirs := \ 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 := \ @@ -278,6 +288,7 @@ net_4_x_parallel_dirs := \ System.Workflow.Activities \ System.Workflow.ComponentModel \ System.Workflow.Runtime \ + System.Reflection.Context \ $(pcl_facade_dirs) xbuild_2_0_dirs := \ diff --git a/mcs/class/Mono.Tasklets/Makefile b/mcs/class/Mono.Tasklets/Makefile index 8883dbaf834..19a6cc1ceed 100644 --- a/mcs/class/Mono.Tasklets/Makefile +++ b/mcs/class/Mono.Tasklets/Makefile @@ -3,7 +3,9 @@ SUBDIRS = include ../../build/rules.make LIBRARY = Mono.Tasklets.dll -NO_TEST = yes + +LIB_MCS_FLAGS = +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) include ../../build/library.make diff --git a/mcs/class/Mono.Tasklets/Mono.Tasklets_test.dll.sources b/mcs/class/Mono.Tasklets/Mono.Tasklets_test.dll.sources new file mode 100644 index 00000000000..f994ee35b3d --- /dev/null +++ b/mcs/class/Mono.Tasklets/Mono.Tasklets_test.dll.sources @@ -0,0 +1 @@ +Mono.Tasklets/ContinuationsTest.cs diff --git a/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs b/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs new file mode 100644 index 00000000000..d0b2de65429 --- /dev/null +++ b/mcs/class/Mono.Tasklets/Test/Mono.Tasklets/ContinuationsTest.cs @@ -0,0 +1,175 @@ +using NUnit.Framework; + +using System; +using Mono.Tasklets; + +namespace MonoTests.System +{ + [TestFixture] + public class ContinuationsTest { + + private Continuation _contA = new Continuation(); + + private int total = 0; + + [Test] + public void TestContinuationsLoop() { + _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); + } + } +} + +// vim: noexpandtab +// Local Variables: +// tab-width: 4 +// c-basic-offset: 4 +// indent-tabs-mode: t +// End: diff --git a/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptHandle.cs b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptHandle.cs new file mode 100644 index 00000000000..873ce5782aa --- /dev/null +++ b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptHandle.cs @@ -0,0 +1,49 @@ +// +// SafeNCryptHandle.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptKeyHandle.cs b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptKeyHandle.cs new file mode 100644 index 00000000000..3dcbfae8d6d --- /dev/null +++ b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptKeyHandle.cs @@ -0,0 +1,42 @@ +// +// SafeNCryptKeyHandle.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptProviderHandle.cs b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptProviderHandle.cs new file mode 100644 index 00000000000..4a2d17ab828 --- /dev/null +++ b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptProviderHandle.cs @@ -0,0 +1,42 @@ +// +// SafeNCryptProviderHandle.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptSecretHandle.cs b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptSecretHandle.cs new file mode 100644 index 00000000000..8943e38e48d --- /dev/null +++ b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeNCryptSecretHandle.cs @@ -0,0 +1,42 @@ +// +// SafeNCryptSecretHandle.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeClientStream.cs b/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeClientStream.cs index 2c195034d83..23bf26f7482 100644 --- a/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeClientStream.cs +++ b/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeClientStream.cs @@ -63,7 +63,7 @@ namespace System.IO.Pipes { } - public AnonymousPipeClientStream (PipeDirection direction,SafePipeHandle safePipeHandle) + public AnonymousPipeClientStream (PipeDirection direction, SafePipeHandle safePipeHandle) : base (direction, DefaultBufferSize) { /* @@ -73,7 +73,11 @@ namespace System.IO.Pipes impl = new UnixAnonymousPipeClient (this, safePipeHandle); */ +#if MOBILE + throw new NotImplementedException (); +#else InitializeHandle (safePipeHandle, false, false); +#endif IsConnected = true; } diff --git a/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeServerStream.cs b/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeServerStream.cs index 01e4b1dbf49..97455f30cda 100644 --- a/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeServerStream.cs +++ b/mcs/class/System.Core/System.IO.Pipes/AnonymousPipeServerStream.cs @@ -59,10 +59,18 @@ namespace System.IO.Pipes } 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) { @@ -77,6 +85,7 @@ namespace System.IO.Pipes InitializeHandle (impl.Handle, false, false); IsConnected = true; } +#endif [MonoTODO] public AnonymousPipeServerStream (PipeDirection direction, SafePipeHandle serverSafePipeHandle, SafePipeHandle clientSafePipeHandle) @@ -90,6 +99,9 @@ namespace System.IO.Pipes 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 @@ -99,6 +111,12 @@ namespace System.IO.Pipes IsConnected = true; ClientSafePipeHandle = clientSafePipeHandle; +#endif + } + + ~AnonymousPipeServerStream () + { + // To be compatible with .net } IAnonymousPipeServer impl; diff --git a/mcs/class/System.Core/System.IO.Pipes/NamedPipeClientStream.cs b/mcs/class/System.Core/System.IO.Pipes/NamedPipeClientStream.cs index 357f7387d23..181ab1ccbf0 100644 --- a/mcs/class/System.Core/System.IO.Pipes/NamedPipeClientStream.cs +++ b/mcs/class/System.Core/System.IO.Pipes/NamedPipeClientStream.cs @@ -72,21 +72,33 @@ namespace System.IO.Pipes } 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) { @@ -99,21 +111,30 @@ namespace System.IO.Pipes 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 { diff --git a/mcs/class/System.Core/System.IO.Pipes/NamedPipeServerStream.cs b/mcs/class/System.Core/System.IO.Pipes/NamedPipeServerStream.cs index b29deaf3301..2723109bd98 100644 --- a/mcs/class/System.Core/System.IO.Pipes/NamedPipeServerStream.cs +++ b/mcs/class/System.Core/System.IO.Pipes/NamedPipeServerStream.cs @@ -70,10 +70,18 @@ namespace System.IO.Pipes } 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) { @@ -101,16 +109,26 @@ namespace System.IO.Pipes 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; @@ -120,12 +138,14 @@ namespace System.IO.Pipes impl.Disconnect (); } +#if !MOBILE [MonoTODO] [SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal)] public void RunAsClient (PipeStreamImpersonationWorker impersonationWorker) { throw new NotImplementedException (); } +#endif public void WaitForConnection () { @@ -140,6 +160,7 @@ namespace System.IO.Pipes throw new NotImplementedException (); } +#if !MOBILE // async operations Action wait_connect_delegate; @@ -156,6 +177,7 @@ namespace System.IO.Pipes { wait_connect_delegate.EndInvoke (asyncResult); } +#endif } } diff --git a/mcs/class/System.Core/System.IO.Pipes/PipeStream.cs b/mcs/class/System.Core/System.IO.Pipes/PipeStream.cs index fd4a57a6930..ed030e7608b 100644 --- a/mcs/class/System.Core/System.IO.Pipes/PipeStream.cs +++ b/mcs/class/System.Core/System.IO.Pipes/PipeStream.cs @@ -46,15 +46,18 @@ namespace System.IO.Pipes // 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) { @@ -85,6 +88,7 @@ namespace System.IO.Pipes throw new ArgumentOutOfRangeException (); } } +#endif protected PipeStream (PipeDirection direction, int bufferSize) : this (direction, PipeTransmissionMode.Byte, bufferSize) @@ -140,7 +144,9 @@ namespace System.IO.Pipes set { stream = value; } } +#if !MOBILE protected bool IsHandleExposed { get; private set; } +#endif [MonoTODO] public bool IsMessageComplete { get; private set; } @@ -176,7 +182,19 @@ namespace System.IO.Pipes } // initialize/dispose/state check +#if MOBILE + internal static void CheckPipePropertyOperations () + { + } + static void CheckReadOperations () + { + } + + static void CheckWriteOperations () + { + } +#else [MonoTODO] protected internal virtual void CheckPipePropertyOperations () { @@ -206,6 +224,7 @@ namespace System.IO.Pipes this.IsHandleExposed = isExposed; this.IsAsync = isAsync; } +#endif protected override void Dispose (bool disposing) { @@ -234,6 +253,7 @@ namespace System.IO.Pipes throw new NotSupportedException (); } +#if !MOBILE public PipeSecurity GetAccessControl () { return new PipeSecurity (SafePipeHandle, @@ -255,6 +275,7 @@ namespace System.IO.Pipes public void WaitForPipeDrain () { } +#endif [MonoTODO] public override int Read ([In] byte [] buffer, int offset, int count) @@ -298,6 +319,7 @@ namespace System.IO.Pipes // async +#if !MOBILE Func read_delegate; [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)] @@ -327,6 +349,7 @@ namespace System.IO.Pipes { write_delegate.EndInvoke (asyncResult); } +#endif } } diff --git a/mcs/class/System.Core/System.Security.Cryptography/AesCng.cs b/mcs/class/System.Core/System.Security.Cryptography/AesCng.cs new file mode 100644 index 00000000000..64377b7bf09 --- /dev/null +++ b/mcs/class/System.Core/System.Security.Cryptography/AesCng.cs @@ -0,0 +1,104 @@ +// +// AesCng.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/System.Core/System.Security.Cryptography/TripleDESCng.cs b/mcs/class/System.Core/System.Security.Cryptography/TripleDESCng.cs new file mode 100644 index 00000000000..48f93772b69 --- /dev/null +++ b/mcs/class/System.Core/System.Security.Cryptography/TripleDESCng.cs @@ -0,0 +1,104 @@ +// +// TripleDESCng.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/System.Core/common_System.Core.dll.sources b/mcs/class/System.Core/common_System.Core.dll.sources index 8457ac0ffa9..4489cceea18 100644 --- a/mcs/class/System.Core/common_System.Core.dll.sources +++ b/mcs/class/System.Core/common_System.Core.dll.sources @@ -6,8 +6,25 @@ System.IO.MemoryMappedFiles/MemoryMappedFile.cs 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 @@ -187,9 +204,20 @@ ReferenceSources/Strings.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 diff --git a/mcs/class/System.Core/mobile_static_System.Core.dll.sources b/mcs/class/System.Core/mobile_static_System.Core.dll.sources index 0d79ec4913e..8b8fef0e40e 100644 --- a/mcs/class/System.Core/mobile_static_System.Core.dll.sources +++ b/mcs/class/System.Core/mobile_static_System.Core.dll.sources @@ -3,8 +3,6 @@ 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 diff --git a/mcs/class/System.Core/net_4_x_System.Core.dll.sources b/mcs/class/System.Core/net_4_x_System.Core.dll.sources index 5dedcbf316c..f367efd60c7 100644 --- a/mcs/class/System.Core/net_4_x_System.Core.dll.sources +++ b/mcs/class/System.Core/net_4_x_System.Core.dll.sources @@ -1,29 +1,16 @@ #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 diff --git a/mcs/class/System.Data/Microsoft.SqlServer.Server/SqlDataRecord.cs b/mcs/class/System.Data/Microsoft.SqlServer.Server/SqlDataRecord.cs index b928fc4086a..04a93d20c2d 100644 --- a/mcs/class/System.Data/Microsoft.SqlServer.Server/SqlDataRecord.cs +++ b/mcs/class/System.Data/Microsoft.SqlServer.Server/SqlDataRecord.cs @@ -35,87 +35,87 @@ namespace Microsoft.SqlServer.Server { public sealed class SqlDataRecord : IDataRecord { - public bool GetBoolean (int i) + public bool GetBoolean (int ordinal) { throw new NotImplementedException (); } - public byte GetByte (int i) + public byte GetByte (int ordinal) { throw new NotImplementedException (); } - public long GetBytes (int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + public long GetBytes (int ordinal, long fieldOffset, byte[] buffer, int bufferOffset, int length) { throw new NotImplementedException (); } - public char GetChar (int i) + public char GetChar (int ordinal) { throw new NotImplementedException (); } - public long GetChars (int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + public long GetChars (int ordinal, long fieldOffset, char[] buffer, int bufferOffset, int length) { throw new NotImplementedException (); } - public IDataReader GetData (int i) + public IDataReader GetData (int ordinal) { throw new NotImplementedException (); } - public string GetDataTypeName (int i) + public string GetDataTypeName (int ordinal) { throw new NotImplementedException (); } - public DateTime GetDateTime (int i) + public DateTime GetDateTime (int ordinal) { throw new NotImplementedException (); } - public decimal GetDecimal (int i) + public decimal GetDecimal (int ordinal) { throw new NotImplementedException (); } - public double GetDouble (int i) + public double GetDouble (int ordinal) { throw new NotImplementedException (); } - public System.Type GetFieldType (int i) + public System.Type GetFieldType (int ordinal) { throw new NotImplementedException (); } - public float GetFloat (int i) + public float GetFloat (int ordinal) { throw new NotImplementedException (); } - public Guid GetGuid (int i) + public Guid GetGuid (int ordinal) { throw new NotImplementedException (); } - public short GetInt16 (int i) + public short GetInt16 (int ordinal) { throw new NotImplementedException (); } - public int GetInt32 (int i) + public int GetInt32 (int ordinal) { throw new NotImplementedException (); } - public long GetInt64 (int i) + public long GetInt64 (int ordinal) { throw new NotImplementedException (); } - public string GetName (int i) + public string GetName (int ordinal) { throw new NotImplementedException (); } @@ -125,12 +125,12 @@ namespace Microsoft.SqlServer.Server throw new NotImplementedException (); } - public string GetString (int i) + public string GetString (int ordinal) { throw new NotImplementedException (); } - public object GetValue (int i) + public object GetValue (int ordinal) { throw new NotImplementedException (); } @@ -140,7 +140,7 @@ namespace Microsoft.SqlServer.Server throw new NotImplementedException (); } - public bool IsDBNull (int i) + public bool IsDBNull (int ordinal) { throw new NotImplementedException (); } @@ -151,13 +151,13 @@ namespace Microsoft.SqlServer.Server } } - public object this [string index] { + public object this [string name] { get { throw new NotImplementedException (); } } - public object this [int index] { + public object this [int ordinal] { get { throw new NotImplementedException (); } diff --git a/mcs/class/System.Drawing/Makefile b/mcs/class/System.Drawing/Makefile index 59ff776b9f1..e815bbf4afb 100644 --- a/mcs/class/System.Drawing/Makefile +++ b/mcs/class/System.Drawing/Makefile @@ -5,7 +5,7 @@ SUBDIRS = 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 diff --git a/mcs/class/System.Drawing/System.Drawing/Point.cs b/mcs/class/System.Drawing/System.Drawing/Point.cs index 88a8390b564..53f9568067a 100644 --- a/mcs/class/System.Drawing/System.Drawing/Point.cs +++ b/mcs/class/System.Drawing/System.Drawing/Point.cs @@ -40,7 +40,7 @@ namespace System.Drawing { [Serializable] [ComVisible (true)] -#if !MONOTOUCH && !MONOMAC +#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER [TypeConverter (typeof (PointConverter))] #endif public struct Point diff --git a/mcs/class/System.Drawing/System.Drawing/Rectangle.cs b/mcs/class/System.Drawing/System.Drawing/Rectangle.cs index c2ffbc80e5e..0d1194675b2 100644 --- a/mcs/class/System.Drawing/System.Drawing/Rectangle.cs +++ b/mcs/class/System.Drawing/System.Drawing/Rectangle.cs @@ -39,7 +39,7 @@ namespace System.Drawing { [Serializable] [ComVisible (true)] -#if !MONOTOUCH && !MONOMAC +#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER [TypeConverter (typeof (RectangleConverter))] #endif public struct Rectangle diff --git a/mcs/class/System.Drawing/System.Drawing/Size.cs b/mcs/class/System.Drawing/System.Drawing/Size.cs index be8fda0ea8e..3c657dc29f2 100644 --- a/mcs/class/System.Drawing/System.Drawing/Size.cs +++ b/mcs/class/System.Drawing/System.Drawing/Size.cs @@ -40,7 +40,7 @@ namespace System.Drawing { [Serializable] [ComVisible (true)] -#if !MONOTOUCH && !MONOMAC +#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER [TypeConverter (typeof (SizeConverter))] #endif public struct Size diff --git a/mcs/class/System.Drawing/System.Drawing/SizeF.cs b/mcs/class/System.Drawing/System.Drawing/SizeF.cs index 38714d1c996..922ab4e35e2 100644 --- a/mcs/class/System.Drawing/System.Drawing/SizeF.cs +++ b/mcs/class/System.Drawing/System.Drawing/SizeF.cs @@ -40,7 +40,7 @@ namespace System.Drawing { [Serializable] [ComVisible (true)] -#if !MONOTOUCH && !MONOMAC +#if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER [TypeConverter (typeof (SizeFConverter))] #endif public struct SizeF diff --git a/mcs/class/System.Net.Http.WinHttpHandler/Assembly/AssemblyInfo.cs b/mcs/class/System.Net.Http.WinHttpHandler/Assembly/AssemblyInfo.cs new file mode 100644 index 00000000000..d477aee4490 --- /dev/null +++ b/mcs/class/System.Net.Http.WinHttpHandler/Assembly/AssemblyInfo.cs @@ -0,0 +1,62 @@ +// +// 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 diff --git a/mcs/class/System.Net.Http.WinHttpHandler/Makefile b/mcs/class/System.Net.Http.WinHttpHandler/Makefile new file mode 100644 index 00000000000..55b07ffdd63 --- /dev/null +++ b/mcs/class/System.Net.Http.WinHttpHandler/Makefile @@ -0,0 +1,11 @@ +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 diff --git a/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.dll.sources b/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.dll.sources new file mode 100644 index 00000000000..97feb39e8ae --- /dev/null +++ b/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http.WinHttpHandler.dll.sources @@ -0,0 +1,8 @@ +../../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 diff --git a/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/CookieUsePolicy.cs b/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/CookieUsePolicy.cs new file mode 100644 index 00000000000..f27cb2ca49f --- /dev/null +++ b/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/CookieUsePolicy.cs @@ -0,0 +1,39 @@ +// +// 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 diff --git a/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/WinHttpHandler.cs b/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/WinHttpHandler.cs new file mode 100644 index 00000000000..e2db5f66fac --- /dev/null +++ b/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/WinHttpHandler.cs @@ -0,0 +1,92 @@ +// +// 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 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 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 SendAsync (HttpRequestMessage request, Threading.CancellationToken cancellationToken) { throw new PlatformNotSupportedException (); } + } +} \ No newline at end of file diff --git a/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/WindowsProxyUsePolicy.cs b/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/WindowsProxyUsePolicy.cs new file mode 100644 index 00000000000..48de6bb82c2 --- /dev/null +++ b/mcs/class/System.Net.Http.WinHttpHandler/System.Net.Http/WindowsProxyUsePolicy.cs @@ -0,0 +1,40 @@ +// +// 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 diff --git a/mcs/class/System.Numerics.Vectors/Makefile b/mcs/class/System.Numerics.Vectors/Makefile index 47fa0620e97..42fb194dbfb 100644 --- a/mcs/class/System.Numerics.Vectors/Makefile +++ b/mcs/class/System.Numerics.Vectors/Makefile @@ -4,7 +4,7 @@ include ../../build/rules.make LIBRARY = System.Numerics.Vectors.dll LIB_REFS = System System.Numerics -LIB_MCS_FLAGS = +LIB_MCS_FLAGS = -unsafe EXTRA_DISTFILES = diff --git a/mcs/class/System.Numerics.Vectors/SR.cs b/mcs/class/System.Numerics.Vectors/SR.cs new file mode 100644 index 00000000000..72e9cfb0ac1 --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/SR.cs @@ -0,0 +1,17 @@ +// 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.Count cannot be called via reflection when intrinsics are enabled."; + + public static string Format (string message, object data) + { + return string.Format (message, data); + } +} diff --git a/mcs/class/System.Numerics.Vectors/System.Numerics.Vectors.dll.sources b/mcs/class/System.Numerics.Vectors/System.Numerics.Vectors.dll.sources index 0a2dca5005f..01bdfc1724e 100644 --- a/mcs/class/System.Numerics.Vectors/System.Numerics.Vectors.dll.sources +++ b/mcs/class/System.Numerics.Vectors/System.Numerics.Vectors.dll.sources @@ -2,3 +2,10 @@ ../../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 diff --git a/mcs/class/System.Numerics.Vectors/System.Numerics/ConstantHelper.cs b/mcs/class/System.Numerics.Vectors/System.Numerics/ConstantHelper.cs new file mode 100644 index 00000000000..ea32ed3803f --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/System.Numerics/ConstantHelper.cs @@ -0,0 +1,142 @@ +// 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; + } + } +} diff --git a/mcs/class/System.Numerics.Vectors/System.Numerics/HashCodeHelper.cs b/mcs/class/System.Numerics.Vectors/System.Numerics/HashCodeHelper.cs new file mode 100644 index 00000000000..1467e2f68f8 --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/System.Numerics/HashCodeHelper.cs @@ -0,0 +1,17 @@ +// 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 + { + /// + /// Combines two hash codes, useful for combining hash codes of individual vector elements + /// + internal static int CombineHashCodes(int h1, int h2) + { + return (((h1 << 5) + h1) ^ h2); + } + } +} diff --git a/mcs/class/System.Numerics.Vectors/System.Numerics/JitIntrinsicAttribute.cs b/mcs/class/System.Numerics.Vectors/System.Numerics/JitIntrinsicAttribute.cs new file mode 100644 index 00000000000..741041222f8 --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/System.Numerics/JitIntrinsicAttribute.cs @@ -0,0 +1,14 @@ +// 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 +{ + /// + /// An attribute that can be attached to JIT Intrinsic methods/properties + /// + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)] + internal class JitIntrinsicAttribute : Attribute + { + } +} diff --git a/mcs/class/System.Numerics.Vectors/System.Numerics/Register.cs b/mcs/class/System.Numerics.Vectors/System.Numerics/Register.cs new file mode 100644 index 00000000000..a27e922b9d8 --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/System.Numerics/Register.cs @@ -0,0 +1,172 @@ +// 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 +{ + /// + /// 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. + /// + [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 + } +} diff --git a/mcs/class/System.Numerics.Vectors/System.Numerics/Vector.cs b/mcs/class/System.Numerics.Vectors/System.Numerics/Vector.cs new file mode 100644 index 00000000000..13785ed5cfe --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/System.Numerics/Vector.cs @@ -0,0 +1,5002 @@ +// 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 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.) + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /// + /// 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. + /// + public struct Vector : IEquatable>, IFormattable where T : struct + { + #region Fields + private Register register; + #endregion Fields + + #region Static Members + /// + /// Returns the number of elements stored in the vector. This value is hardware dependent. + /// + [JitIntrinsic] + public static int Count + { + get + { + return s_count; + } + } + private static readonly int s_count = InitializeCount(); + + /// + /// Returns a vector containing all zeroes. + /// + [JitIntrinsic] + public static Vector Zero { get { return zero; } } + private static readonly Vector zero = new Vector(GetZeroValue()); + + /// + /// Returns a vector containing all ones. + /// + [JitIntrinsic] + public static Vector One { get { return one; } } + private static readonly Vector one = new Vector(GetOneValue()); + + internal static Vector AllOnes { get { return allOnes; } } + private static readonly Vector allOnes = new Vector(GetAllBitsSetValue()); + #endregion Static Members + + #region Static Initialization + private struct VectorSizeHelper + { + internal Vector _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 + /// + /// Constructs a vector whose components are all value + /// + [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; + } + } + } + + /// + /// Constructs a vector from the given array. The size of the given array must be at least Vector'T.Count. + /// + [JitIntrinsic] + public unsafe Vector(T[] values) : this(values, 0) { } + + /// + /// 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. + /// + 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 + /// + /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count. + /// + /// The destination array which the values are copied into + /// If the destination array is null + /// If number of elements in source vector is greater than those available in destination array + [JitIntrinsic] + public unsafe void CopyTo(T[] destination) + { + CopyTo(destination, 0); + } + + /// + /// Copies the vector to the given destination array. The destination array must be at least size Vector'T.Count. + /// + /// The destination array which the values are copied into + /// The index to start copying to + /// If the destination array is null + /// If index is greater than end of the array or index is less than zero + /// If number of elements in source vector is greater than those available in destination array + [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; + } + } + } + } + + /// + /// Returns the element at the given index. + /// + [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); + } + } + } + + /// + /// Returns a boolean indicating whether the given Object is equal to this vector instance. + /// + /// The Object to compare against. + /// True if the Object is equal to this vector; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public override bool Equals(object obj) + { + if (!(obj is Vector)) + { + return false; + } + return Equals((Vector)obj); + } + + /// + /// Returns a boolean indicating whether the given vector is equal to this vector instance. + /// + /// The vector to compare this instance to. + /// True if the other vector is equal to this instance; False otherwise. + [JitIntrinsic] + public bool Equals(Vector 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); + } + } + } + + /// + /// Returns the hash code for this instance. + /// + /// The hash code. + 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); + } + } + } + + /// + /// Returns a String representing this vector. + /// + /// The string representation. + public override string ToString() + { + return ToString("G", CultureInfo.CurrentCulture); + } + + /// + /// Returns a String representing this vector, using the specified format string to format individual elements. + /// + /// The format of individual elements. + /// The string representation. + public string ToString(string format) + { + return ToString(format, CultureInfo.CurrentCulture); + } + + /// + /// Returns a String representing this vector, using the specified format string to format individual elements + /// and the given IFormatProvider. + /// + /// The format of individual elements. + /// The format provider to use when formatting elements. + /// The string representation. + 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 + /// + /// Adds two vectors together. + /// + /// The first source vector. + /// The second source vector. + /// The summed vector. + public static unsafe Vector operator +(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(dataPtr); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + else + { + Vector sum = new Vector(); + 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; + } + } + } + + /// + /// Subtracts the second vector from the first. + /// + /// The first source vector. + /// The second source vector. + /// The difference vector. + public static unsafe Vector operator -(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(dataPtr); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + else + { + Vector difference = new Vector(); + 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. + /// + /// Multiplies two vectors together. + /// + /// The first source vector. + /// The second source vector. + /// The product vector. + public static unsafe Vector operator *(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(dataPtr); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + else + { + Vector product = new Vector(); + 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. + /// + /// Multiplies a vector by the given scalar. + /// + /// The source vector. + /// The scalar value. + /// The scaled vector. + public static Vector operator *(Vector value, T factor) + { + unchecked + { + if (Vector.IsHardwareAccelerated) + { + return new Vector(factor) * value; + } + else + { + Vector product = new Vector(); + 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. + /// + /// Multiplies a vector by the given scalar. + /// + /// The scalar value. + /// The source vector. + /// The scaled vector. + public static Vector operator *(T factor, Vector value) + { + unchecked + { + if (Vector.IsHardwareAccelerated) + { + return new Vector(factor) * value; + } + else + { + Vector product = new Vector(); + 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. + /// + /// Divides the first vector by the second. + /// + /// The first source vector. + /// The second source vector. + /// The vector resulting from the division. + public static unsafe Vector operator /(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(dataPtr); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + else + { + Vector quotient = new Vector(); + 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; + } + } + } + + /// + /// Negates a given vector. + /// + /// The source vector. + /// The negated vector. + public static Vector operator -(Vector value) + { + return Zero - value; + } + #endregion Arithmetic Operators + + #region Bitwise Operators + /// + /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The resultant vector. + [JitIntrinsic] + public static unsafe Vector operator &(Vector left, Vector right) + { + Vector result = new Vector(); + 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.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; + } + + /// + /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The resultant vector. + [JitIntrinsic] + public static unsafe Vector operator |(Vector left, Vector right) + { + Vector result = new Vector(); + 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.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; + } + + /// + /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The resultant vector. + [JitIntrinsic] + public static unsafe Vector operator ^(Vector left, Vector right) + { + Vector result = new Vector(); + 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.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; + } + + /// + /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements. + /// + /// The source vector. + /// The one's complement vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector operator ~(Vector value) + { + return allOnes ^ value; + } + #endregion Bitwise Operators + + #region Logical Operators + /// + /// Returns a boolean indicating whether each pair of elements in the given vectors are equal. + /// + /// The first vector to compare. + /// The first vector to compare. + /// True if all elements are equal; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(Vector left, Vector right) + { + return left.Equals(right); + } + + /// + /// Returns a boolean indicating whether any single pair of elements in the given vectors are equal. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if any element pairs are equal; False if no element pairs are equal. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(Vector left, Vector right) + { + return !(left == right); + } + #endregion Logical Operators + + #region Conversions + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [CLSCompliant(false)] + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [CLSCompliant(false)] + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [CLSCompliant(false)] + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [CLSCompliant(false)] + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + /// + /// Reinterprets the bits of the given vector into those of another type. + /// + /// The source vector + /// The reinterpreted vector. + [JitIntrinsic] + public static explicit operator Vector(Vector value) + { + return new Vector(ref value.register); + } + + #endregion Conversions + + #region Internal Comparison Methods + [JitIntrinsic] + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + internal static unsafe Vector Equals(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(ref register); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + } + + [JitIntrinsic] + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + internal static unsafe Vector LessThan(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(ref register); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + } + + [JitIntrinsic] + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + internal static unsafe Vector GreaterThan(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(ref register); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + } + + [JitIntrinsic] + internal static Vector GreaterThanOrEqual(Vector left, Vector right) + { + return Equals(left, right) | GreaterThan(left, right); + } + + [JitIntrinsic] + internal static Vector LessThanOrEqual(Vector left, Vector right) + { + return Equals(left, right) | LessThan(left, right); + } + + [JitIntrinsic] + internal static Vector ConditionalSelect(Vector condition, Vector left, Vector right) + { + return (left & condition) | (Vector.AndNot(right, condition)); + } + #endregion Comparison Methods + + #region Internal Math Methods + [JitIntrinsic] + internal static unsafe Vector Abs(Vector 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(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(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(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(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(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(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 Min(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(dataPtr); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + else + { + Vector vec = new Vector(); + 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 Max(Vector left, Vector 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(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(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(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(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(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(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(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(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(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(dataPtr); + } + else + { + throw new NotSupportedException(SR.Arg_TypeNotSupported); + } + } + else + { + Vector vec = new Vector(); + 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 left, Vector 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 SquareRoot(Vector 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(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(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(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(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(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(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(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(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(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(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 + } +} diff --git a/mcs/class/System.Numerics.Vectors/System.Numerics/Vector_Operations.cs b/mcs/class/System.Numerics.Vectors/System.Numerics/Vector_Operations.cs new file mode 100644 index 00000000000..83a5ad38cab --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/System.Numerics/Vector_Operations.cs @@ -0,0 +1,865 @@ +// 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 +{ + /// + /// Contains various methods useful for creating, manipulating, combining, and converting generic vectors with one another. + /// + 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 intrinsics + #region Select Methods + /// + /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. + /// + /// The integral mask vector used to drive selection. + /// The first source vector. + /// The second source vector. + /// The new vector with elements selected based on the mask. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) + { + return (Vector)Vector.ConditionalSelect((Vector)condition, left, right); + } + + /// + /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. + /// + /// The integral mask vector used to drive selection. + /// The first source vector. + /// The second source vector. + /// The new vector with elements selected based on the mask. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) + { + return (Vector)Vector.ConditionalSelect((Vector)condition, left, right); + } + + /// + /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. + /// + /// The mask vector used to drive selection. + /// The first source vector. + /// The second source vector. + /// The new vector with elements selected based on the mask. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) where T : struct + { + return Vector.ConditionalSelect(condition, left, right); + } + #endregion Select Methods + + #region Comparison methods + #region Equals methods + /// + /// Returns a new vector whose elements signal whether the elements in left and right were equal. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Equals(Vector left, Vector right) where T : struct + { + return Vector.Equals(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Equals(Vector left, Vector right) + { + return (Vector)Vector.Equals(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left and right were equal. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Equals(Vector left, Vector right) + { + return Vector.Equals(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Equals(Vector left, Vector right) + { + return (Vector)Vector.Equals(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left and right were equal. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Equals(Vector left, Vector right) + { + return Vector.Equals(left, right); + } + + /// + /// Returns a boolean indicating whether each pair of elements in the given vectors are equal. + /// + /// The first vector to compare. + /// The first vector to compare. + /// True if all elements are equal; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool EqualsAll(Vector left, Vector right) where T : struct + { + return left == right; + } + + /// + /// Returns a boolean indicating whether any single pair of elements in the given vectors are equal. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if any element pairs are equal; False if no element pairs are equal. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool EqualsAny(Vector left, Vector right) where T : struct + { + return !Vector.Equals(left, right).Equals(Vector.Zero); + } + #endregion Equals methods + + #region Lessthan Methods + /// + /// Returns a new vector whose elements signal whether the elements in left were less than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThan(Vector left, Vector right) where T : struct + { + return Vector.LessThan(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether the elements in left were less than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant integral vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThan(Vector left, Vector right) + { + return (Vector)Vector.LessThan(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left were less than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThan(Vector left, Vector right) + { + return Vector.LessThan(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether the elements in left were less than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant integral vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThan(Vector left, Vector right) + { + return (Vector)Vector.LessThan(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left were less than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThan(Vector left, Vector right) + { + return Vector.LessThan(left, right); + } + + /// + /// Returns a boolean indicating whether all of the elements in left are less than their corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if all elements in left are less than their corresponding elements in right; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool LessThanAll(Vector left, Vector right) where T : struct + { + Vector cond = (Vector)Vector.LessThan(left, right); + return cond.Equals(Vector.AllOnes); + } + + /// + /// Returns a boolean indicating whether any element in left is less than its corresponding element in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if any elements in left are less than their corresponding elements in right; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool LessThanAny(Vector left, Vector right) where T : struct + { + Vector cond = (Vector)Vector.LessThan(left, right); + return !cond.Equals(Vector.Zero); + } + #endregion LessthanMethods + + #region Lessthanorequal methods + /// + /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThanOrEqual(Vector left, Vector right) where T : struct + { + return Vector.LessThanOrEqual(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant integral vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThanOrEqual(Vector left, Vector right) + { + return (Vector)Vector.LessThanOrEqual(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThanOrEqual(Vector left, Vector right) + { + return Vector.LessThanOrEqual(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThanOrEqual(Vector left, Vector right) + { + return Vector.LessThanOrEqual(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant integral vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector LessThanOrEqual(Vector left, Vector right) + { + return (Vector)Vector.LessThanOrEqual(left, right); + } + + /// + /// Returns a boolean indicating whether all elements in left are less than or equal to their corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if all elements in left are less than or equal to their corresponding elements in right; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool LessThanOrEqualAll(Vector left, Vector right) where T : struct + { + Vector cond = (Vector)Vector.LessThanOrEqual(left, right); + return cond.Equals(Vector.AllOnes); + } + + /// + /// Returns a boolean indicating whether any element in left is less than or equal to its corresponding element in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if any elements in left are less than their corresponding elements in right; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool LessThanOrEqualAny(Vector left, Vector right) where T : struct + { + Vector cond = (Vector)Vector.LessThanOrEqual(left, right); + return !cond.Equals(Vector.Zero); + } + #endregion Lessthanorequal methods + + #region Greaterthan methods + /// + /// Returns a new vector whose elements signal whether the elements in left were greater than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThan(Vector left, Vector right) where T : struct + { + return Vector.GreaterThan(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether the elements in left were greater than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant integral vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThan(Vector left, Vector right) + { + return (Vector)Vector.GreaterThan(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left were greater than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThan(Vector left, Vector right) + { + return Vector.GreaterThan(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether the elements in left were greater than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant integral vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThan(Vector left, Vector right) + { + return (Vector)Vector.GreaterThan(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left were greater than their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThan(Vector left, Vector right) + { + return Vector.GreaterThan(left, right); + } + + /// + /// Returns a boolean indicating whether all elements in left are greater than the corresponding elements in right. + /// elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if all elements in left are greater than their corresponding elements in right; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanAll(Vector left, Vector right) where T : struct + { + Vector cond = (Vector)Vector.GreaterThan(left, right); + return cond.Equals(Vector.AllOnes); + } + + /// + /// Returns a boolean indicating whether any element in left is greater than its corresponding element in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if any elements in left are greater than their corresponding elements in right; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanAny(Vector left, Vector right) where T : struct + { + Vector cond = (Vector)Vector.GreaterThan(left, right); + return !cond.Equals(Vector.Zero); + } + #endregion Greaterthan methods + + #region Greaterthanorequal methods + /// + /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThanOrEqual(Vector left, Vector right) where T : struct + { + return Vector.GreaterThanOrEqual(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant integral vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThanOrEqual(Vector left, Vector right) + { + return (Vector)Vector.GreaterThanOrEqual(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThanOrEqual(Vector left, Vector right) + { + return Vector.GreaterThanOrEqual(left, right); + } + + /// + /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their + /// corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThanOrEqual(Vector left, Vector right) + { + return Vector.GreaterThanOrEqual(left, right); + } + + /// + /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to + /// their corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// The resultant integral vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector GreaterThanOrEqual(Vector left, Vector right) + { + return (Vector)Vector.GreaterThanOrEqual(left, right); + } + + /// + /// Returns a boolean indicating whether all of the elements in left are greater than or equal to + /// their corresponding elements in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if all elements in left are greater than or equal to their corresponding elements in right; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanOrEqualAll(Vector left, Vector right) where T : struct + { + Vector cond = (Vector)Vector.GreaterThanOrEqual(left, right); + return cond.Equals(Vector.AllOnes); + } + + /// + /// Returns a boolean indicating whether any element in left is greater than or equal to its corresponding element in right. + /// + /// The first vector to compare. + /// The second vector to compare. + /// True if any elements in left are greater than or equal to their corresponding elements in right; False otherwise. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static bool GreaterThanOrEqualAny(Vector left, Vector right) where T : struct + { + Vector cond = (Vector)Vector.GreaterThanOrEqual(left, right); + return !cond.Equals(Vector.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 type parameter are recognized as intrinsics + /// + /// Returns whether or not vector operations are subject to hardware acceleration through JIT intrinsic support. + /// + [JitIntrinsic] + public static bool IsHardwareAccelerated + { + get + { + return false; + } + } + + // Vector + // Basic Math + // All Math operations for Vector are aggressively inlined here + + /// + /// Returns a new vector whose elements are the absolute values of the given vector's elements. + /// + /// The source vector. + /// The absolute value vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Abs(Vector value) where T : struct + { + return Vector.Abs(value); + } + + /// + /// Returns a new vector whose elements are the minimum of each pair of elements in the two given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The minimum vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Min(Vector left, Vector right) where T : struct + { + return Vector.Min(left, right); + } + + /// + /// Returns a new vector whose elements are the maximum of each pair of elements in the two given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The maximum vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Max(Vector left, Vector right) where T : struct + { + return Vector.Max(left, right); + } + + // Specialized vector operations + + /// + /// Returns the dot product of two vectors. + /// + /// The first source vector. + /// The second source vector. + /// The dot product. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static T Dot(Vector left, Vector right) where T : struct + { + return Vector.DotProduct(left, right); + } + + /// + /// Returns a new vector whose elements are the square roots of the given vector's elements. + /// + /// The source vector. + /// The square root vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector SquareRoot(Vector value) where T : struct + { + return Vector.SquareRoot(value); + } + #endregion Vector Math Methods + + #region Named Arithmetic Operators + /// + /// Creates a new vector whose values are the sum of each pair of elements from the two given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The summed vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Add(Vector left, Vector right) where T : struct + { + return left + right; + } + + /// + /// Creates a new vector whose values are the difference between each pairs of elements in the given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The difference vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Subtract(Vector left, Vector right) where T : struct + { + return left - right; + } + + /// + /// Creates a new vector whose values are the product of each pair of elements from the two given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The summed vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Multiply(Vector left, Vector right) where T : struct + { + return left * right; + } + + /// + /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value. + /// + /// The source vector. + /// The scalar factor. + /// The scaled vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Multiply(Vector left, T right) where T : struct + { + return left * right; + } + + /// + /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value. + /// + /// The scalar factor. + /// The source vector. + /// The scaled vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Multiply(T left, Vector right) where T : struct + { + return left * right; + } + + /// + /// Returns a new vector whose values are the result of dividing the first vector's elements + /// by the corresponding elements in the second vector. + /// + /// The first source vector. + /// The second source vector. + /// The divided vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Divide(Vector left, Vector right) where T : struct + { + return left / right; + } + + /// + /// Returns a new vector whose elements are the given vector's elements negated. + /// + /// The source vector. + /// The negated vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Negate(Vector value) where T : struct + { + return -value; + } + #endregion Named Arithmetic Operators + + #region Named Bitwise Operators + /// + /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector BitwiseAnd(Vector left, Vector right) where T : struct + { + return left & right; + } + + /// + /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector BitwiseOr(Vector left, Vector right) where T : struct + { + return left | right; + } + + /// + /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements. + /// + /// The source vector. + /// The one's complement vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector OnesComplement(Vector value) where T : struct + { + return ~value; + } + + /// + /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector Xor(Vector left, Vector right) where T : struct + { + return left ^ right; + } + + /// + /// Returns a new vector by performing a bitwise-and-not operation on each of the elements in the given vectors. + /// + /// The first source vector. + /// The second source vector. + /// The resultant vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AndNot(Vector left, Vector right) where T : struct + { + return left & ~right; + } + #endregion Named Bitwise Operators + + #region Conversion Methods + /// + /// Reinterprets the bits of the given vector into those of a vector of unsigned bytes. + /// + /// The source vector + /// The reinterpreted vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorByte(Vector value) where T : struct + { + return (Vector)value; + } + + /// + /// Reinterprets the bits of the given vector into those of a vector of signed bytes. + /// + /// The source vector + /// The reinterpreted vector. + [CLSCompliant(false)] + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorSByte(Vector value) where T : struct + { + return (Vector)value; + } + + /// + /// Reinterprets the bits of the given vector into those of a vector of 16-bit integers. + /// + /// The source vector + /// The reinterpreted vector. + [CLSCompliant(false)] + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorUInt16(Vector value) where T : struct + { + return (Vector)value; + } + + /// + /// Reinterprets the bits of the given vector into those of a vector of signed 16-bit integers. + /// + /// The source vector + /// The reinterpreted vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorInt16(Vector value) where T : struct + { + return (Vector)value; + } + + /// + /// Reinterprets the bits of the given vector into those of a vector of unsigned 32-bit integers. + /// + /// The source vector + /// The reinterpreted vector. + [CLSCompliant(false)] + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorUInt32(Vector value) where T : struct + { + return (Vector)value; + } + + /// + /// Reinterprets the bits of the given vector into those of a vector of signed 32-bit integers. + /// + /// The source vector + /// The reinterpreted vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorInt32(Vector value) where T : struct + { + return (Vector)value; + } + + /// + /// Reinterprets the bits of the given vector into those of a vector of unsigned 64-bit integers. + /// + /// The source vector + /// The reinterpreted vector. + [CLSCompliant(false)] + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorUInt64(Vector value) where T : struct + { + return (Vector)value; + } + + + /// + /// Reinterprets the bits of the given vector into those of a vector of signed 64-bit integers. + /// + /// The source vector + /// The reinterpreted vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorInt64(Vector value) where T : struct + { + return (Vector)value; + } + + /// + /// Reinterprets the bits of the given vector into those of a vector of 32-bit floating point numbers. + /// + /// The source vector + /// The reinterpreted vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorSingle(Vector value) where T : struct + { + return (Vector)value; + } + + /// + /// Reinterprets the bits of the given vector into those of a vector of 64-bit floating point numbers. + /// + /// The source vector + /// The reinterpreted vector. + [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] + public static Vector AsVectorDouble(Vector value) where T : struct + { + return (Vector)value; + } + #endregion Conversion Methods + } +} diff --git a/mcs/class/System.Numerics.Vectors/net_4_x_System.Numerics.Vectors.dll.exclude.sources b/mcs/class/System.Numerics.Vectors/net_4_x_System.Numerics.Vectors.dll.exclude.sources new file mode 100644 index 00000000000..0b188400ca0 --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/net_4_x_System.Numerics.Vectors.dll.exclude.sources @@ -0,0 +1,7 @@ +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 diff --git a/mcs/class/System.Numerics.Vectors/net_4_x_System.Numerics.Vectors.dll.sources b/mcs/class/System.Numerics.Vectors/net_4_x_System.Numerics.Vectors.dll.sources new file mode 100644 index 00000000000..d4f1837d8ec --- /dev/null +++ b/mcs/class/System.Numerics.Vectors/net_4_x_System.Numerics.Vectors.dll.sources @@ -0,0 +1 @@ +#include System.Numerics.Vectors.dll.sources diff --git a/mcs/class/System.Reflection.Context/Assembly/AssemblyInfo.cs b/mcs/class/System.Reflection.Context/Assembly/AssemblyInfo.cs new file mode 100644 index 00000000000..67d49125ac9 --- /dev/null +++ b/mcs/class/System.Reflection.Context/Assembly/AssemblyInfo.cs @@ -0,0 +1,62 @@ +// +// 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 diff --git a/mcs/class/System.Reflection.Context/Makefile b/mcs/class/System.Reflection.Context/Makefile new file mode 100644 index 00000000000..73bee9e345e --- /dev/null +++ b/mcs/class/System.Reflection.Context/Makefile @@ -0,0 +1,11 @@ +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 diff --git a/mcs/class/System.Reflection.Context/System.Reflection.Context.dll.sources b/mcs/class/System.Reflection.Context/System.Reflection.Context.dll.sources new file mode 100644 index 00000000000..18206897d54 --- /dev/null +++ b/mcs/class/System.Reflection.Context/System.Reflection.Context.dll.sources @@ -0,0 +1,5 @@ +../../build/common/Consts.cs +../../build/common/Locale.cs +../../build/common/MonoTODOAttribute.cs +Assembly/AssemblyInfo.cs +System.Reflection.Context/CustomReflectionContext.cs diff --git a/mcs/class/System.Reflection.Context/System.Reflection.Context/CustomReflectionContext.cs b/mcs/class/System.Reflection.Context/System.Reflection.Context/CustomReflectionContext.cs new file mode 100644 index 00000000000..28a6e62f443 --- /dev/null +++ b/mcs/class/System.Reflection.Context/System.Reflection.Context/CustomReflectionContext.cs @@ -0,0 +1,93 @@ +// +// 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 AddProperties (Type type) + { + throw new NotImplementedException (); + } + + [MonoTODO] + protected PropertyInfo CreateProperty (Type propertyType, string name, Func getter, Action setter) + { + throw new NotImplementedException (); + } + + [MonoTODO] + protected PropertyInfo CreateProperty (Type propertyType, string name, Func getter, Action setter, IEnumerable propertyCustomAttributes, IEnumerable getterCustomAttributes, IEnumerable setterCustomAttributes) + { + throw new NotImplementedException (); + } + + [MonoTODO] + protected virtual IEnumerable GetCustomAttributes (MemberInfo member, IEnumerable declaredAttributes) + { + throw new NotImplementedException (); + } + + [MonoTODO] + protected virtual IEnumerable GetCustomAttributes (ParameterInfo parameter, IEnumerable declaredAttributes) + { + throw new NotImplementedException (); + } + + [MonoTODO] + public override Assembly MapAssembly (Assembly assembly) + { + throw new NotImplementedException (); + } + + [MonoTODO] + public override TypeInfo MapType (TypeInfo type) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.Reflection.DispatchProxy/Assembly/AssemblyInfo.cs b/mcs/class/System.Reflection.DispatchProxy/Assembly/AssemblyInfo.cs new file mode 100644 index 00000000000..993d77ceb19 --- /dev/null +++ b/mcs/class/System.Reflection.DispatchProxy/Assembly/AssemblyInfo.cs @@ -0,0 +1,62 @@ +// +// 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 diff --git a/mcs/class/System.Reflection.DispatchProxy/Makefile b/mcs/class/System.Reflection.DispatchProxy/Makefile new file mode 100644 index 00000000000..ddc839647f4 --- /dev/null +++ b/mcs/class/System.Reflection.DispatchProxy/Makefile @@ -0,0 +1,11 @@ +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 diff --git a/mcs/class/System.Reflection.DispatchProxy/System.Reflection.DispatchProxy.dll.sources b/mcs/class/System.Reflection.DispatchProxy/System.Reflection.DispatchProxy.dll.sources new file mode 100644 index 00000000000..da5d484aa97 --- /dev/null +++ b/mcs/class/System.Reflection.DispatchProxy/System.Reflection.DispatchProxy.dll.sources @@ -0,0 +1,5 @@ +../../build/common/Consts.cs +../../build/common/Locale.cs +../../build/common/MonoTODOAttribute.cs +Assembly/AssemblyInfo.cs +System.Reflection/DispatchProxy.cs diff --git a/mcs/class/System.Reflection.DispatchProxy/System.Reflection/DispatchProxy.cs b/mcs/class/System.Reflection.DispatchProxy/System.Reflection/DispatchProxy.cs new file mode 100644 index 00000000000..540e525b425 --- /dev/null +++ b/mcs/class/System.Reflection.DispatchProxy/System.Reflection/DispatchProxy.cs @@ -0,0 +1,50 @@ +// +// 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 () where TProxy : DispatchProxy + { + throw new NotImplementedException (); + } + + [MonoTODO] + protected abstract object Invoke (MethodInfo targetMethod, object[] args); + } +} diff --git a/mcs/class/System.Security/System.Security.Cryptography/ProtectedData.cs b/mcs/class/System.Security/System.Security.Cryptography/ProtectedData.cs index 2e4032b44dd..d2cd4b21f49 100644 --- a/mcs/class/System.Security/System.Security.Cryptography/ProtectedData.cs +++ b/mcs/class/System.Security/System.Security.Cryptography/ProtectedData.cs @@ -1,60 +1,61 @@ -// -// ProtectedData.cs: Protect (encrypt) data without (user involved) key management -// +// +// ProtectedData.cs: Protect (encrypt) data without (user involved) key management +// // Author: // Sebastien Pouliot -// +// // (C) 2003 Motus Technologies Inc. (http://www.motus.com) // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "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. -// - +// +// 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.Runtime.InteropServices; -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; + +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 () + { + } + // FIXME [DataProtectionPermission (SecurityAction.Demand, ProtectData = true)] - 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) + { + if (userData == null) + throw new ArgumentNullException ("userData"); + // on Windows this is supported only under 2000 and later OS Check (scope); switch (impl) { +#if !MOBILE case DataProtectionImplementation.ManagedProtection: try { return ManagedProtection.Protect (userData, optionalEntropy, scope); @@ -71,21 +72,23 @@ namespace System.Security.Cryptography { string msg = Locale.GetText ("Data protection failed."); throw new CryptographicException (msg, e); } +#endif default: throw new PlatformNotSupportedException (); } } // FIXME [DataProtectionPermission (SecurityAction.Demand, UnprotectData = true)] - 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) + { + if (encryptedData == null) + throw new ArgumentNullException ("encryptedData"); + // on Windows this is supported only under 2000 and later OS Check (scope); switch (impl) { +#if !MOBILE case DataProtectionImplementation.ManagedProtection: try { return ManagedProtection.Unprotect (encryptedData, optionalEntropy, scope); @@ -102,11 +105,12 @@ namespace System.Security.Cryptography { string msg = Locale.GetText ("Data unprotection failed."); throw new CryptographicException (msg, e); } +#endif default: throw new PlatformNotSupportedException (); } - } - + } + // private stuff enum DataProtectionImplementation { @@ -156,6 +160,6 @@ namespace System.Security.Cryptography { throw new PlatformNotSupportedException (); } } - } -} - + } +} + diff --git a/mcs/class/System.Security/common_System.Security.dll.sources b/mcs/class/System.Security/common_System.Security.dll.sources new file mode 100644 index 00000000000..5a34119a3ad --- /dev/null +++ b/mcs/class/System.Security/common_System.Security.dll.sources @@ -0,0 +1,34 @@ +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 + diff --git a/mcs/class/System.Security/mobile_static_System.Security.dll.sources b/mcs/class/System.Security/mobile_static_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/mobile_static_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.Security/monodroid_System.Security.dll.sources b/mcs/class/System.Security/monodroid_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/monodroid_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.Security/monotouch_System.Security.dll.sources b/mcs/class/System.Security/monotouch_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/monotouch_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.Security/monotouch_runtime_System.Security.dll.sources b/mcs/class/System.Security/monotouch_runtime_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/monotouch_runtime_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.Security/monotouch_tv_System.Security.dll.sources b/mcs/class/System.Security/monotouch_tv_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/monotouch_tv_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.Security/monotouch_tv_runtime_System.Security.dll.sources b/mcs/class/System.Security/monotouch_tv_runtime_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/monotouch_tv_runtime_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.Security/monotouch_watch_System.Security.dll.sources b/mcs/class/System.Security/monotouch_watch_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/monotouch_watch_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.Security/monotouch_watch_runtime_System.Security.dll.sources b/mcs/class/System.Security/monotouch_watch_runtime_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/monotouch_watch_runtime_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.Security/xammac_System.Security.dll.sources b/mcs/class/System.Security/xammac_System.Security.dll.sources new file mode 100644 index 00000000000..599b7fa67f7 --- /dev/null +++ b/mcs/class/System.Security/xammac_System.Security.dll.sources @@ -0,0 +1 @@ +#include common_System.Security.dll.sources diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs index 4a22c093813..4fc4f14eee4 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs @@ -33,7 +33,9 @@ using System.Net; 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 { @@ -119,6 +121,7 @@ namespace System.ServiceModel.Channels return false; } +#if !MOBILE && !XAMMAC_4_5 public override bool CanBuildChannelListener ( BindingContext context) { @@ -132,6 +135,7 @@ namespace System.ServiceModel.Channels } return false; } +#endif public override T GetProperty (BindingContext context) { @@ -141,6 +145,7 @@ namespace System.ServiceModel.Channels return base.GetProperty (context); } +#if !MOBILE && !XAMMAC_4_5 void IWsdlExportExtension.ExportContract (WsdlExporter exporter, WsdlContractConversionContext context) { @@ -192,5 +197,6 @@ namespace System.ServiceModel.Channels transfer_mode == TransferMode.StreamedResponse) assertions.Add (doc.CreateElement ("msf", "Streamed", "http://schemas.microsoft.com/ws/2006/05/framing/policy")); } +#endif } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SslStreamSecurityBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SslStreamSecurityBindingElement.cs index 3201ef86eb6..12be181d6d7 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SslStreamSecurityBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SslStreamSecurityBindingElement.cs @@ -43,16 +43,21 @@ namespace System.ServiceModel.Channels { 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; } @@ -63,10 +68,13 @@ namespace System.ServiceModel.Channels 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) { @@ -87,6 +95,7 @@ namespace System.ServiceModel.Channels "msf", "SslTransportSecurity", PolicyImportHelper.FramingPolicyNS); return element; } +#endif [MonoTODO] public override IChannelFactory @@ -96,6 +105,7 @@ namespace System.ServiceModel.Channels throw new NotImplementedException (); } +#if !MOBILE && !XAMMAC_4_5 [MonoTODO] public override IChannelListener BuildChannelListener ( @@ -103,6 +113,7 @@ namespace System.ServiceModel.Channels { throw new NotImplementedException (); } +#endif [MonoTODO] public override bool CanBuildChannelFactory ( @@ -111,12 +122,14 @@ namespace System.ServiceModel.Channels throw new NotImplementedException (); } +#if !MOBILE && !XAMMAC_4_5 [MonoTODO] public override bool CanBuildChannelListener ( BindingContext context) { throw new NotImplementedException (); } +#endif public override BindingElement Clone () { @@ -129,6 +142,7 @@ namespace System.ServiceModel.Channels throw new NotImplementedException (); } +#if !MOBILE && !XAMMAC_4_5 #region explicit interface implementations [MonoTODO] void IPolicyExportExtension.ExportPolicy ( @@ -140,5 +154,6 @@ namespace System.ServiceModel.Channels context.GetBindingAssertions ().Add (transportBinding); } #endregion +#endif } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs index 64c3b38a249..ae823e534eb 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs @@ -31,7 +31,9 @@ using System; 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 @@ -88,9 +90,15 @@ namespace System.ServiceModel.Channels { if (!CanBuildChannelFactory (context)) throw new InvalidOperationException (String.Format ("Not supported channel factory type '{0}'", typeof (TChannel))); + +#if !MOBILE && !XAMMAC_4_5 return new TcpChannelFactory (this, context); +#else + throw new NotImplementedException (); +#endif } +#if !MOBILE && !XAMMAC_4_5 public override IChannelListener BuildChannelListener ( BindingContext context) @@ -99,6 +107,7 @@ namespace System.ServiceModel.Channels throw new InvalidOperationException (String.Format ("Not supported channel listener type '{0}'", typeof (TChannel))); return new TcpChannelListener (this, context); } +#endif public override BindingElement Clone () { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElement.cs index 4f1a5fde8f2..bab577c5bae 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElement.cs @@ -56,7 +56,7 @@ namespace System.ServiceModel.Channels max_recv_message_size = other.max_recv_message_size; } - public bool ManualAddressing { + public virtual bool ManualAddressing { get { return manual_addressing; } set { manual_addressing = value; } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/WindowsStreamSecurityBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/WindowsStreamSecurityBindingElement.cs index e57cfde91e3..2d8e461f735 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/WindowsStreamSecurityBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/WindowsStreamSecurityBindingElement.cs @@ -61,12 +61,14 @@ namespace System.ServiceModel.Channels return context.BuildInnerChannelFactory (); } +#if !MOBILE && !XAMMAC_4_5 public override IChannelListener BuildChannelListener ( BindingContext context) { return context.BuildInnerChannelListener (); } +#endif public override bool CanBuildChannelFactory ( BindingContext context) @@ -74,11 +76,13 @@ namespace System.ServiceModel.Channels return context.CanBuildInnerChannelFactory (); } +#if !MOBILE && !XAMMAC_4_5 public override bool CanBuildChannelListener ( BindingContext context) { return context.CanBuildInnerChannelListener (); } +#endif public override BindingElement Clone () { @@ -89,8 +93,10 @@ namespace System.ServiceModel.Channels { 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; } @@ -120,6 +126,7 @@ namespace System.ServiceModel.Channels get { throw new NotImplementedException (); } } +#if !MOBILE && !XAMMAC_4_5 [MonoTODO] void IPolicyExportExtension.ExportPolicy ( MetadataExporter exporter, @@ -141,6 +148,7 @@ namespace System.ServiceModel.Channels element.AppendChild (protectionLevel); return element; } +#endif #endregion } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecureConversationSecurityTokenParameters.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecureConversationSecurityTokenParameters.cs index 41c6658f9cf..3d8e71035a0 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecureConversationSecurityTokenParameters.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecureConversationSecurityTokenParameters.cs @@ -25,22 +25,29 @@ // 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; @@ -49,6 +56,7 @@ namespace System.ServiceModel.Security.Tokens r.OutgoingEncryptionParts.ChannelParts.IsBodyIncluded = true; r.MakeReadOnly (); default_channel_protection_requirements = r; +#endif dummy_context = new BindingContext ( new CustomBinding (), @@ -56,7 +64,9 @@ namespace System.ServiceModel.Security.Tokens } SecurityBindingElement element; +#if !MOBILE && !XAMMAC_4_5 ChannelProtectionRequirements requirements; +#endif bool cancellable; public SecureConversationSecurityTokenParameters () @@ -77,6 +87,7 @@ namespace System.ServiceModel.Security.Tokens { } +#if !MOBILE && !XAMMAC_4_5 public SecureConversationSecurityTokenParameters ( SecurityBindingElement element, bool requireCancellation, @@ -89,13 +100,25 @@ namespace System.ServiceModel.Security.Tokens 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 { @@ -108,9 +131,11 @@ namespace System.ServiceModel.Security.Tokens set { element = value; } } +#if !MOBILE && !XAMMAC_4_5 public ChannelProtectionRequirements BootstrapProtectionRequirements { get { return requirements; } } +#endif // SecurityTokenParameters @@ -135,13 +160,13 @@ namespace System.ServiceModel.Security.Tokens 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) { @@ -154,6 +179,7 @@ namespace System.ServiceModel.Security.Tokens requirement.Properties [ReqType.IssuedSecurityTokenParametersProperty] = this.Clone (); requirement.KeyType = SecurityKeyType.SymmetricKey; } +#endif public override string ToString () { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecurityTokenParameters.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecurityTokenParameters.cs index f4c3f3ceff5..c5ff1439e0c 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecurityTokenParameters.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/SecurityTokenParameters.cs @@ -25,8 +25,11 @@ // 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; @@ -114,6 +117,7 @@ namespace System.ServiceModel.Security.Tokens protected abstract SecurityTokenParameters CloneCore (); +#if !MOBILE && !XAMMAC_4_5 protected abstract SecurityKeyIdentifierClause CreateKeyIdentifierClause ( SecurityToken token, SecurityTokenReferenceStyle referenceStyle); @@ -125,11 +129,13 @@ namespace System.ServiceModel.Security.Tokens } 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) @@ -145,5 +151,6 @@ namespace System.ServiceModel.Security.Tokens { throw new NotImplementedException (); } +#endif } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/UserNameSecurityTokenParameters.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/UserNameSecurityTokenParameters.cs index 8a40a61c0cd..46f14360654 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/UserNameSecurityTokenParameters.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Security.Tokens/UserNameSecurityTokenParameters.cs @@ -25,8 +25,10 @@ // 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 @@ -64,6 +66,7 @@ namespace System.ServiceModel.Security.Tokens return new UserNameSecurityTokenParameters (this); } +#if !MOBILE && !XAMMAC_4_5 protected override SecurityKeyIdentifierClause CreateKeyIdentifierClause ( SecurityToken token, SecurityTokenReferenceStyle referenceStyle) { @@ -81,5 +84,6 @@ namespace System.ServiceModel.Security.Tokens requirement.TokenType = SecurityTokenTypes.UserName; requirement.RequireCryptographicToken = true; } +#endif } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources index 20a6a2cbf7a..8e54cb5c622 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources @@ -1004,6 +1004,7 @@ System.ServiceModel/BasicHttpBinding_4_5.cs 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 diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsBinding.cs b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsBinding.cs index e6a96dac52a..21e66a4f65b 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsBinding.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsBinding.cs @@ -79,6 +79,7 @@ namespace System.ServiceModel public BasicHttpsSecurity Security { get { return security; } + set { security = value; } } public override BindingElementCollection diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsSecurity.cs b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsSecurity.cs index c5c870c0f33..de946ceb443 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsSecurity.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsSecurity.cs @@ -64,6 +64,7 @@ namespace System.ServiceModel public HttpTransportSecurity Transport { get { return transport; } + set { transport = value; } } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/CallbackBehaviorAttribute.cs b/mcs/class/System.ServiceModel/System.ServiceModel/CallbackBehaviorAttribute.cs index f392be8d37a..5a5ca874df8 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/CallbackBehaviorAttribute.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/CallbackBehaviorAttribute.cs @@ -29,7 +29,9 @@ using System; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; +#if !MOBILE && !XAMMAC_4_5 using System.Transactions; +#endif namespace System.ServiceModel { @@ -45,7 +47,9 @@ namespace System.ServiceModel MaxItemsInObjectGraph = 0x10000; UseSynchronizationContext = true; ValidateMustUnderstand = true; +#if !MOBILE && !XAMMAC_4_5 TransactionIsolationLevel = IsolationLevel.Unspecified; +#endif } [MonoTODO] @@ -63,8 +67,10 @@ namespace System.ServiceModel [MonoTODO] public int MaxItemsInObjectGraph { get; set; } +#if !MOBILE && !XAMMAC_4_5 [MonoTODO] public IsolationLevel TransactionIsolationLevel { get; set; } +#endif [MonoTODO] public string TransactionTimeout { get; set; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/DnsEndpointIdentity.cs b/mcs/class/System.ServiceModel/System.ServiceModel/DnsEndpointIdentity.cs index b5ac514b0da..9c9b76aec61 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/DnsEndpointIdentity.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/DnsEndpointIdentity.cs @@ -27,7 +27,9 @@ // 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; @@ -37,6 +39,7 @@ namespace System.ServiceModel { public class DnsEndpointIdentity : EndpointIdentity { +#if !MOBILE && !XAMMAC_4_5 public DnsEndpointIdentity (Claim identity) { Initialize (identity); @@ -46,5 +49,11 @@ namespace System.ServiceModel : this (Claim.CreateDnsClaim (dns)) { } +#else + public DnsEndpointIdentity (string dns) + { + throw new NotImplementedException (); + } +#endif } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/DuplexChannelFactory.cs b/mcs/class/System.ServiceModel/System.ServiceModel/DuplexChannelFactory.cs index e72ab9b8d2b..01336d803a5 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/DuplexChannelFactory.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/DuplexChannelFactory.cs @@ -217,8 +217,11 @@ namespace System.ServiceModel // 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; diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/DuplexClientRuntimeChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel/DuplexClientRuntimeChannel.cs index 4fa56e12a78..db6647c76f5 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/DuplexClientRuntimeChannel.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/DuplexClientRuntimeChannel.cs @@ -192,10 +192,6 @@ namespace System.ServiceModel.MonoInternal } 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); } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/HttpBindingBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel/HttpBindingBase.cs index 4ed2088711e..8852d3d1278 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/HttpBindingBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/HttpBindingBase.cs @@ -110,7 +110,7 @@ namespace System.ServiceModel set { reader_quotas = value; } } - public override abstract string Scheme { + public override string Scheme { get; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/MessageSecurityOverTcp.cs b/mcs/class/System.ServiceModel/System.ServiceModel/MessageSecurityOverTcp.cs index c7852cd1ffd..6e9a794ee41 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/MessageSecurityOverTcp.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/MessageSecurityOverTcp.cs @@ -31,22 +31,28 @@ namespace System.ServiceModel { 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; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/MessageSecurityVersion.cs b/mcs/class/System.ServiceModel/System.ServiceModel/MessageSecurityVersion.cs index 2f53bc57b67..d6a5e19d286 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/MessageSecurityVersion.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/MessageSecurityVersion.cs @@ -27,8 +27,10 @@ // 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; @@ -38,6 +40,7 @@ namespace System.ServiceModel { public abstract class MessageSecurityVersion { +#if !MOBILE && !XAMMAC_4_5 // Types class MessageSecurityTokenVersion : SecurityTokenVersion { @@ -112,6 +115,7 @@ namespace System.ServiceModel SecureConversationVersion = SecureConversationVersion.WSSecureConversationFeb2005; TrustVersion = TrustVersion.WSTrustFeb2005; } + this.SecurityVersion = wss11 ? SecurityVersion.WSSecurity11 : SecurityVersion.WSSecurity10; } public override BasicSecurityProfileVersion BasicSecurityProfileVersion { @@ -122,14 +126,11 @@ namespace System.ServiceModel 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 @@ -137,12 +138,16 @@ namespace System.ServiceModel 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 { @@ -183,9 +188,11 @@ namespace System.ServiceModel 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; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/NetHttpsBinding.cs b/mcs/class/System.ServiceModel/System.ServiceModel/NetHttpsBinding.cs new file mode 100644 index 00000000000..703de2241ed --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel/NetHttpsBinding.cs @@ -0,0 +1,83 @@ +// 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 diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs b/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs index 794445155d8..51a8c3cfb2e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs @@ -46,7 +46,9 @@ namespace System.ServiceModel XmlDictionaryReaderQuotas reader_quotas = new XmlDictionaryReaderQuotas (); bool transaction_flow; +#if !MOBILE && !XAMMAC_4_5 TransactionProtocol transaction_protocol; +#endif TcpTransportBindingElement transport; public NetTcpBinding () @@ -69,9 +71,13 @@ namespace System.ServiceModel 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, @@ -147,10 +153,12 @@ namespace System.ServiceModel set { transaction_flow = value; } } +#if !MOBILE && !XAMMAC_4_5 public TransactionProtocol TransactionProtocol { get { return transaction_protocol; } set { transaction_protocol = value; } } +#endif // overrides @@ -160,18 +168,22 @@ namespace System.ServiceModel 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 list = new List (); +#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); @@ -184,6 +196,7 @@ namespace System.ServiceModel 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 () { @@ -239,6 +252,7 @@ namespace System.ServiceModel // FIXME: requireCancellation element, true, reqs); } +#endif BindingElement CreateTransportSecurity () { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/SpnEndpointIdentity.cs b/mcs/class/System.ServiceModel/System.ServiceModel/SpnEndpointIdentity.cs index d93be038818..396579fd255 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/SpnEndpointIdentity.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/SpnEndpointIdentity.cs @@ -27,7 +27,9 @@ // 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; @@ -37,6 +39,7 @@ namespace System.ServiceModel { public class SpnEndpointIdentity : EndpointIdentity { +#if !MOBILE && !XAMMAC_4_5 public SpnEndpointIdentity (Claim identity) { Initialize (identity); @@ -46,6 +49,12 @@ namespace System.ServiceModel : this (Claim.CreateSpnClaim (spn)) { } +#else + public SpnEndpointIdentity (string spn) + { + throw new NotImplementedException (); + } +#endif [MonoTODO] public static TimeSpan SpnLookupTime { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/UpnEndpointIdentity.cs b/mcs/class/System.ServiceModel/System.ServiceModel/UpnEndpointIdentity.cs index a866e93e4cb..e53d72009a6 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/UpnEndpointIdentity.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/UpnEndpointIdentity.cs @@ -27,7 +27,9 @@ // 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; @@ -37,6 +39,7 @@ namespace System.ServiceModel { public class UpnEndpointIdentity : EndpointIdentity { +#if !MOBILE && !XAMMAC_4_5 public UpnEndpointIdentity (Claim identity) { Initialize (identity); @@ -46,5 +49,11 @@ namespace System.ServiceModel : this (Claim.CreateUpnClaim (upn)) { } +#else + public UpnEndpointIdentity (string upn) + { + throw new NotImplementedException (); + } +#endif } } diff --git a/mcs/class/System.ServiceModel/mobile_System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/mobile_System.ServiceModel.dll.sources index 1b83c9e468e..6666c86e484 100644 --- a/mcs/class/System.ServiceModel/mobile_System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/mobile_System.ServiceModel.dll.sources @@ -187,6 +187,7 @@ System.ServiceModel/BasicHttpSecurity.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 @@ -200,6 +201,8 @@ System.ServiceModel/Constants.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 @@ -218,6 +221,7 @@ System.ServiceModel/IClientChannel.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 @@ -233,6 +237,7 @@ System.ServiceModel/MessageHeader_1.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 @@ -255,3 +260,30 @@ Dummy_2_1.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 diff --git a/mcs/class/System.Xml.XPath.XmlDocument/Assembly/AssemblyInfo.cs b/mcs/class/System.Xml.XPath.XmlDocument/Assembly/AssemblyInfo.cs new file mode 100644 index 00000000000..a34208a27eb --- /dev/null +++ b/mcs/class/System.Xml.XPath.XmlDocument/Assembly/AssemblyInfo.cs @@ -0,0 +1,62 @@ +// +// 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 diff --git a/mcs/class/System.Xml.XPath.XmlDocument/Makefile b/mcs/class/System.Xml.XPath.XmlDocument/Makefile new file mode 100644 index 00000000000..504b374a939 --- /dev/null +++ b/mcs/class/System.Xml.XPath.XmlDocument/Makefile @@ -0,0 +1,11 @@ +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 diff --git a/mcs/class/System.Xml.XPath.XmlDocument/System.Xml.XPath.XmlDocument.dll.sources b/mcs/class/System.Xml.XPath.XmlDocument/System.Xml.XPath.XmlDocument.dll.sources new file mode 100644 index 00000000000..c5813ec7c3d --- /dev/null +++ b/mcs/class/System.Xml.XPath.XmlDocument/System.Xml.XPath.XmlDocument.dll.sources @@ -0,0 +1,5 @@ +../../build/common/Consts.cs +../../build/common/Locale.cs +../../build/common/MonoTODOAttribute.cs +Assembly/AssemblyInfo.cs +System.Xml/XmlDocumentXPathExtensions.cs diff --git a/mcs/class/System.Xml.XPath.XmlDocument/System.Xml/XmlDocumentXPathExtensions.cs b/mcs/class/System.Xml.XPath.XmlDocument/System.Xml/XmlDocumentXPathExtensions.cs new file mode 100644 index 00000000000..ee4968baf6a --- /dev/null +++ b/mcs/class/System.Xml.XPath.XmlDocument/System.Xml/XmlDocumentXPathExtensions.cs @@ -0,0 +1,83 @@ +// +// 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 (); + } + } +} diff --git a/mcs/class/System/System.IO/FileSystemWatcher_mobile.cs b/mcs/class/System/System.IO/FileSystemWatcher_mobile.cs new file mode 100644 index 00000000000..aa13ac52094 --- /dev/null +++ b/mcs/class/System/System.IO/FileSystemWatcher_mobile.cs @@ -0,0 +1,55 @@ +// +// FileSystemWatcher.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/System/System.Net.WebSockets/WebSocketCloseStatus.cs b/mcs/class/System/System.Net.WebSockets/WebSocketCloseStatus.cs index c89f2de39a2..d6621207cec 100644 --- a/mcs/class/System/System.Net.WebSockets/WebSocketCloseStatus.cs +++ b/mcs/class/System/System.Net.WebSockets/WebSocketCloseStatus.cs @@ -38,12 +38,12 @@ namespace System.Net.WebSockets EndpointUnavailable = 1001, ProtocolError = 1002, InvalidMessageType = 1003, - Empty, + Empty = 1005, InvalidPayloadData = 1007, PolicyViolation = 1008, - MessageTooBig = 1004, + MessageTooBig = 1009, MandatoryExtension = 1010, - InternalServerError + InternalServerError = 1011 } } diff --git a/mcs/class/System/System.Security.Authentication.ExtendedProtection/ChannelBindingKind.cs b/mcs/class/System/System.Security.Authentication.ExtendedProtection/ChannelBindingKind.cs index ec341ea85e2..8aecd6542a6 100644 --- a/mcs/class/System/System.Security.Authentication.ExtendedProtection/ChannelBindingKind.cs +++ b/mcs/class/System/System.Security.Authentication.ExtendedProtection/ChannelBindingKind.cs @@ -32,8 +32,8 @@ namespace System.Security.Authentication.ExtendedProtection { public enum ChannelBindingKind { - Unknown, - Unique, - Endpoint + Unknown = 0, + Unique = 25, + Endpoint = 26 } } diff --git a/mcs/class/System/mobile_System.dll.sources b/mcs/class/System/mobile_System.dll.sources index 9dbb7e79b4f..4bba90982fe 100644 --- a/mcs/class/System/mobile_System.dll.sources +++ b/mcs/class/System/mobile_System.dll.sources @@ -28,6 +28,16 @@ System.IO.Compression/DeflateStream.cs 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 diff --git a/mcs/class/corlib/Microsoft.Win32/Registry.cs b/mcs/class/corlib/Microsoft.Win32/Registry.cs index 778ccf34afc..343e818ace8 100644 --- a/mcs/class/corlib/Microsoft.Win32/Registry.cs +++ b/mcs/class/corlib/Microsoft.Win32/Registry.cs @@ -29,8 +29,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if !NET_2_1 - using System; using System.Runtime.InteropServices; @@ -137,5 +135,3 @@ namespace Microsoft.Win32 } } -#endif // NET_2_1 - diff --git a/mcs/class/corlib/Microsoft.Win32/RegistryHive.cs b/mcs/class/corlib/Microsoft.Win32/RegistryHive.cs index aa5e9d99276..922e78009ef 100644 --- a/mcs/class/corlib/Microsoft.Win32/RegistryHive.cs +++ b/mcs/class/corlib/Microsoft.Win32/RegistryHive.cs @@ -27,8 +27,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if !NET_2_1 - using System; using System.Runtime.InteropServices; @@ -51,5 +49,3 @@ namespace Microsoft.Win32 } -#endif // NET_2_1 - diff --git a/mcs/class/corlib/Microsoft.Win32/RegistryKey.cs b/mcs/class/corlib/Microsoft.Win32/RegistryKey.cs index 623efdf77bb..a0f30146c82 100644 --- a/mcs/class/corlib/Microsoft.Win32/RegistryKey.cs +++ b/mcs/class/corlib/Microsoft.Win32/RegistryKey.cs @@ -29,8 +29,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if !NET_2_1 - using System; using System.IO; using System.Collections; @@ -44,6 +42,50 @@ using Microsoft.Win32.SafeHandles; 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 /// /// Wrapper class for Windows Registry Entry. /// @@ -693,7 +735,6 @@ namespace Microsoft.Win32 } } +#endif } -#endif // NET_2_1 - diff --git a/mcs/class/corlib/Microsoft.Win32/RegistryValueKind.cs b/mcs/class/corlib/Microsoft.Win32/RegistryValueKind.cs index 38f5c23026e..8db4a861b56 100644 --- a/mcs/class/corlib/Microsoft.Win32/RegistryValueKind.cs +++ b/mcs/class/corlib/Microsoft.Win32/RegistryValueKind.cs @@ -25,8 +25,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if !NET_2_1 - using System.Runtime.InteropServices; namespace Microsoft.Win32 @@ -44,5 +42,3 @@ namespace Microsoft.Win32 } } -#endif // NET_2_1 - diff --git a/mcs/class/corlib/Microsoft.Win32/RegistryValueOptions.cs b/mcs/class/corlib/Microsoft.Win32/RegistryValueOptions.cs index 98d4f3ec325..54f16378f30 100644 --- a/mcs/class/corlib/Microsoft.Win32/RegistryValueOptions.cs +++ b/mcs/class/corlib/Microsoft.Win32/RegistryValueOptions.cs @@ -26,8 +26,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if !NET_2_1 - using System; namespace Microsoft.Win32 @@ -39,5 +37,3 @@ namespace Microsoft.Win32 } } -#endif // NET_2_1 - diff --git a/mcs/class/corlib/Mono/RuntimeHandles.cs b/mcs/class/corlib/Mono/RuntimeHandles.cs index f6d0827bab3..b83ff68550b 100644 --- a/mcs/class/corlib/Mono/RuntimeHandles.cs +++ b/mcs/class/corlib/Mono/RuntimeHandles.cs @@ -10,6 +10,7 @@ // using System; +using System.Reflection; using System.Runtime.CompilerServices; namespace Mono { @@ -92,4 +93,52 @@ 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; + } + } } diff --git a/mcs/class/corlib/Mono/RuntimeStructs.cs b/mcs/class/corlib/Mono/RuntimeStructs.cs index c4453463262..29b75c077d3 100644 --- a/mcs/class/corlib/Mono/RuntimeStructs.cs +++ b/mcs/class/corlib/Mono/RuntimeStructs.cs @@ -28,6 +28,15 @@ namespace Mono { 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 */ + } } } diff --git a/mcs/class/corlib/ReferenceSources/RuntimeType.cs b/mcs/class/corlib/ReferenceSources/RuntimeType.cs index f577efcd5ca..4981f4175a1 100644 --- a/mcs/class/corlib/ReferenceSources/RuntimeType.cs +++ b/mcs/class/corlib/ReferenceSources/RuntimeType.cs @@ -452,7 +452,8 @@ namespace System 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.Value; @@ -618,11 +619,9 @@ namespace System [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 (); diff --git a/mcs/class/corlib/System.Diagnostics.Tracing/EventSource.cs b/mcs/class/corlib/System.Diagnostics.Tracing/EventSource.cs index 405d346a527..0872f01977a 100644 --- a/mcs/class/corlib/System.Diagnostics.Tracing/EventSource.cs +++ b/mcs/class/corlib/System.Diagnostics.Tracing/EventSource.cs @@ -33,6 +33,12 @@ namespace System.Diagnostics.Tracing { 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; diff --git a/mcs/class/corlib/System.Diagnostics/StackTrace.cs b/mcs/class/corlib/System.Diagnostics/StackTrace.cs index 420b497fc9a..ba77979609f 100644 --- a/mcs/class/corlib/System.Diagnostics/StackTrace.cs +++ b/mcs/class/corlib/System.Diagnostics/StackTrace.cs @@ -37,6 +37,7 @@ using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; +using System.IO; namespace System.Diagnostics { @@ -60,6 +61,8 @@ namespace System.Diagnostics { readonly StackTrace[] captured_traces; private bool debug_info; + private static Dictionary> metadataHandlers; + [MethodImplAttribute (MethodImplOptions.NoInlining)] public StackTrace () { @@ -288,6 +291,8 @@ namespace System.Diagnostics { 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); @@ -295,13 +300,78 @@ namespace System.Diagnostics { } 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> (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> (); + 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 lines = null; + if (!mvidLines.TryGetValue (mvid, out lines)) { + lines = new List (); + mvidLines.Add (mvid, lines); + } + + lines.Add (lineNumber); + } + + var mvids = new List (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 handler) + { + if (metadataHandlers == null) + InitMetadataHandlers (); + + metadataHandlers.Add (id, handler); + } } } diff --git a/mcs/class/corlib/System.Globalization/CultureInfo.cs b/mcs/class/corlib/System.Globalization/CultureInfo.cs index b755b4d5091..8b4a3504d3a 100644 --- a/mcs/class/corlib/System.Globalization/CultureInfo.cs +++ b/mcs/class/corlib/System.Globalization/CultureInfo.cs @@ -127,12 +127,22 @@ namespace System.Globalization 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 () diff --git a/mcs/class/corlib/System.Reflection.Emit/FlowControl.cs b/mcs/class/corlib/System.Reflection.Emit/FlowControl.cs index 8a852c13942..133ff0be6d9 100644 --- a/mcs/class/corlib/System.Reflection.Emit/FlowControl.cs +++ b/mcs/class/corlib/System.Reflection.Emit/FlowControl.cs @@ -25,7 +25,6 @@ // 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 { @@ -87,5 +86,3 @@ namespace System.Reflection.Emit { } } - -#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OpCode.cs b/mcs/class/corlib/System.Reflection.Emit/OpCode.cs index e6cdf10b737..aa3453d2006 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OpCode.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OpCode.cs @@ -26,8 +26,6 @@ // Copyright (C) 2004 Novell, Inc (http://www.novell.com) // -#if !FULL_AOT_RUNTIME || IOS_REFLECTION - using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -151,4 +149,3 @@ namespace System.Reflection.Emit { } } } -#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OpCodeNames.cs b/mcs/class/corlib/System.Reflection.Emit/OpCodeNames.cs index 1163869317e..67ddad4a581 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OpCodeNames.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OpCodeNames.cs @@ -1,4 +1,3 @@ -#if !FULL_AOT_RUNTIME || IOS_REFLECTION namespace System.Reflection.Emit { static class OpCodeNames { internal static readonly string [] names = { @@ -309,4 +308,3 @@ namespace System.Reflection.Emit { }; } } -#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OpCodeType.cs b/mcs/class/corlib/System.Reflection.Emit/OpCodeType.cs index df0cbf0d50a..c50e574bde8 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OpCodeType.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OpCodeType.cs @@ -25,7 +25,6 @@ // 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 { @@ -75,4 +74,3 @@ namespace System.Reflection.Emit { } } -#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OpCodes.cs b/mcs/class/corlib/System.Reflection.Emit/OpCodes.cs index 6e891d538d4..03317d2626f 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OpCodes.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OpCodes.cs @@ -1,4 +1,3 @@ -#if !FULL_AOT_RUNTIME || IOS_REFLECTION using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -929,4 +928,3 @@ namespace System.Reflection.Emit { } } } -#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OperandType.cs b/mcs/class/corlib/System.Reflection.Emit/OperandType.cs index 2985b1b57ee..4d823d33cbe 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OperandType.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OperandType.cs @@ -25,7 +25,6 @@ // 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 { @@ -112,5 +111,3 @@ namespace System.Reflection.Emit { } } - -#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/PackingSize.cs b/mcs/class/corlib/System.Reflection.Emit/PackingSize.cs index 08052a3386e..ad6be1d1d74 100644 --- a/mcs/class/corlib/System.Reflection.Emit/PackingSize.cs +++ b/mcs/class/corlib/System.Reflection.Emit/PackingSize.cs @@ -25,7 +25,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -70,6 +69,3 @@ namespace System.Reflection.Emit { } } - - -#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/StackBehaviour.cs b/mcs/class/corlib/System.Reflection.Emit/StackBehaviour.cs index 16a27149592..524ea8d3059 100644 --- a/mcs/class/corlib/System.Reflection.Emit/StackBehaviour.cs +++ b/mcs/class/corlib/System.Reflection.Emit/StackBehaviour.cs @@ -25,7 +25,6 @@ // 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 { @@ -153,4 +152,3 @@ namespace System.Reflection.Emit { } } -#endif diff --git a/mcs/class/corlib/System.Reflection.Metadata/AssemblyExtensions.cs b/mcs/class/corlib/System.Reflection.Metadata/AssemblyExtensions.cs new file mode 100644 index 00000000000..19da0435b5a --- /dev/null +++ b/mcs/class/corlib/System.Reflection.Metadata/AssemblyExtensions.cs @@ -0,0 +1,46 @@ +// +// AssemblyExtensions.cs +// +// Authors: +// Marek Safar +// +// 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 diff --git a/mcs/class/corlib/System.Reflection/Assembly.cs b/mcs/class/corlib/System.Reflection/Assembly.cs index f75802198eb..c90059d3a87 100644 --- a/mcs/class/corlib/System.Reflection/Assembly.cs +++ b/mcs/class/corlib/System.Reflection/Assembly.cs @@ -138,6 +138,9 @@ namespace System.Reflection { [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) { diff --git a/mcs/class/corlib/System.Reflection/AssemblyName.cs b/mcs/class/corlib/System.Reflection/AssemblyName.cs index 9da34563f24..42006c3e80f 100644 --- a/mcs/class/corlib/System.Reflection/AssemblyName.cs +++ b/mcs/class/corlib/System.Reflection/AssemblyName.cs @@ -433,6 +433,11 @@ namespace System.Reflection { get { return (cultureinfo == null)? null : cultureinfo.Name; } +#if NETSTANDARD + set { + throw new NotImplementedException (); + } +#endif } [ComVisibleAttribute(false)] diff --git a/mcs/class/corlib/System.Runtime.Loader/AssemblyLoadContext.cs b/mcs/class/corlib/System.Runtime.Loader/AssemblyLoadContext.cs new file mode 100644 index 00000000000..1839144bcbc --- /dev/null +++ b/mcs/class/corlib/System.Runtime.Loader/AssemblyLoadContext.cs @@ -0,0 +1,108 @@ +// +// AssemblyLoadContext.cs +// +// Authors: +// Marek Safar +// +// 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 Resolving; + public event Action Unloading; + } +} + +#endif \ No newline at end of file diff --git a/mcs/class/corlib/System/RuntimeTypeHandle.cs b/mcs/class/corlib/System/RuntimeTypeHandle.cs index eb6c42f0976..cd51c87a2a8 100644 --- a/mcs/class/corlib/System/RuntimeTypeHandle.cs +++ b/mcs/class/corlib/System/RuntimeTypeHandle.cs @@ -243,5 +243,9 @@ namespace System [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static bool IsGenericTypeDefinition (RuntimeType type); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal extern static IntPtr GetGenericParameterInfo (RuntimeType type); + } } diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs index c9a00481185..df214d97b20 100644 --- a/mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs +++ b/mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs @@ -14,6 +14,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Diagnostics; using System.Runtime.ExceptionServices; +using System.Linq; using NUnit.Framework; @@ -517,7 +518,10 @@ namespace MonoTests.System.Reflection.Emit 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); @@ -552,9 +556,12 @@ namespace MonoTests.System.Reflection.Emit 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"); } } diff --git a/mcs/class/corlib/Test/System.Runtime.ExceptionServices/ExceptionDispatchInfoTest.cs b/mcs/class/corlib/Test/System.Runtime.ExceptionServices/ExceptionDispatchInfoTest.cs index 900ffec6e7c..51ffc73db4d 100644 --- a/mcs/class/corlib/Test/System.Runtime.ExceptionServices/ExceptionDispatchInfoTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.ExceptionServices/ExceptionDispatchInfoTest.cs @@ -31,6 +31,7 @@ using NUnit.Framework; using System.Runtime.ExceptionServices; using System.Threading.Tasks; using System.Diagnostics; +using System.Linq; namespace MonoTests.System.Runtime.ExceptionServices { @@ -38,6 +39,14 @@ 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 () { @@ -75,7 +84,7 @@ namespace MonoTests.System.Runtime.ExceptionServices 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"); @@ -90,8 +99,9 @@ namespace MonoTests.System.Runtime.ExceptionServices 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"); } } @@ -120,9 +130,9 @@ namespace MonoTests.System.Runtime.ExceptionServices 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"); } } @@ -147,10 +157,10 @@ namespace MonoTests.System.Runtime.ExceptionServices 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"); } } @@ -166,9 +176,9 @@ namespace MonoTests.System.Runtime.ExceptionServices } } 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"); } } } diff --git a/mcs/class/corlib/corlib.dll.sources b/mcs/class/corlib/corlib.dll.sources index e037132ba7d..1419dea79ed 100644 --- a/mcs/class/corlib/corlib.dll.sources +++ b/mcs/class/corlib/corlib.dll.sources @@ -307,6 +307,7 @@ System.Reflection.Emit/StringToken.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 @@ -601,6 +602,7 @@ System.Runtime.Remoting.Proxies/ProxyAttribute.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 diff --git a/mcs/class/referencesource/System.Core/System/Security/Cryptography/BCryptNative.cs b/mcs/class/referencesource/System.Core/System/Security/Cryptography/BCryptNative.cs index 48a8467961f..b0586886a1b 100644 --- a/mcs/class/referencesource/System.Core/System/Security/Cryptography/BCryptNative.cs +++ b/mcs/class/referencesource/System.Core/System/Security/Cryptography/BCryptNative.cs @@ -59,7 +59,7 @@ namespace System.Security.Cryptography { public const string Sha512 = "SHA512"; // BCRYPT_SHA512_ALGORITHM internal const string Rsa = "RSA"; // BCRYPT_RSA_ALGORITHM } - +#if !MONO /// /// Well known key blob tyes /// @@ -454,5 +454,6 @@ namespace System.Security.Cryptography { } return keyBlob; } +#endif } } diff --git a/mcs/class/referencesource/System.Core/System/Security/Cryptography/CngKey.cs b/mcs/class/referencesource/System.Core/System/Security/Cryptography/CngKey.cs index 13ea41c2fb2..46870878014 100644 --- a/mcs/class/referencesource/System.Core/System/Security/Cryptography/CngKey.cs +++ b/mcs/class/referencesource/System.Core/System/Security/Cryptography/CngKey.cs @@ -31,6 +31,10 @@ namespace System.Security.Cryptography { /// [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; @@ -816,5 +820,6 @@ namespace System.Security.Cryptography { Contract.Assert(m_keyHandle != null); NCryptNative.SetProperty(m_keyHandle, property.Name, property.Value, property.Options); } +#endif } } diff --git a/mcs/class/referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs b/mcs/class/referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs index 40505e30ddb..c1f169ead6a 100644 --- a/mcs/class/referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs +++ b/mcs/class/referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs @@ -18,6 +18,15 @@ namespace System.Security.Cryptography { /// [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; @@ -407,5 +416,6 @@ namespace System.Security.Cryptography { return hasher.HashFinal(); } } + #endif } } diff --git a/mcs/class/referencesource/System.Core/System/Security/Cryptography/NCryptNative.cs b/mcs/class/referencesource/System.Core/System/Security/Cryptography/NCryptNative.cs index cf56209111a..8807a434240 100644 --- a/mcs/class/referencesource/System.Core/System/Security/Cryptography/NCryptNative.cs +++ b/mcs/class/referencesource/System.Core/System/Security/Cryptography/NCryptNative.cs @@ -8,7 +8,9 @@ using System; 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; @@ -100,7 +102,7 @@ namespace System.Security.Cryptography { ProtectKey = 0x00000001, // NCRYPT_UI_PROTECT_KEY_FLAG ForceHighProtection = 0x00000002 // NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG } - +#if !MONO /// /// Native interop with CNG's NCrypt layer. Native definitions are in ncrypt.h /// @@ -1741,4 +1743,5 @@ namespace System.Security.Cryptography { return error == ErrorCode.Success; } } +#endif } diff --git a/mcs/class/referencesource/System.Core/System/Security/Cryptography/RsaCng.cs b/mcs/class/referencesource/System.Core/System/Security/Cryptography/RsaCng.cs index 3085b90e249..842c40428e9 100644 --- a/mcs/class/referencesource/System.Core/System/Security/Cryptography/RsaCng.cs +++ b/mcs/class/referencesource/System.Core/System/Security/Cryptography/RsaCng.cs @@ -10,6 +10,18 @@ namespace System.Security.Cryptography { 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) }; @@ -504,5 +516,6 @@ namespace System.Security.Cryptography throw new CryptographicException(SR.GetString(SR.Cryptography_UnsupportedPaddingMode)); } } +#endif } } diff --git a/mcs/tools/mono-api-html/ApiDiff.cs b/mcs/tools/mono-api-html/ApiDiff.cs index 8fe27844852..0f4cd7c2d95 100644 --- a/mcs/tools/mono-api-html/ApiDiff.cs +++ b/mcs/tools/mono-api-html/ApiDiff.cs @@ -78,10 +78,11 @@ namespace Xamarin.ApiDiff { 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) @@ -120,7 +121,8 @@ namespace Xamarin.ApiDiff { 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 { @@ -130,6 +132,13 @@ namespace Xamarin.ApiDiff { 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] [diff.html]"); Console.WriteLine (); @@ -253,9 +262,11 @@ namespace Xamarin.ApiDiff { } else { file.WriteLine ("

{0}.dll vs {1}.dll

", ac.SourceAssembly, ac.TargetAssembly); } - file.WriteLine ("Hide non-breaking changes"); - file.WriteLine (""); - file.WriteLine ("
"); + if (!State.IgnoreNonbreaking) { + file.WriteLine ("Hide non-breaking changes"); + file.WriteLine (""); + file.WriteLine ("
"); + } file.WriteLine ("
"); file.Write (diffHtml); file.WriteLine ("
"); diff --git a/mcs/tools/mono-api-html/ClassComparer.cs b/mcs/tools/mono-api-html/ClassComparer.cs index a3399fbef04..f6cf940c9e4 100644 --- a/mcs/tools/mono-api-html/ClassComparer.cs +++ b/mcs/tools/mono-api-html/ClassComparer.cs @@ -198,6 +198,20 @@ namespace Xamarin.ApiDiff { 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) @@ -206,7 +220,7 @@ namespace Xamarin.ApiDiff { 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 ()); } diff --git a/mcs/tools/mono-api-html/FieldComparer.cs b/mcs/tools/mono-api-html/FieldComparer.cs index a2b0225b448..f292eee22dd 100644 --- a/mcs/tools/mono-api-html/FieldComparer.cs +++ b/mcs/tools/mono-api-html/FieldComparer.cs @@ -45,14 +45,16 @@ namespace Xamarin.ApiDiff { 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"); + } } } diff --git a/mcs/tools/mono-api-html/MemberComparer.cs b/mcs/tools/mono-api-html/MemberComparer.cs index d12d86625c2..9da6edc106d 100644 --- a/mcs/tools/mono-api-html/MemberComparer.cs +++ b/mcs/tools/mono-api-html/MemberComparer.cs @@ -138,9 +138,13 @@ namespace Xamarin.ApiDiff { void Modify (ApiChanges modified) { foreach (var changes in modified) { + if (State.IgnoreNonbreaking && changes.Value.All (c => !c.Breaking)) + continue; Output.WriteLine ("

{0}:

", changes.Key); Output.WriteLine ("
");
 				foreach (var element in changes.Value) {
+					if (State.IgnoreNonbreaking && !element.Breaking)
+						continue;
 					Output.Write ("
", element.Breaking ? "data-is-breaking" : "data-is-non-breaking"); foreach (var line in element.Member.ToString ().Split ('\n')) Output.WriteLine ("\t{0}", line); @@ -158,6 +162,8 @@ namespace Xamarin.ApiDiff { if (State.IgnoreRemoved.Any (re => re.IsMatch (GetDescription (item)))) continue; SetContext (item); + if (State.IgnoreNonbreaking && !IsBreakingRemoval (item)) + continue; if (!r) { BeforeRemoving (elements); r = true; diff --git a/mcs/tools/mono-symbolicate/LocationProvider.cs b/mcs/tools/mono-symbolicate/LocationProvider.cs index 01a7ceb97d9..3e9d8837138 100644 --- a/mcs/tools/mono-symbolicate/LocationProvider.cs +++ b/mcs/tools/mono-symbolicate/LocationProvider.cs @@ -7,218 +7,152 @@ using Mono.Cecil; 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; - public SequencePoint TryGetLocation (string typeFullName, string methodSignature, int offset, bool isOffsetIL, uint methodIndex) - { - if (!assembly.MainModule.HasSymbols) - return null; + public AssemblyLocationProvider (string assemblyPath) + { + assemblyPath = Path.GetFullPath (assemblyPath); - 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); - types = type.NestedTypes; - } + var readerParameters = new ReaderParameters { ReadSymbols = true }; + assembly = AssemblyDefinition.ReadAssembly (assemblyPath, readerParameters); + } - 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; - } - } + 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) { + type = types.FirstOrDefault (t => t.Name == ntype); + if (type == null) + return false; - return null; + types = type.NestedTypes; } - SeqPointInfo seqPointInfo; - private int GetILOffsetFromFile (int methodToken, uint methodIndex, int 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) + return false; + + int ilOffset; + if (sfData.IsILOffset) { + ilOffset = sfData.Offset; + } else { if (seqPointInfo == null) - seqPointInfo = SeqPointInfo.Read (seqPointDataPath); + return false; - return seqPointInfo.GetILOffset (methodToken, methodIndex, nativeOffset); + ilOffset = seqPointInfo.GetILOffset (method.MetadataToken.ToInt32 (), sfData.MethodIndex, sfData.Offset); } - static bool CompareName (MethodDefinition candidate, string expected) - { - if (candidate.Name == expected) - return true; + if (ilOffset < 0) + return false; - if (!candidate.HasGenericParameters) - return false; + SequencePoint sp = null; + foreach (var instr in method.Body.Instructions) { + if (instr.SequencePoint != null) + sp = instr.SequencePoint; - 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; + if (instr.Offset >= ilOffset) { + sfData.SetLocation (sp.Document.Url, sp.StartLine); + return true; } - - return candidate.GenericParameters.Count == arity; } - static bool CompareParameters (Collection 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 ("."); - } - - FormatElementType (pt, builder); - - builder.Append (" "); - builder.Append (parameter.Name); - } - - 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; + } - var array = ts as ArrayType; - if (array != null) { - FormatElementType (ts.ElementType, builder); - builder.Append ("["); + static bool CompareParameters (Collection candidate, string expected) + { + var builder = new StringBuilder (); + builder.Append ("("); - for (int ii = 0; ii < array.Rank - 1; ++ii) { - builder.Append (","); - } + for (int i = 0; i < candidate.Count; i++) { + var parameter = candidate [i]; + if (i > 0) + builder.Append (", "); - builder.Append ("]"); - return; - } + if (parameter.ParameterType.IsSentinel) + builder.Append ("...,"); + + 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 assemblies; - HashSet directories; + builder.Append (")"); - public LocationProvider () { - assemblies = new Dictionary (); - directories = new HashSet (); + 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); } } } diff --git a/mcs/tools/mono-symbolicate/Makefile b/mcs/tools/mono-symbolicate/Makefile index 3c30921a61e..62dd73f7f22 100644 --- a/mcs/tools/mono-symbolicate/Makefile +++ b/mcs/tools/mono-symbolicate/Makefile @@ -15,44 +15,65 @@ LIB_PATH = $(topdir)/class/lib/$(PROFILE) 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/).*Test\//) in /" $(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) 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 diff --git a/mcs/tools/mono-symbolicate/SeqPointInfo.cs b/mcs/tools/mono-symbolicate/SeqPointInfo.cs index 606e4fb3f17..22a3dae62fb 100644 --- a/mcs/tools/mono-symbolicate/SeqPointInfo.cs +++ b/mcs/tools/mono-symbolicate/SeqPointInfo.cs @@ -2,7 +2,7 @@ using System; using System.IO; using System.Collections.Generic; -namespace Symbolicate +namespace Mono { static class BinaryReaderExtensions { diff --git a/mcs/tools/mono-symbolicate/StackFrameData.cs b/mcs/tools/mono-symbolicate/StackFrameData.cs new file mode 100644 index 00000000000..cc9b44c91e4 --- /dev/null +++ b/mcs/tools/mono-symbolicate/StackFrameData.cs @@ -0,0 +1,99 @@ +using System.Text.RegularExpressions; +using System.Globalization; + +namespace Mono +{ + class StackFrameData + { + static Regex regex = new Regex (@"\w*at (?.+) *(\[0x(?.+)\]|<0x.+ \+ 0x(?.+)>( (?\d+)|)) in :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 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; + } + + public static bool TryParse (string line, out StackFrameData stackFrame) + { + stackFrame = null; + + var match = regex.Match (line); + if (!match.Success) + 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 (":0") && LineNumber != -1) + return Line.Replace (":0", string.Format ("{0}:{1}", File, LineNumber)); + + return Line; + } + } +} diff --git a/mcs/tools/mono-symbolicate/StackTraceMetadata.cs b/mcs/tools/mono-symbolicate/StackTraceMetadata.cs new file mode 100644 index 00000000000..4aa47532320 --- /dev/null +++ b/mcs/tools/mono-symbolicate/StackTraceMetadata.cs @@ -0,0 +1,36 @@ +using System.Text.RegularExpressions; + +namespace Mono +{ + class StackTraceMetadata + { + static Regex regex = new Regex (@"\[(?.+)\] (?.+)"); + + 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; + } + } +} diff --git a/mcs/tools/mono-symbolicate/SymbolManager.cs b/mcs/tools/mono-symbolicate/SymbolManager.cs new file mode 100644 index 00000000000..466f18dc68c --- /dev/null +++ b/mcs/tools/mono-symbolicate/SymbolManager.cs @@ -0,0 +1,111 @@ +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; + + public SymbolManager (string msymDir) { + this.msymDir = msymDir; + } + + internal bool TryResolveLocation (StackFrameData sfData, string mvid, string aotid) + { + var assemblyLocProvider = GetOrCreateAssemblyLocationProvider (mvid); + + SeqPointInfo seqPointInfo = null; + if (!sfData.IsILOffset && aotid != null) + seqPointInfo = GetOrCreateSeqPointInfo (aotid); + + return assemblyLocProvider.TryResolveLocation (sfData, seqPointInfo); + } + + Dictionary assemblies = new Dictionary (); + + private AssemblyLocationProvider GetOrCreateAssemblyLocationProvider (string mvid) + { + if (assemblies.ContainsKey (mvid)) + return assemblies[mvid]; + + var mvidDir = Path.Combine (msymDir, mvid); + if (!Directory.Exists (mvidDir)) + throw new Exception (string.Format("MVID directory does not exist: {0}", mvidDir)); + + string assemblyPath = null; + var exeFiles = Directory.GetFiles (mvidDir, "*.exe"); + var dllFiles = Directory.GetFiles (mvidDir, "*.dll"); + + if (exeFiles.Length + dllFiles.Length != 1) + throw new Exception (string.Format ("MVID directory should include one assembly: {0}", mvidDir)); + + assemblyPath = (exeFiles.Length > 0)? exeFiles[0] : dllFiles[0]; + + var locProvider = new AssemblyLocationProvider (assemblyPath); + + assemblies.Add (mvid, locProvider); + + return locProvider; + } + + Dictionary seqPointInfos = new Dictionary (); + + private SeqPointInfo GetOrCreateSeqPointInfo (string aotid) + { + if (seqPointInfos.ContainsKey (aotid)) + return seqPointInfos[aotid]; + + var aotidDir = Path.Combine (msymDir, aotid); + if (!Directory.Exists (aotidDir)) + throw new Exception (string.Format("AOTID directory does not exist: {0}", aotidDir)); + + 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)) { + // 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); + + 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 + } + } + } + } +} diff --git a/mcs/tools/mono-symbolicate/mono-symbolicate.exe.sources b/mcs/tools/mono-symbolicate/mono-symbolicate.exe.sources index 5c4437ba569..b6f80e99ace 100644 --- a/mcs/tools/mono-symbolicate/mono-symbolicate.exe.sources +++ b/mcs/tools/mono-symbolicate/mono-symbolicate.exe.sources @@ -1,3 +1,7 @@ symbolicate.cs LocationProvider.cs SeqPointInfo.cs +StackFrameData.cs +StackTraceMetadata.cs +SymbolManager.cs +../../class/Mono.Options/Mono.Options/Options.cs diff --git a/mcs/tools/mono-symbolicate/symbolicate.cs b/mcs/tools/mono-symbolicate/symbolicate.cs index cb7aa9a46cd..6479a48b863 100644 --- a/mcs/tools/mono-symbolicate/symbolicate.cs +++ b/mcs/tools/mono-symbolicate/symbolicate.cs @@ -1,92 +1,170 @@ 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 (?.+) *(\[0x(?.+)\]|<0x.+ \+ 0x(?.+)>( (?\d+)|)) in :0"); + class Command { + public readonly int MinArgCount; + public readonly int MaxArgCount; + public readonly Action> Action; + + public Command (Action> action, int minArgCount = 0, int maxArgCount = int.MaxValue) + { + Action = action; + MinArgCount = minArgCount; + MaxArgCount = maxArgCount; + } + } public static int Main (String[] args) { - if (args.Length < 2) { - Console.Error.WriteLine ("Usage: symbolicate [lookup directories]"); - return 1; - } + var showHelp = false; + List extra = null; - var assemblyPath = args [0]; - var inputFile = args [1]; + Command cmd = null; - var locProvider = new LocationProvider (); + if (args[0] == "store-symbols") + cmd = new Command (StoreSymbolsAction, 2); - for (var i = 2; i < args.Length; i++) - locProvider.AddDirectory (args [i]); + if (cmd != null) { + args = args.Skip (1).ToArray (); + } else { + cmd = new Command (SymbolicateAction, 2, 2); + } - locProvider.AddAssembly (assemblyPath); + var options = new OptionSet { + { "h|help", "Show this help", v => showHelp = true }, + }; - using (StreamReader r = new StreamReader (inputFile)) { - for (var line = r.ReadLine (); line != null; line = r.ReadLine ()) { - line = SymbolicateLine (line, locProvider); - Console.WriteLine (line); - } + try { + extra = options.Parse (args); + } catch (OptionException e) { + Console.WriteLine ("Option error: {0}", e.Message); + showHelp = true; } + if (showHelp || extra == null || extra.Count < cmd.MinArgCount || extra.Count > cmd.MaxArgCount) { + Console.Error.WriteLine ("Usage: symbolicate "); + Console.Error.WriteLine (" symbolicate store-symbols []+"); + Console.WriteLine (); + Console.WriteLine ("Available options:"); + options.WriteOptionDescriptions (Console.Out); + return 1; + } + + cmd.Action (extra); + return 0; } - static string SymbolicateLine (string line, LocationProvider locProvider) + private static void SymbolicateAction (List 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); - 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 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); - return line.Replace (":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 stackFrames = new List(); + List metadata = new List(); + 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); + + return sb; + } + + private static void DumpStackTrace (SymbolManager symbolManager, StringBuilder sb, List stackFrames, List metadata) + { + string aotid = null; + var aotidMetadata = metadata.FirstOrDefault ( m => m.Id == "AOTID" ); + if (aotidMetadata != null) + aotid = aotidMetadata.Value; - // Adjustment for Type..ctor () - if (typeNameEnd > 0 && str [typeNameEnd - 1] == '.') { - --typeNameEnd; + var linesMvid = ProcessLinesMVID (metadata); + var lineNumber = 0; + foreach (var sfData in stackFrames) { + string mvid = null; + 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 ProcessLinesMVID (List metadata) + { + var linesMvid = new Dictionary (); + 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 +} diff --git a/mono/io-layer/Makefile.am b/mono/io-layer/Makefile.am index fd819424978..54e2dde02a1 100644 --- a/mono/io-layer/Makefile.am +++ b/mono/io-layer/Makefile.am @@ -15,7 +15,6 @@ OTHER_H = \ context.h \ error.h \ events.h \ - handles.h \ io.h \ io-trace.h \ io-layer.h \ @@ -46,9 +45,6 @@ OTHER_SRC = \ events.c \ events.h \ event-private.h \ - handles.c \ - handles.h \ - handles-private.h \ io.c \ io.h \ io-portability.c \ @@ -93,6 +89,7 @@ OTHER_SRC = \ wapi_glob.c \ wapi.h \ wapi-private.h \ + wapi.c \ wthreads.c diff --git a/mono/io-layer/error.c b/mono/io-layer/error.c index 6d40dd3b5cc..db128be5c72 100644 --- a/mono/io-layer/error.c +++ b/mono/io-layer/error.c @@ -14,11 +14,11 @@ #include #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) { diff --git a/mono/io-layer/event-private.h b/mono/io-layer/event-private.h index 25df9111656..07b35e0c2f9 100644 --- a/mono/io-layer/event-private.h +++ b/mono/io-layer/event-private.h @@ -14,10 +14,7 @@ #include #include -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 { @@ -27,9 +24,11 @@ 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_ */ diff --git a/mono/io-layer/events.c b/mono/io-layer/events.c index f34ae7139b2..8e3fa4a0394 100644 --- a/mono/io-layer/events.c +++ b/mono/io-layer/events.c @@ -14,79 +14,94 @@ #include #include -#include #include #include #include #include +#include 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) @@ -96,28 +111,7 @@ 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) @@ -128,162 +122,124 @@ 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; } @@ -311,127 +267,13 @@ gpointer CreateEvent(WapiSecurityAttributes *security G_GNUC_UNUSED, 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); } /** @@ -451,95 +293,65 @@ static gboolean namedevent_pulse (gpointer handle) */ 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; } /** @@ -553,85 +365,54 @@ static gboolean namedevent_reset (gpointer handle) */ 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; } /** @@ -650,21 +431,47 @@ static gboolean namedevent_set (gpointer handle) */ 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) @@ -672,8 +479,6 @@ gpointer OpenEvent (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED 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 @@ -685,9 +490,9 @@ gpointer OpenEvent (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED 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. */ diff --git a/mono/io-layer/handles-private.h b/mono/io-layer/handles-private.h deleted file mode 100644 index 81b17ea2f6b..00000000000 --- a/mono/io-layer/handles-private.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * 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 -#include -#include -#include -#include - -#include -#include -#include - -#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_ */ diff --git a/mono/io-layer/handles.c b/mono/io-layer/handles.c deleted file mode 100644 index 0dd31517695..00000000000 --- a/mono/io-layer/handles.c +++ /dev/null @@ -1,1341 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#ifdef HAVE_SIGNAL_H -#include -#endif -#include -#include -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -#ifdef HAVE_SYS_UN_H -# include -#endif -#ifdef HAVE_SYS_MMAN_H -# include -#endif -#ifdef HAVE_DIRENT_H -# include -#endif -#include -#ifdef HAVE_SYS_RESOURCE_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#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; ii) { - *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; idevice == 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); -} diff --git a/mono/io-layer/handles.h b/mono/io-layer/handles.h deleted file mode 100644 index 31cab7bdb94..00000000000 --- a/mono/io-layer/handles.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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_ */ diff --git a/mono/io-layer/io-private.h b/mono/io-layer/io-private.h index 9af4b1f0a11..392b081ca79 100644 --- a/mono/io-layer/io-private.h +++ b/mono/io-layer/io-private.h @@ -21,16 +21,8 @@ #include #include -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 diff --git a/mono/io-layer/io-trace.h b/mono/io-layer/io-trace.h index f67ff65f842..e65fdc345a3 100644 --- a/mono/io-layer/io-trace.h +++ b/mono/io-layer/io-trace.h @@ -13,6 +13,7 @@ #ifdef DISABLE_IO_LAYER_TRACE #define MONO_TRACE(...) #else +#include "mono/utils/mono-logger-internals.h" #define MONO_TRACE(...) mono_trace (__VA_ARGS__) #endif diff --git a/mono/io-layer/io.c b/mono/io-layer/io.c index 145529ed532..8ec7c50ae58 100644 --- a/mono/io-layer/io.c +++ b/mono/io-layer/io.c @@ -38,7 +38,6 @@ #include #include -#include #include #include #include @@ -47,8 +46,120 @@ #include #include #include +#include + +/* + * 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, @@ -71,31 +182,22 @@ static gboolean file_setfiletime(gpointer handle, 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, @@ -107,32 +209,37 @@ static gboolean console_write(gpointer handle, gconstpointer buffer, /* 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); @@ -142,20 +249,18 @@ static gboolean pipe_write (gpointer handle, gconstpointer buffer, /* 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); @@ -181,7 +286,7 @@ static const struct { 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, @@ -217,21 +322,8 @@ static const struct { 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. */ @@ -384,6 +476,31 @@ static void file_close (gpointer handle, gpointer data) 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); @@ -397,7 +514,7 @@ static gboolean file_read(gpointer handle, gpointer buffer, 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__, @@ -450,7 +567,7 @@ static gboolean file_write(gpointer handle, gconstpointer buffer, 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__, @@ -526,7 +643,7 @@ static gboolean file_flush(gpointer handle) 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__, @@ -566,7 +683,7 @@ static guint32 file_seek(gpointer handle, gint32 movedistance, 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__, @@ -663,7 +780,7 @@ static gboolean file_setendoffile(gpointer handle) 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__, @@ -773,7 +890,7 @@ static guint32 file_getfilesize(gpointer handle, guint32 *highsize) 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__, @@ -859,7 +976,7 @@ static gboolean file_getfiletime(gpointer handle, WapiFileTime *create_time, 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__, @@ -941,7 +1058,7 @@ static gboolean file_setfiletime(gpointer handle, 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__, @@ -1058,6 +1175,21 @@ static void console_close (gpointer handle, gpointer data) } } +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); @@ -1071,7 +1203,7 @@ static gboolean console_read(gpointer handle, gpointer buffer, 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__, @@ -1121,7 +1253,7 @@ static gboolean console_write(gpointer handle, gconstpointer buffer, 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__, @@ -1167,6 +1299,16 @@ static gboolean console_write(gpointer handle, gconstpointer buffer, 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; @@ -1182,6 +1324,21 @@ static void pipe_close (gpointer handle, gpointer 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); @@ -1195,7 +1352,7 @@ static gboolean pipe_read (gpointer handle, gpointer buffer, 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__, @@ -1255,7 +1412,7 @@ static gboolean pipe_write(gpointer handle, gconstpointer buffer, 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__, @@ -1497,10 +1654,8 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess, 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; @@ -1553,7 +1708,7 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess, 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); @@ -1624,19 +1779,19 @@ gpointer CreateFile(const gunichar2 *name, guint32 fileaccess, #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); @@ -2175,7 +2330,7 @@ gpointer GetStdHandle(WapiStdHandle stdhandle) thr_ret = mono_os_mutex_lock (&stdhandle_mutex); g_assert (thr_ret == 0); - 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 */ @@ -2187,7 +2342,7 @@ gpointer GetStdHandle(WapiStdHandle stdhandle) } } else { /* Add a reference to this handle */ - _wapi_handle_ref (handle); + mono_w32handle_ref (handle); } done: @@ -2227,9 +2382,9 @@ gpointer GetStdHandle(WapiStdHandle stdhandle) 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); @@ -2268,9 +2423,9 @@ gboolean ReadFile(gpointer handle, gpointer buffer, guint32 numbytes, 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); @@ -2293,9 +2448,9 @@ gboolean WriteFile(gpointer handle, gconstpointer buffer, guint32 numbytes, */ 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); @@ -2317,9 +2472,9 @@ gboolean FlushFileBuffers(gpointer 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); @@ -2361,9 +2516,9 @@ gboolean SetEndOfFile(gpointer 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); @@ -2387,14 +2542,9 @@ guint32 SetFilePointer(gpointer handle, gint32 movedistance, */ 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); @@ -2422,9 +2572,9 @@ WapiFileType GetFileType(gpointer 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); @@ -2462,9 +2612,9 @@ guint32 GetFileSize(gpointer handle, guint32 *highsize) 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); @@ -2502,9 +2652,9 @@ gboolean SetFileTime(gpointer handle, const WapiFileTime *create_time, 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); @@ -2737,8 +2887,8 @@ gpointer FindFirstFile (const gunichar2 *pattern, WapiFindData *find_data) 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); @@ -2772,7 +2922,7 @@ gboolean FindNextFile (gpointer handle, WapiFindData *find_data) 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__, @@ -2781,7 +2931,7 @@ gboolean FindNextFile (gpointer handle, WapiFindData *find_data) return(FALSE); } - thr_ret = _wapi_handle_lock_handle (handle); + thr_ret = mono_w32handle_lock_handle (handle); g_assert (thr_ret == 0); retry: @@ -2888,7 +3038,7 @@ 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); @@ -2913,7 +3063,7 @@ gboolean FindClose (gpointer handle) 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__, @@ -2922,16 +3072,16 @@ gboolean FindClose (gpointer handle) 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); } @@ -3346,8 +3496,6 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe, 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); @@ -3359,8 +3507,8 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe, 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); @@ -3375,9 +3523,9 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe, 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]); @@ -3388,11 +3536,11 @@ gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe, 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]); @@ -4273,9 +4421,30 @@ GetVolumeInformation (const gunichar2 *path, gunichar2 *volumename, int volumesi } #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); + } } diff --git a/mono/io-layer/io.h b/mono/io-layer/io.h index 4c5a492b95b..5321bcd7c44 100644 --- a/mono/io-layer/io.h +++ b/mono/io-layer/io.h @@ -225,6 +225,7 @@ extern gboolean GetVolumeInformation (const gunichar2 *path, gunichar2 *volumena extern void _wapi_io_init (void); +extern void _wapi_io_cleanup (void); G_END_DECLS diff --git a/mono/io-layer/locking.c b/mono/io-layer/locking.c index c014a2d3dc4..001df9bef7e 100644 --- a/mono/io-layer/locking.c +++ b/mono/io-layer/locking.c @@ -15,10 +15,10 @@ #include #include #include -#include #include #include #include +#include gboolean _wapi_lock_file_region (int fd, off_t offset, off_t length) @@ -125,7 +125,7 @@ LockFile (gpointer handle, guint32 offset_low, guint32 offset_high, 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__, @@ -172,7 +172,7 @@ UnlockFile (gpointer handle, guint32 offset_low, 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__, diff --git a/mono/io-layer/mutex-private.h b/mono/io-layer/mutex-private.h index 21eaaac6705..74dbb841224 100644 --- a/mono/io-layer/mutex-private.h +++ b/mono/io-layer/mutex-private.h @@ -15,10 +15,7 @@ #include #include -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 { @@ -28,11 +25,13 @@ 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_ */ diff --git a/mono/io-layer/mutexes.c b/mono/io-layer/mutexes.c index 9bcff16fe22..0bddd29ed0f 100644 --- a/mono/io-layer/mutexes.c +++ b/mono/io-layer/mutexes.c @@ -15,206 +15,154 @@ #include #include -#include #include #include #include #include +#include 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 @@ -222,224 +170,197 @@ static void namedmutex_prewait (gpointer handle) * 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; } @@ -462,140 +383,87 @@ cleanup: * * 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) @@ -604,8 +472,6 @@ gpointer OpenMutex (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED 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 */ @@ -616,9 +482,9 @@ gpointer OpenMutex (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED 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. */ diff --git a/mono/io-layer/posix.c b/mono/io-layer/posix.c index 2856d4fcd61..fe350c8b866 100644 --- a/mono/io-layer/posix.c +++ b/mono/io-layer/posix.c @@ -22,10 +22,10 @@ #include #include -#include #include #include #include +#include static guint32 convert_from_flags(int flags) @@ -101,8 +101,8 @@ gpointer _wapi_stdhandle_create (int fd, const gchar *name) 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); diff --git a/mono/io-layer/process-private.h b/mono/io-layer/process-private.h index ddd6e863f36..a17de8a3adb 100644 --- a/mono/io-layer/process-private.h +++ b/mono/io-layer/process-private.h @@ -30,12 +30,10 @@ #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 diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c index 89bd3f0e8bb..20ad800c048 100644 --- a/mono/io-layer/processes.c +++ b/mono/io-layer/processes.c @@ -95,7 +95,6 @@ #include #include -#include #include #include #include @@ -109,6 +108,7 @@ #include #include #include +#include /* The process' environment strings */ #if defined(__APPLE__) @@ -129,6 +129,9 @@ extern char **environ; 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)) @@ -136,13 +139,16 @@ static FILE * 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 @@ -178,7 +184,7 @@ lookup_process_handle (gpointer handle) 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; @@ -894,8 +900,8 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, 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; @@ -998,7 +1004,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } /* 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 @@ -1029,7 +1035,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, 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; @@ -1046,7 +1052,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } 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_w32handle_ref (handle); mono_process->handle = handle; process_handle_data->mono_process = mono_process; @@ -1072,7 +1078,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } if (fork_failed) - _wapi_handle_unref (handle); + mono_w32handle_unref (handle); if (startup_pipe [1] != -1) { /* Write 1 byte, doesn't matter what */ @@ -1130,20 +1136,22 @@ process_set_name (WapiHandle_process *process_handle) } 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); @@ -1153,7 +1161,7 @@ wapi_processes_init (void) gpointer _wapi_process_duplicate (void) { - _wapi_handle_ref (current_process); + mono_w32handle_ref (current_process); return current_process; } @@ -1209,9 +1217,9 @@ process_open_compare (gpointer handle, gpointer user_data) * 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; @@ -1239,7 +1247,7 @@ OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, g 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) { @@ -1257,7 +1265,7 @@ OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, g } } - /* _wapi_search_handle () already added a ref */ + /* mono_w32handle_search () already added a ref */ return handle; } @@ -1304,7 +1312,7 @@ GetExitCodeProcess (gpointer process, guint32 *code) */ process_wait (process, 0, TRUE); - if (_wapi_handle_issignalled (process)) + if (mono_w32handle_issignalled (process)) *code = process_handle->exitstatus; else *code = STILL_ACTIVE; @@ -1350,7 +1358,7 @@ GetProcessTimes (gpointer process, WapiFileTime *create_time, /* 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 @@ -2588,7 +2596,7 @@ mono_processes_cleanup (void) mp->handle = NULL; mono_os_mutex_unlock (&mono_processes_mutex); if (unref_handle) - _wapi_handle_unref (unref_handle); + mono_w32handle_unref (unref_handle); } } @@ -2657,6 +2665,23 @@ process_close (gpointer handle, gpointer data) 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)) { @@ -2834,7 +2859,7 @@ process_wait (gpointer handle, guint32 timeout, gboolean alertable) 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; } diff --git a/mono/io-layer/processes.h b/mono/io-layer/processes.h index a5ff917f4df..a388d63ef93 100644 --- a/mono/io-layer/processes.h +++ b/mono/io-layer/processes.h @@ -15,7 +15,6 @@ #endif #include -#include #include #include diff --git a/mono/io-layer/semaphore-private.h b/mono/io-layer/semaphore-private.h index 8414f4e9205..3c27eef9892 100644 --- a/mono/io-layer/semaphore-private.h +++ b/mono/io-layer/semaphore-private.h @@ -13,10 +13,7 @@ #include #include -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 @@ -27,9 +24,11 @@ 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_ */ diff --git a/mono/io-layer/semaphores.c b/mono/io-layer/semaphores.c index 721749cd3d7..c473f4dc004 100644 --- a/mono/io-layer/semaphores.c +++ b/mono/io-layer/semaphores.c @@ -19,104 +19,99 @@ #include #include -#include #include #include #include #include +#include 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) @@ -127,146 +122,123 @@ 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; } @@ -291,8 +263,6 @@ cleanup: */ 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__); @@ -307,111 +277,13 @@ gpointer CreateSemaphore(WapiSecurityAttributes *security G_GNUC_UNUSED, gint32 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); } /** @@ -428,21 +300,61 @@ end: */ 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, @@ -452,8 +364,6 @@ gpointer OpenSemaphore (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UN 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 */ @@ -464,9 +374,9 @@ gpointer OpenSemaphore (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UN 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. */ diff --git a/mono/io-layer/shared.c b/mono/io-layer/shared.c index 64a8b330d44..b1d9c1ba509 100644 --- a/mono/io-layer/shared.c +++ b/mono/io-layer/shared.c @@ -27,12 +27,6 @@ _wapi_shm_semaphores_init (void) mono_os_mutex_init (&noshm_sems [i]); } -void -_wapi_shm_semaphores_remove (void) -{ - /* Nothing */ -} - int _wapi_shm_sem_lock (int sem) { diff --git a/mono/io-layer/shared.h b/mono/io-layer/shared.h index 4807adc5a8e..204f50661ff 100644 --- a/mono/io-layer/shared.h +++ b/mono/io-layer/shared.h @@ -11,7 +11,6 @@ #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); diff --git a/mono/io-layer/socket-private.h b/mono/io-layer/socket-private.h index db210e23568..31bbfe33c89 100644 --- a/mono/io-layer/socket-private.h +++ b/mono/io-layer/socket-private.h @@ -13,7 +13,7 @@ #include #include -extern struct _WapiHandleOps _wapi_socket_ops; +#include "wapi-private.h" struct _WapiHandle_socket { @@ -24,4 +24,7 @@ struct _WapiHandle_socket int still_readable; }; +void +_wapi_socket_init (void); + #endif /* _WAPI_SOCKET_PRIVATE_H_ */ diff --git a/mono/io-layer/sockets.c b/mono/io-layer/sockets.c index 4785e1504e3..bc4e032ef4e 100644 --- a/mono/io-layer/sockets.c +++ b/mono/io-layer/sockets.c @@ -39,12 +39,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -59,21 +59,26 @@ 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) @@ -105,11 +110,28 @@ 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) @@ -117,7 +139,7 @@ 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; } @@ -135,12 +157,12 @@ int closesocket(guint32 fd) { 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); } @@ -158,12 +180,12 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen) 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", @@ -187,7 +209,7 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen) 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); @@ -202,9 +224,9 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen) 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); @@ -221,7 +243,7 @@ int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen) 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); } @@ -246,7 +268,7 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr, 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); } @@ -275,8 +297,8 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr, * 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 */ @@ -321,7 +343,7 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr, 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); @@ -345,7 +367,7 @@ int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen) 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); } @@ -370,7 +392,7 @@ int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen) 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); } @@ -400,7 +422,7 @@ int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval, 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); } @@ -431,7 +453,7 @@ int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval, } 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", @@ -459,7 +481,7 @@ int _wapi_listen(guint32 fd, int backlog) 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); } @@ -491,7 +513,7 @@ int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags, 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); } @@ -520,7 +542,7 @@ int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags, * 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; @@ -548,7 +570,7 @@ _wapi_recvmsg(guint32 fd, struct msghdr *msg, int recv_flags) 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); } @@ -560,7 +582,7 @@ _wapi_recvmsg(guint32 fd, struct msghdr *msg, int recv_flags) 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; @@ -585,7 +607,7 @@ int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags) 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); } @@ -622,7 +644,7 @@ int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags, 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); } @@ -650,7 +672,7 @@ _wapi_sendmsg(guint32 fd, const struct msghdr *msg, int send_flags) 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); } @@ -684,7 +706,7 @@ int _wapi_setsockopt(guint32 fd, int level, int optname, #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); } @@ -747,14 +769,14 @@ int _wapi_shutdown(guint32 fd, int how) 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", @@ -811,9 +833,9 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused, 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); @@ -856,10 +878,8 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused, } - 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); @@ -878,7 +898,7 @@ static gboolean socket_disconnect (guint32 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__, @@ -1017,7 +1037,7 @@ TransmitFile (guint32 socket, gpointer file, guint32 bytes_to_write, guint32 byt 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; } @@ -1066,7 +1086,7 @@ WSAIoctl (guint32 fd, gint32 command, 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; } @@ -1204,7 +1224,7 @@ int ioctlsocket(guint32 fd, unsigned long command, gpointer arg) 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); } @@ -1316,7 +1336,7 @@ void _wapi_FD_CLR(guint32 fd, fd_set *set) return; } - if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) { WSASetLastError (WSAENOTSOCK); return; } @@ -1333,7 +1353,7 @@ int _wapi_FD_ISSET(guint32 fd, fd_set *set) return(0); } - if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) { WSASetLastError (WSAENOTSOCK); return(0); } @@ -1350,7 +1370,7 @@ void _wapi_FD_SET(guint32 fd, fd_set *set) return; } - if (_wapi_handle_type (handle) != WAPI_HANDLE_SOCKET) { + if (mono_w32handle_get_type (handle) != MONO_W32HANDLE_SOCKET) { WSASetLastError (WSAENOTSOCK); return; } diff --git a/mono/io-layer/thread-private.h b/mono/io-layer/thread-private.h index a950e5e6da8..a4095002ddd 100644 --- a/mono/io-layer/thread-private.h +++ b/mono/io-layer/thread-private.h @@ -14,11 +14,11 @@ #include #include +#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; @@ -28,6 +28,9 @@ struct _WapiHandle_thread 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); diff --git a/mono/io-layer/threads.h b/mono/io-layer/threads.h index f26cefb548e..412f0f1ebe8 100644 --- a/mono/io-layer/threads.h +++ b/mono/io-layer/threads.h @@ -12,7 +12,6 @@ #include -#include #include #include #include diff --git a/mono/io-layer/wait.c b/mono/io-layer/wait.c index edd875ee188..e9b46f450cc 100644 --- a/mono/io-layer/wait.c +++ b/mono/io-layer/wait.c @@ -13,18 +13,18 @@ #include #include -#include #include #include #include #include +#include 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; } @@ -35,8 +35,8 @@ static gboolean own_if_owned(gpointer handle) { 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; } @@ -89,20 +89,20 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, 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; @@ -113,11 +113,11 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, 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); @@ -145,7 +145,7 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, 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__, @@ -156,7 +156,7 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, } 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) { @@ -164,7 +164,7 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 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, (end - now) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL); } if(waited==0 && !apc_pending) { @@ -194,7 +194,7 @@ done: 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); @@ -281,19 +281,19 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait, 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); @@ -302,12 +302,12 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer 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); @@ -329,7 +329,7 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait, 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); @@ -339,7 +339,7 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer 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) { @@ -347,7 +347,7 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait, 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, (end - now) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL); } if (waited==0 && !apc_pending) { @@ -376,7 +376,7 @@ done: 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); @@ -391,7 +391,7 @@ static gboolean test_and_own (guint32 numobjects, gpointer *handles, 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) { @@ -405,7 +405,7 @@ static gboolean test_and_own (guint32 numobjects, gpointer *handles, 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); } @@ -492,7 +492,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles, 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]); @@ -501,7 +501,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles, } 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); @@ -526,7 +526,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles, 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; @@ -550,7 +550,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles, * 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) { @@ -558,41 +558,41 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles, * 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) { 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 ((end - now) / 10 / 1000, poll, &apc_pending); } } } else { @@ -602,7 +602,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles, 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) { @@ -637,7 +637,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles, for (i = 0; i < numobjects; i++) { /* Unref everything we reffed above */ - _wapi_handle_unref (handles[i]); + mono_w32handle_unref (handles[i]); } return retval; diff --git a/mono/io-layer/wapi-private.h b/mono/io-layer/wapi-private.h index e82d8e68f66..8d3617f1f3e 100644 --- a/mono/io-layer/wapi-private.h +++ b/mono/io-layer/wapi-private.h @@ -15,90 +15,18 @@ #include #include -#include #include +#include #include -/* 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 #include #include @@ -106,6 +34,7 @@ struct _WapiHandleOps #include #include #include +#include struct _WapiHandle_shared_ref { @@ -115,33 +44,6 @@ 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 @@ -165,6 +67,21 @@ struct _WapiFileShare 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_ */ diff --git a/mono/io-layer/wapi.c b/mono/io-layer/wapi.c new file mode 100644 index 00000000000..81e6f6ff027 --- /dev/null +++ b/mono/io-layer/wapi.c @@ -0,0 +1,186 @@ + +#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; +} diff --git a/mono/io-layer/wapi.h b/mono/io-layer/wapi.h index c6cbecd49c5..85da1991103 100644 --- a/mono/io-layer/wapi.h +++ b/mono/io-layer/wapi.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -31,4 +30,17 @@ #include #include +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_ */ diff --git a/mono/io-layer/wthreads.c b/mono/io-layer/wthreads.c index 26246bbaa08..16c5f0e50d2 100644 --- a/mono/io-layer/wthreads.c +++ b/mono/io-layer/wthreads.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -33,27 +32,51 @@ #include #include #include +#include #ifdef HAVE_VALGRIND_MEMCHECK_H #include #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 @@ -78,7 +101,7 @@ lookup_thread (HANDLE handle) 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; @@ -101,8 +124,8 @@ wapi_thread_handle_set_exited (gpointer handle, guint32 exitstatus) 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 */ @@ -123,19 +146,19 @@ wapi_thread_handle_set_exited (gpointer handle, guint32 exitstatus) } 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); } /* @@ -149,12 +172,10 @@ wapi_create_thread_handle (void) 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); @@ -169,7 +190,7 @@ wapi_create_thread_handle (void) * 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); @@ -179,7 +200,7 @@ wapi_create_thread_handle (void) void wapi_ref_thread_handle (gpointer handle) { - _wapi_handle_ref (handle); + mono_w32handle_ref (handle); } gpointer @@ -201,7 +222,7 @@ _wapi_thread_own_mutex (gpointer mutex) thread = get_current_thread (); - _wapi_handle_ref (mutex); + mono_w32handle_ref (mutex); g_ptr_array_add (thread->owned_mutexes, mutex); } @@ -213,7 +234,7 @@ _wapi_thread_disown_mutex (gpointer mutex) thread = get_current_thread (); - _wapi_handle_unref (mutex); + mono_w32handle_unref (mutex); g_ptr_array_remove (thread->owned_mutexes, mutex); } @@ -229,7 +250,7 @@ void 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) @@ -364,7 +385,7 @@ GetThreadPriority (gpointer handle) 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) @@ -399,7 +420,7 @@ SetThreadPriority (gpointer handle, gint32 priority) 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) { diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am index 3639f3e5eb0..32f5628d5f7 100644 --- a/mono/metadata/Makefile.am +++ b/mono/metadata/Makefile.am @@ -292,4 +292,4 @@ libmonoruntimeinclude_HEADERS = \ 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 diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index d0d80a5e9de..f1492bd8c8b 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -67,6 +67,7 @@ #include #include #include +#include #ifdef HOST_WIN32 #include #endif @@ -1513,97 +1514,6 @@ get_shadow_assembly_location (const char *filename, MonoError *error) 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) { @@ -1802,7 +1712,7 @@ mono_make_shadow_copy (const char *filename, MonoError *oerror) 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; diff --git a/mono/metadata/cil-coff.h b/mono/metadata/cil-coff.h index 26b4782ca5a..8581a042f2c 100644 --- a/mono/metadata/cil-coff.h +++ b/mono/metadata/cil-coff.h @@ -295,8 +295,8 @@ typedef struct { #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; diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index b72657fda72..3ce27a7119e 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -573,6 +573,7 @@ struct _MonoGenericParam { }; /* Additional details about a MonoGenericParam */ +/* Keep in sync with managed Mono.RuntimeStructs.GenericParamInfo */ typedef struct { MonoClass *pklass; /* The corresponding `MonoClass'. */ const char *name; diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c index 0ceac2d500a..d564151b7df 100644 --- a/mono/metadata/domain.c +++ b/mono/metadata/domain.c @@ -43,6 +43,7 @@ #include #include #include +#include //#define DEBUG_DOMAIN_UNLOAD 1 @@ -525,6 +526,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char * #endif #ifndef HOST_WIN32 + mono_w32handle_init (); wapi_init (); #endif @@ -893,6 +895,7 @@ mono_cleanup (void) #ifndef HOST_WIN32 wapi_cleanup (); + mono_w32handle_cleanup (); #endif } diff --git a/mono/metadata/file-io.c b/mono/metadata/file-io.c index a871337ee36..9315bdf828f 100644 --- a/mono/metadata/file-io.c +++ b/mono/metadata/file-io.c @@ -34,6 +34,7 @@ #include #include #include +#include #undef DEBUG @@ -1272,11 +1273,11 @@ mono_filesize_from_fd (int fd) #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 } diff --git a/mono/metadata/handle.c b/mono/metadata/handle.c index 4b4239eb66f..bf538fa6d28 100644 --- a/mono/metadata/handle.c +++ b/mono/metadata/handle.c @@ -45,8 +45,7 @@ Combine: MonoDefaults, GENERATE_GET_CLASS_WITH_CACHE, TYPED_HANDLE_DECL and frie 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 diff --git a/mono/metadata/handle.h b/mono/metadata/handle.h index 3d48c064858..b3403695811 100644 --- a/mono/metadata/handle.h +++ b/mono/metadata/handle.h @@ -180,22 +180,30 @@ Handle macros/functions #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 diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index d6012ab5071..19985061661 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -459,6 +459,7 @@ ICALL(OBJ_3, "MemberwiseClone", ves_icall_System_Object_MemberwiseClone) 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) @@ -738,8 +739,6 @@ ICALL(RT_31, "GetCorrespondingInflatedMethod", ves_icall_RuntimeType_GetCorrespo ICALL(RT_3, "GetEvents_internal", ves_icall_RuntimeType_GetEvents_internal) ICALL(RT_5, "GetFields_internal", ves_icall_RuntimeType_GetFields_internal) 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) @@ -767,6 +766,7 @@ ICALL(RTH_2, "GetAssembly", ves_icall_RuntimeTypeHandle_GetAssembly) 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) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index c294eb0a49d..94081c73fd3 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -2881,45 +2881,10 @@ ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type) return -1; } -ICALL_EXPORT GenericParameterAttributes -ves_icall_RuntimeType_GetGenericParameterAttributes (MonoReflectionType *type) +ICALL_EXPORT MonoGenericParamInfo * +ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (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) -{ - 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 @@ -4899,6 +4864,27 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAss 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) { diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index 2922234965a..4f36ba3c82c 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -994,6 +994,7 @@ mono_dllmap_lookup_list (MonoDllMap *dll_map, const char *dll, const char* func, */ } if (dll_map->func && strcmp (dll_map->func, func) == 0) { + *rdll = dll_map->target; *rfunc = dll_map->target_func; break; } @@ -1021,7 +1022,7 @@ mono_dllmap_lookup (MonoImage *assembly, const char *dll, const char* func, cons * @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. * @@ -1056,7 +1057,7 @@ mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, cons 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; @@ -1067,7 +1068,7 @@ mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, cons 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; diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index 6dbf07f7941..3edf257bee5 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -4220,7 +4220,6 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual_) * 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) @@ -4447,7 +4446,6 @@ mono_mb_emit_auto_layout_exception (MonoMethodBuilder *mb, MonoClass *klass) /* * 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) @@ -7594,7 +7592,6 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM * * 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) @@ -8653,7 +8650,6 @@ generate_check_cache (int obj_arg_position, int class_arg_position, int cache_ar /* * 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) @@ -8739,7 +8735,6 @@ mono_marshal_isinst_with_cache (MonoObject *obj, MonoClass *klass, uintptr_t *ca /* * 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) @@ -8916,7 +8911,6 @@ mono_marshal_get_isinst (MonoClass *klass) * 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) @@ -8999,7 +8993,6 @@ 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) @@ -9073,7 +9066,6 @@ 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) @@ -9152,7 +9144,6 @@ 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) @@ -9520,8 +9511,6 @@ record_slot_vstore (MonoObject *array, size_t index, MonoObject *value) #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 @@ -9930,9 +9919,6 @@ mono_marshal_get_virtual_stelemref_wrappers (int *nwrappers) return res; } -/* - * The wrapper info for the wrapper is a WrapperInfo structure. - */ MonoMethod* mono_marshal_get_stelemref (void) { @@ -10083,8 +10069,6 @@ 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) @@ -10119,8 +10103,6 @@ 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) diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h index 96f6a5da7c9..a1b9eb84178 100644 --- a/mono/metadata/metadata-internals.h +++ b/mono/metadata/metadata-internals.h @@ -271,6 +271,8 @@ struct _MonoImage { gpointer aot_module; + guint8 aotid[16]; + /* * The Assembly this image was loaded from. */ diff --git a/mono/metadata/metadata-verify.c b/mono/metadata/metadata-verify.c index 287c68fbfb7..2c5612c2a1d 100644 --- a/mono/metadata/metadata-verify.c +++ b/mono/metadata/metadata-verify.c @@ -730,7 +730,7 @@ verify_cli_header (VerifyContext *ctx) 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; diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index ab0911bc677..2df6db21ec6 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -6069,6 +6069,21 @@ mono_guid_to_string (const guint8 *guid) 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) { diff --git a/mono/metadata/metadata.h b/mono/metadata/metadata.h index 542f9e108e4..6a5172d8810 100644 --- a/mono/metadata/metadata.h +++ b/mono/metadata/metadata.h @@ -301,7 +301,10 @@ typedef struct { 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; @@ -480,6 +483,8 @@ MONO_API uint32_t mono_metadata_token_from_dor (uint32_t dor_index); 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); diff --git a/mono/metadata/process.c b/mono/metadata/process.c index 138bd98553b..8178d283823 100644 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -27,6 +27,7 @@ #include /* FIXME: fix this code to not depend so much on the internals */ #include +#include #define LOGDEBUG(...) /* define LOGDEBUG(...) g_message(__VA_ARGS__) */ diff --git a/mono/metadata/sgen-bridge-internals.h b/mono/metadata/sgen-bridge-internals.h index df6a4bb8cde..129582ed778 100644 --- a/mono/metadata/sgen-bridge-internals.h +++ b/mono/metadata/sgen-bridge-internals.h @@ -45,6 +45,8 @@ typedef struct { 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); /* @@ -62,6 +64,7 @@ void sgen_new_bridge_init (SgenBridgeProcessor *collector); 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_processor(); #endif diff --git a/mono/metadata/sgen-bridge.c b/mono/metadata/sgen-bridge.c index 17719009759..a1f0f51fbbb 100644 --- a/mono/metadata/sgen-bridge.c +++ b/mono/metadata/sgen-bridge.c @@ -39,7 +39,6 @@ mono_gc_wait_for_bridge_processing (void) sgen_gc_unlock (); } - void mono_gc_register_bridge_callbacks (MonoGCBridgeCallbacks *callbacks) { @@ -47,14 +46,10 @@ mono_gc_register_bridge_callbacks (MonoGCBridgeCallbacks *callbacks) g_error ("Invalid bridge callback version. Expected %d but got %d\n", SGEN_BRIDGE_VERSION, callbacks->bridge_version); bridge_callbacks = *callbacks; - - // If callbacks are still uninitialized, initialize defaults - if (!bridge_processor.reset_data) - sgen_tarjan_bridge_init (&bridge_processor); } static gboolean -init_bridge_processor (SgenBridgeProcessor *processor, const char *name) +init_bridge_processor_by_name (SgenBridgeProcessor *processor, const char *name) { if (!strcmp ("old", name)) { memset (processor, 0, sizeof (SgenBridgeProcessor)); @@ -71,10 +66,18 @@ init_bridge_processor (SgenBridgeProcessor *processor, const char *name) return TRUE; } +void +sgen_init_bridge_processor() +{ + // If a bridge was registered but there is no bridge processor yet, init defaults + if (bridge_callbacks.cross_references && !bridge_processor.reset_data) + sgen_tarjan_bridge_init (&bridge_processor); +} + void sgen_set_bridge_implementation (const char *name) { - if (!init_bridge_processor (&bridge_processor, name)) + if (!init_bridge_processor_by_name (&bridge_processor, name)) g_warning ("Invalid value for bridge implementation, valid values are: 'new', 'old' and 'tarjan'."); } @@ -590,7 +593,7 @@ sgen_bridge_handle_gc_debug (const char *opt) 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 (init_bridge_processor_by_name (&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)); diff --git a/mono/metadata/sgen-bridge.h b/mono/metadata/sgen-bridge.h index 38dc44637cc..2292225e083 100644 --- a/mono/metadata/sgen-bridge.h +++ b/mono/metadata/sgen-bridge.h @@ -9,20 +9,23 @@ * 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 @@ -37,6 +40,10 @@ * 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_ @@ -88,6 +95,7 @@ typedef struct { void (*cross_references) (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs); } MonoGCBridgeCallbacks; +// Clients should call before initializing runtime. MONO_API void mono_gc_register_bridge_callbacks (MonoGCBridgeCallbacks *callbacks); MONO_API void mono_gc_wait_for_bridge_processing (void); diff --git a/mono/metadata/sgen-dynarray.h b/mono/metadata/sgen-dynarray.h new file mode 100644 index 00000000000..f5a6a61be6e --- /dev/null +++ b/mono/metadata/sgen-dynarray.h @@ -0,0 +1,346 @@ +/* + * 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; +} diff --git a/mono/metadata/sgen-new-bridge.c b/mono/metadata/sgen-new-bridge.c index a1eb82a714f..4631c0c5430 100644 --- a/mono/metadata/sgen-new-bridge.c +++ b/mono/metadata/sgen-new-bridge.c @@ -24,6 +24,11 @@ #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 @@ -39,31 +44,6 @@ #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 * @@ -131,266 +111,6 @@ static gboolean bridge_accounting_enabled = FALSE; 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 */ diff --git a/mono/metadata/sgen-tarjan-bridge.c b/mono/metadata/sgen-tarjan-bridge.c index 66dff8d1d1c..76c5ac64a90 100644 --- a/mono/metadata/sgen-tarjan-bridge.c +++ b/mono/metadata/sgen-tarjan-bridge.c @@ -24,126 +24,22 @@ #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) @@ -152,6 +48,8 @@ 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) { @@ -182,9 +80,10 @@ class_kind (MonoClass *klass) return GC_BRIDGE_TRANSPARENT_CLASS; } -//enable unsage logging +//enable usage logging // #define DUMP_GRAPH 1 +// ScanData state enum { INITIAL, SCANNED, @@ -197,30 +96,45 @@ Optimizations: 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; @@ -299,6 +213,7 @@ free_object_buckets (void) //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; @@ -372,6 +287,8 @@ create_data (GCObject *obj) 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]; @@ -574,6 +491,7 @@ is_opaque_object (GCObject *obj) 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) { @@ -627,6 +545,7 @@ 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) { @@ -635,7 +554,7 @@ 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" @@ -647,8 +566,8 @@ compute_low_index (ScanData *data, GCObject *obj) { ScanData *other; ColorData *cd; - obj = bridge_object_forward (obj); + obj = bridge_object_forward (obj); other = find_data (obj); #if DUMP_GRAPH @@ -723,12 +642,12 @@ create_scc (ScanData *data) #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); } @@ -775,7 +694,7 @@ create_scc (ScanData *data) 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; } @@ -785,7 +704,7 @@ dfs (void) 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); @@ -852,15 +771,15 @@ register_finalized_object (GCObject *obj) 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 (); @@ -951,7 +870,7 @@ processing_stw_step (void) #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); } @@ -1049,7 +968,7 @@ processing_build_callback_data (int generation) 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); @@ -1089,7 +1008,7 @@ processing_build_callback_data (int generation) #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 diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c index 95bac2301bd..aaef8f6422a 100644 --- a/mono/metadata/socket-io.c +++ b/mono/metadata/socket-io.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #ifdef HAVE_SYS_TIME_H diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index b4f3f091597..50a4329603c 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -4540,7 +4540,7 @@ mono_thread_resume_interruption (void) 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*/ diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index 1023abcd24b..1522b040dd3 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -113,8 +114,8 @@ typedef struct MonoAotOptions { 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; @@ -902,7 +903,10 @@ arch_init (MonoAotCompile *acfg) 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 @@ -7047,12 +7051,11 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts) } 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="));; - } 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")) { @@ -7120,7 +7123,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts) 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"); @@ -8864,6 +8867,21 @@ emit_extra_methods (MonoAotCompile *acfg) emit_aot_data (acfg, MONO_AOT_TABLE_EXTRA_METHOD_INFO_OFFSETS, "extra_method_info_offsets", buf, p - buf); } +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) { @@ -8879,7 +8897,7 @@ 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; @@ -8899,11 +8917,25 @@ emit_exception_info (MonoAotCompile *acfg) } 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); @@ -9357,6 +9389,8 @@ init_aot_file_info (MonoAotCompile *acfg, MonoAotFileInfo *info) 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 @@ -9489,6 +9523,8 @@ emit_aot_file_info (MonoAotCompile *acfg, MonoAotFileInfo *info) 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)); @@ -9933,7 +9969,7 @@ compile_asm (MonoAotCompile *acfg) * 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); @@ -10380,6 +10416,12 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) 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"); diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 5aa2ca6d88a..d60828b0027 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -1782,17 +1782,6 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, guint8 *blob, char 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; @@ -2013,6 +2002,9 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) 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); diff --git a/mono/mini/generics.cs b/mono/mini/generics.cs index 1284cb292ae..80638b5048e 100644 --- a/mono/mini/generics.cs +++ b/mono/mini/generics.cs @@ -898,6 +898,7 @@ class Tests } [Category ("!FULLAOT")] + [Category ("!BITCODE")] public static int test_0_regress_668095_synchronized_gshared () { return DoSomething (new DefaultRetriever ()); } diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index 8651aa25ec4..d7c6d9a232f 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -1630,6 +1630,9 @@ resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_a 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); @@ -1751,9 +1754,11 @@ mono_resolve_generic_virtual_iface_call (MonoVTable *vt, int imt_slot, MonoMetho 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); @@ -1816,12 +1821,16 @@ mono_llvmonly_init_delegate (MonoDelegate *del) * 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); @@ -1842,6 +1851,9 @@ mono_llvmonly_init_delegate_virtual (MonoDelegate *del, MonoObject *target, Mono 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)) diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 78273ea20de..d0232dd540f 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -9745,6 +9745,20 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b 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 @@ -9964,20 +9978,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } } - /* - * 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. */ @@ -11330,6 +11330,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b 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; diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index 054aa4017ae..2f855729e9a 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -339,38 +339,89 @@ merge_argument_class_from_type (MonoType *type, ArgumentClass class1) } 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; @@ -386,7 +437,7 @@ add_valuetype_win64 (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, guint32 argsize = 8; ArgumentClass arg_class; MonoMarshalType *info = NULL; - MonoMarshalField *fields = NULL; + StructFieldInfo *fields = NULL; MonoClass *klass; gboolean pass_on_stack = FALSE; @@ -419,15 +470,12 @@ add_valuetype_win64 (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, * 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); + nfields = count_fields_nested (klass, sig->pinvoke); + fields = g_new0 (StructFieldInfo, nfields); + collect_field_info_nested (klass, fields, 0, 0, sig->pinvoke, klass->unicode); 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) { + if ((fields [i].offset < 8) && (fields [i].offset + fields [i].size) > 8) { pass_on_stack = TRUE; break; } @@ -511,14 +559,11 @@ add_valuetype_win64 (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, 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; + argsize = fields [i].offset + fields [i].size; - 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); arg_class = class1; @@ -598,10 +643,10 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, /* 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); @@ -614,29 +659,25 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, /* 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; } } @@ -683,20 +724,18 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, * 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; @@ -705,8 +744,6 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, 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) @@ -714,10 +751,7 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, 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; } @@ -730,11 +764,13 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, /* 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; } } @@ -789,6 +825,8 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, break; case ARG_CLASS_MEMORY: break; + case ARG_CLASS_NO_CLASS: + break; default: g_assert_not_reached (); } @@ -802,7 +840,7 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, 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; @@ -1018,7 +1056,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) /* 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: @@ -1550,9 +1588,11 @@ mono_arch_allocate_vars (MonoCompile *cfg) } 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<arch.saved_iregs |= iregs_to_save; + } if (cfg->arch.omit_fp) cfg->arch.reg_save_area_offset = offset; @@ -2361,16 +2401,8 @@ dyn_call_supported (MonoMethodSignature *sig, CallInfo *cinfo) 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; } @@ -2381,12 +2413,7 @@ dyn_call_supported (MonoMethodSignature *sig, CallInfo *cinfo) 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)) @@ -2592,15 +2619,22 @@ mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, g 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: @@ -2637,6 +2671,7 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf) 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: @@ -2697,12 +2732,21 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf) 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: @@ -4764,6 +4808,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) 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: { diff --git a/mono/mini/mini-generic-sharing.c b/mono/mini/mini-generic-sharing.c index e1e2eb19b43..aca368c9dba 100644 --- a/mono/mini/mini-generic-sharing.c +++ b/mono/mini/mini-generic-sharing.c @@ -607,6 +607,7 @@ inflate_info (MonoRuntimeGenericContextInfoTemplate *oti, MonoGenericContext *co 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; @@ -620,7 +621,13 @@ inflate_info (MonoRuntimeGenericContextInfoTemplate *oti, MonoGenericContext *co 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) { @@ -633,6 +640,12 @@ inflate_info (MonoRuntimeGenericContextInfoTemplate *oti, MonoGenericContext *co } 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; @@ -1758,6 +1771,9 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti 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); diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index c385f625a29..bc7b1765b71 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -8389,6 +8389,19 @@ llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues) 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: * @@ -8452,7 +8465,7 @@ emit_aot_file_info (MonoLLVMModule *module) 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 (); @@ -8467,6 +8480,7 @@ emit_aot_file_info (MonoLLVMModule *module) 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); @@ -8589,6 +8603,8 @@ emit_aot_file_info (MonoLLVMModule *module) 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)); @@ -8680,6 +8696,9 @@ mono_llvm_emit_aot_module (const char *filename, const char *cu_name) 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) { diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 1bef455a1ee..861ab5cf437 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -1810,6 +1810,10 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *er 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. @@ -3153,7 +3157,9 @@ mini_parse_debug_option (const char *option) 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")) @@ -3198,7 +3204,7 @@ mini_parse_debug_options (void) 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); } } diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c index da6f70e82b3..fbc9674fb52 100644 --- a/mono/mini/mini-trampolines.c +++ b/mono/mini/mini-trampolines.c @@ -1509,6 +1509,9 @@ mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *e 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); diff --git a/mono/mini/mini.c b/mono/mini/mini.c index e497ce406ac..4c79621baf6 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -3241,7 +3241,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl 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; diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 25c208c8389..9039f491dab 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -125,7 +125,7 @@ #endif /* Version number of the AOT file format */ -#define MONO_AOT_FILE_VERSION 134 +#define MONO_AOT_FILE_VERSION 135 //TODO: This is x86/amd64 specific. #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6)) @@ -315,6 +315,8 @@ typedef struct MonoAotFileInfo 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 */ @@ -2119,7 +2121,7 @@ typedef struct { * 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. diff --git a/mono/mini/test_op_il_seq_point.sh b/mono/mini/test_op_il_seq_point.sh index 45d32b99c05..b89cc887ff1 100755 --- a/mono/mini/test_op_il_seq_point.sh +++ b/mono/mini/test_op_il_seq_point.sh @@ -49,16 +49,16 @@ get_method () { 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 } diff --git a/mono/sgen/sgen-gc.c b/mono/sgen/sgen-gc.c index e16cd9b957a..b510a4fc43b 100644 --- a/mono/sgen/sgen-gc.c +++ b/mono/sgen/sgen-gc.c @@ -3142,6 +3142,8 @@ sgen_gc_init (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"); + sgen_init_bridge_processor(); + gc_initialized = 1; } diff --git a/mono/sgen/sgen-gc.h b/mono/sgen/sgen-gc.h index b0ac3dbcb10..192c570f08b 100644 --- a/mono/sgen/sgen-gc.h +++ b/mono/sgen/sgen-gc.h @@ -287,6 +287,7 @@ sgen_get_nursery_end (void) 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, diff --git a/mono/sgen/sgen-internal.c b/mono/sgen/sgen-internal.c index ccff562737a..12ace19a3e9 100644 --- a/mono/sgen/sgen-internal.c +++ b/mono/sgen/sgen-internal.c @@ -96,8 +96,10 @@ sgen_register_fixed_internal_mem_type (int type, size_t size) 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* diff --git a/mono/tests/exception18.cs b/mono/tests/exception18.cs index 8f1e492c0e9..7f3de465449 100644 --- a/mono/tests/exception18.cs +++ b/mono/tests/exception18.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; class C { @@ -17,6 +18,10 @@ 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; } diff --git a/mono/tests/sgen-bridge-pathologies.cs b/mono/tests/sgen-bridge-pathologies.cs index 6cc184c7939..68fc0a5d060 100644 --- a/mono/tests/sgen-bridge-pathologies.cs +++ b/mono/tests/sgen-bridge-pathologies.cs @@ -198,6 +198,7 @@ class Driver { t.Join (); for (int i = 0; i < 5; ++i) { + Console.WriteLine("-GC {0}/5-", i); GC.Collect (); GC.WaitForPendingFinalizers (); } diff --git a/mono/utils/Makefile.am b/mono/utils/Makefile.am index 02d447ad511..7db91094593 100644 --- a/mono/utils/Makefile.am +++ b/mono/utils/Makefile.am @@ -151,7 +151,9 @@ monoutils_sources = \ parse.c \ parse.h \ checked-build.c \ - checked-build.h + checked-build.h \ + w32handle.c \ + w32handle.h arch_sources = diff --git a/mono/utils/mono-logger-internals.h b/mono/utils/mono-logger-internals.h index 89e9a01023a..f32a25e306d 100644 --- a/mono/utils/mono-logger-internals.h +++ b/mono/utils/mono-logger-internals.h @@ -17,6 +17,7 @@ typedef enum { 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 | @@ -26,7 +27,8 @@ typedef enum { 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; diff --git a/mono/utils/mono-logger.c b/mono/utils/mono-logger.c index 8a5840a1c47..8c6c5aa5512 100644 --- a/mono/utils/mono-logger.c +++ b/mono/utils/mono-logger.c @@ -148,7 +148,7 @@ mono_trace_set_logdest_string (const char *dest) 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; @@ -263,10 +263,11 @@ mono_trace_set_mask_string (const char *value) 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; diff --git a/mono/utils/mono-publib.c b/mono/utils/mono-publib.c index 70271a57f8f..927a933d54b 100644 --- a/mono/utils/mono-publib.c +++ b/mono/utils/mono-publib.c @@ -8,3 +8,21 @@ mono_free (void *ptr) 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; +} diff --git a/mono/utils/mono-publib.h b/mono/utils/mono-publib.h index 53d4aa3ea7f..89d4fb68b75 100644 --- a/mono/utils/mono-publib.h +++ b/mono/utils/mono-publib.h @@ -53,6 +53,8 @@ typedef unsigned __int64 uint64_t; #endif /* end of compiler-specific stuff */ +#include + #if defined(MONO_DLL_EXPORT) #define MONO_API MONO_API_EXPORT #elif defined(MONO_DLL_IMPORT) @@ -71,6 +73,20 @@ typedef void (*MonoHFunc) (void* key, void* value, void* user_data); 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 /* diff --git a/mono/utils/w32handle.c b/mono/utils/w32handle.c new file mode 100644 index 00000000000..d8a34dc4269 --- /dev/null +++ b/mono/utils/w32handle.c @@ -0,0 +1,1198 @@ +/* + * 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 + +#if !defined(HOST_WIN32) + +#include +#include +#include +#include +#ifdef HAVE_SIGNAL_H +#include +#endif +#include +#include +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_UN_H +# include +#endif +#ifdef HAVE_SYS_MMAN_H +# include +#endif +#ifdef HAVE_DIRENT_H +# include +#endif +#include +#ifdef HAVE_SYS_RESOURCE_H +# include +#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; + int thr_ret; + + 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. + */ + thr_ret = mono_os_mutex_lock (&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 (&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 (&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; + } +} + +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 + + return(mono_os_mutex_lock (&global_signal_mutex)); +} + +int +mono_w32handle_unlock_signal_mutex (void) +{ +#ifdef DEBUG + g_message ("%s: unlock global signal mutex", __func__); +#endif + + return(mono_os_mutex_unlock (&global_signal_mutex)); +} + +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); + + return(mono_os_mutex_lock (&handle_data->signal_mutex)); +} + +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; + int ret; + +#ifdef DEBUG + g_message ("%s: unlocking handle %p", __func__, handle); +#endif + + if (!mono_w32handle_lookup_data (handle, &handle_data)) { + return(0); + } + + ret = mono_os_mutex_unlock (&handle_data->signal_mutex); + + mono_w32handle_unref (handle); + + return(ret); +} + +/* + * 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) +{ + int thr_ret; + + g_assert (!shutting_down); + + 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) + 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; + int thr_ret; + + 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)); + + thr_ret = mono_os_mutex_lock (&scan_mutex); + g_assert (thr_ret == 0); + + 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 ++; + } + + thr_ret = mono_os_mutex_unlock (&scan_mutex); + g_assert (thr_ret == 0); + + 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; + int thr_ret; + + 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]) { + thr_ret = mono_os_mutex_lock (&scan_mutex); + g_assert (thr_ret == 0); + + if (!private_handles [fd_index]) + private_handles [fd_index] = g_new0 (MonoW32HandleBase, HANDLE_PER_SLOT); + + thr_ret = mono_os_mutex_unlock (&scan_mutex); + g_assert (thr_ret == 0); + } + + 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; + int thr_ret; + + thr_ret = mono_os_mutex_lock (&scan_mutex); + g_assert (thr_ret == 0); + + 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: + 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 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; + int thr_ret; + + thr_ret = mono_os_mutex_lock (&scan_mutex); + g_assert (thr_ret == 0); + + 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; + } + } + } + } + } + + 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->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; + + thr_ret = mono_os_mutex_lock (&scan_mutex); + g_assert (thr_ret == 0); + + 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)); + + thr_ret = mono_os_mutex_unlock (&scan_mutex); + g_assert (thr_ret == 0); + + 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; ii) { + *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; isignal_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; + int thr_ret; + + thr_ret = mono_os_mutex_lock (&scan_mutex); + g_assert (thr_ret == 0); + + 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"); + } + } + } + + thr_ret = mono_os_mutex_unlock (&scan_mutex); + g_assert (thr_ret == 0); +} + +#endif /* !defined(HOST_WIN32) */ diff --git a/mono/utils/w32handle.h b/mono/utils/w32handle.h new file mode 100644 index 00000000000..4e2c27c6cb7 --- /dev/null +++ b/mono/utils/w32handle.h @@ -0,0 +1,186 @@ + +#ifndef _MONO_UTILS_W32HANDLE_H_ +#define _MONO_UTILS_W32HANDLE_H_ + +#include + +#if !defined(HOST_WIN32) + +#include + +#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_ */ diff --git a/msvc/create-windef.pl b/msvc/create-windef.pl index e7ad3d3cf9c..7d588b915df 100755 --- a/msvc/create-windef.pl +++ b/msvc/create-windef.pl @@ -30,7 +30,7 @@ push @symbols, "MonoFixupCorEE"; 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"; diff --git a/msvc/eglib.vcxproj b/msvc/eglib.vcxproj index e09803d25e2..94a7127d731 100644 --- a/msvc/eglib.vcxproj +++ b/msvc/eglib.vcxproj @@ -1,4 +1,4 @@ - + @@ -180,7 +180,6 @@ - @@ -195,4 +194,4 @@ - \ No newline at end of file + diff --git a/msvc/mono.def b/msvc/mono.def index bbc7249634d..2251543e666 100644 --- a/msvc/mono.def +++ b/msvc/mono.def @@ -423,6 +423,7 @@ mono_get_uint64_class 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 @@ -505,6 +506,12 @@ mono_lock_free_queue_init 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 @@ -769,6 +776,7 @@ mono_security_core_clr_require_elevated_permissions 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 @@ -852,14 +860,20 @@ mono_threads_attach_coop 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 diff --git a/msvc/monosgen.def b/msvc/monosgen.def index 081051fe5e0..1f82284e7c2 100644 --- a/msvc/monosgen.def +++ b/msvc/monosgen.def @@ -425,6 +425,7 @@ mono_get_uint64_class 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 @@ -507,6 +508,12 @@ mono_lock_free_queue_init 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 @@ -771,6 +778,7 @@ mono_security_core_clr_require_elevated_permissions 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 @@ -854,14 +862,20 @@ mono_threads_attach_coop 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 diff --git a/samples/embed/teste.c b/samples/embed/teste.c index 2183ccbb50b..6f727a00e1b 100644 --- a/samples/embed/teste.c +++ b/samples/embed/teste.c @@ -1,5 +1,6 @@ #include #include +#include #include /* @@ -31,6 +32,13 @@ static void main_function (MonoDomain *domain, const char *file, int argc, char* 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[]) { @@ -44,6 +52,9 @@ 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 @@ -66,6 +77,9 @@ main(int argc, char* argv[]) { retval = mono_environment_exitcode_get (); mono_jit_cleanup (domain); + + fprintf (stdout, "custom malloc calls = %d\n", malloc_count); + return retval; }